Просмотр исходного кода

[comboot] Implement INT 22h AX=001Bh (Cleanup, shuffle, and boot to real mode)

tags/v0.9.7
Daniel Verkamp 15 лет назад
Родитель
Сommit
dbbd81c140
2 измененных файлов: 95 добавлений и 1 удалений
  1. 34
    0
      src/arch/i386/include/comboot.h
  2. 61
    1
      src/arch/i386/interface/syslinux/comboot_call.c

+ 34
- 0
src/arch/i386/include/comboot.h Просмотреть файл

@@ -57,6 +57,40 @@ typedef struct {
57 57
 	com32_reg32_t eflags;       /* Offset 40 */
58 58
 } com32sys_t;
59 59
 
60
+typedef struct {
61
+	uint32_t eax;               /* Offset  0 */
62
+	uint32_t ecx;               /* Offset  4 */
63
+	uint32_t edx;               /* Offset  8 */
64
+	uint32_t ebx;               /* Offset 12 */
65
+	uint32_t esp;               /* Offset 16 */
66
+	uint32_t ebp;               /* Offset 20 */
67
+	uint32_t esi;               /* Offset 24 */
68
+	uint32_t edi;               /* Offset 28 */
69
+
70
+	uint32_t eip;               /* Offset 32 */
71
+} syslinux_pm_regs;
72
+
73
+typedef struct {
74
+	uint16_t es;                /* Offset  0 */
75
+	uint16_t _unused_cs;        /* Offset  2 */
76
+	uint16_t ds;                /* Offset  4 */
77
+	uint16_t ss;                /* Offset  6 */
78
+	uint16_t fs;                /* Offset  8 */
79
+	uint16_t gs;                /* Offset 10 */
80
+
81
+	uint32_t eax;                /* Offset 12 */
82
+	uint32_t ecx;                /* Offset 16 */
83
+	uint32_t edx;                /* Offset 20 */
84
+	uint32_t ebx;                /* Offset 24 */
85
+	uint32_t esp;                /* Offset 28 */
86
+	uint32_t ebp;                /* Offset 32 */
87
+	uint32_t esi;                /* Offset 36 */
88
+	uint32_t edi;                /* Offset 40 */
89
+
90
+	uint16_t ip;                /* Offset 44 */
91
+	uint16_t cs;                /* Offset 46 */
92
+} syslinux_rm_regs;
93
+
60 94
 typedef struct {
61 95
 	uint32_t dest;
62 96
 	uint32_t src;

+ 61
- 1
src/arch/i386/interface/syslinux/comboot_call.c Просмотреть файл

@@ -53,6 +53,14 @@ static char __data16_array ( syslinux_configuration_file, [] ) = "";
53 53
 static uint8_t __data16 ( comboot_feature_flags ) = COMBOOT_FEATURE_IDLE_LOOP;
54 54
 #define comboot_feature_flags __use_data16 ( comboot_feature_flags )
55 55
 
56
+typedef union {
57
+	syslinux_pm_regs pm; syslinux_rm_regs rm;
58
+} syslinux_regs;
59
+
60
+/** Initial register values for INT 22h AX=1Ah and 1Bh */
61
+static syslinux_regs __text16 ( comboot_initial_regs );
62
+#define comboot_initial_regs __use_text16 ( comboot_initial_regs )
63
+
56 64
 static struct segoff __text16 ( int20_vector );
57 65
 #define int20_vector __use_text16 ( int20_vector )
58 66
 
@@ -316,7 +324,7 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
316 324
 	case 0x0001: /* Get Version */
317 325
 
318 326
 		/* Number of INT 22h API functions available */
319
-		ix86->regs.ax = 0x0018;
327
+		ix86->regs.ax = 0x001B;
320 328
 
321 329
 		/* SYSLINUX version number */
322 330
 		ix86->regs.ch = 0; /* major */
@@ -569,6 +577,58 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
569 577
 		ix86->flags &= ~CF;
570 578
 		break;
571 579
 
580
+	case 0x001B: /* Cleanup, shuffle and boot to real mode */
581
+		if ( ix86->regs.cx > COMBOOT_MAX_SHUFFLE_DESCRIPTORS )
582
+			break;
583
+
584
+		/* Perform final cleanup */
585
+		shutdown ( SHUTDOWN_BOOT );
586
+
587
+		/* Perform sequence of copies */
588
+		shuffle ( ix86->segs.es, ix86->regs.di, ix86->regs.cx );
589
+
590
+		/* Copy initial register values to .text16 */
591
+		memcpy_user ( real_to_user ( rm_cs, (unsigned) __from_text16 ( &comboot_initial_regs ) ), 0,
592
+		              real_to_user ( ix86->segs.ds, ix86->regs.si ), 0,
593
+		              sizeof(syslinux_rm_regs) );
594
+
595
+		/* Load initial register values */
596
+		__asm__ __volatile__ (
597
+			REAL_CODE (
598
+				/* Point SS:SP at the register value structure */
599
+				"pushw %%cs\n\t"
600
+				"popw %%ss\n\t"
601
+				"movw $comboot_initial_regs, %%sp\n\t"
602
+
603
+				/* Segment registers */
604
+				"popw %%es\n\t"
605
+				"popw %%ax\n\t" /* Skip CS */
606
+				"popw %%ds\n\t"
607
+				"popw %%ax\n\t" /* Skip SS for now */
608
+				"popw %%fs\n\t"
609
+				"popw %%gs\n\t"
610
+
611
+				/* GP registers */
612
+				"popl %%eax\n\t"
613
+				"popl %%ecx\n\t"
614
+				"popl %%edx\n\t"
615
+				"popl %%ebx\n\t"
616
+				"popl %%ebp\n\t" /* Skip ESP for now */
617
+				"popl %%ebp\n\t"
618
+				"popl %%esi\n\t"
619
+				"popl %%edi\n\t"
620
+
621
+				/* Load correct SS:ESP */
622
+				"movw $(comboot_initial_regs + 6), %%sp\n\t"
623
+				"popw %%ss\n\t"
624
+				"movl %%cs:(comboot_initial_regs + 28), %%esp\n\t"
625
+
626
+				"ljmp *%%cs:(comboot_initial_regs + 44)\n\t"
627
+			)
628
+			: : );
629
+
630
+		break;
631
+
572 632
 	default:
573 633
 		DBG ( "COMBOOT unknown int22 function %04x\n", ix86->regs.ax );
574 634
 		break;

Загрузка…
Отмена
Сохранить