|
@@ -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;
|