|
@@ -599,27 +599,32 @@ int int13_boot ( unsigned int drive ) {
|
599
|
599
|
hook_bios_interrupt ( 0x19, ( unsigned int ) int13_exec_fail,
|
600
|
600
|
&int19_vector );
|
601
|
601
|
|
602
|
|
- /* Boot the loaded sector */
|
603
|
|
- __asm__ __volatile__ ( REAL_CODE ( /* Save segment registers */
|
604
|
|
- "pushw %%ds\n\t"
|
605
|
|
- "pushw %%es\n\t"
|
606
|
|
- "pushw %%fs\n\t"
|
607
|
|
- "pushw %%gs\n\t"
|
|
602
|
+ /* Boot the loaded sector
|
|
603
|
+ *
|
|
604
|
+ * We assume that the boot sector may completely destroy our
|
|
605
|
+ * real-mode stack, so we preserve everything we need in
|
|
606
|
+ * static storage.
|
|
607
|
+ */
|
|
608
|
+ __asm__ __volatile__ ( REAL_CODE ( /* Save return address off-stack */
|
|
609
|
+ "popw %%cs:int13_saved_retaddr\n\t"
|
608
|
610
|
/* Save stack pointer */
|
609
|
611
|
"movw %%ss, %%ax\n\t"
|
610
|
612
|
"movw %%ax, %%cs:int13_saved_ss\n\t"
|
611
|
613
|
"movw %%sp, %%cs:int13_saved_sp\n\t"
|
|
614
|
+ /* Jump to boot sector */
|
612
|
615
|
"ljmp $0, $0x7c00\n\t"
|
|
616
|
+ /* Preserved variables */
|
613
|
617
|
"\nint13_saved_ss: .word 0\n\t"
|
614
|
618
|
"\nint13_saved_sp: .word 0\n\t"
|
|
619
|
+ "\nint13_saved_retaddr: .word 0\n\t"
|
|
620
|
+ /* Boot failure return point */
|
615
|
621
|
"\nint13_exec_fail:\n\t"
|
|
622
|
+ /* Restore stack pointer */
|
616
|
623
|
"movw %%cs:int13_saved_ss, %%ax\n\t"
|
617
|
624
|
"movw %%ax, %%ss\n\t"
|
618
|
625
|
"movw %%cs:int13_saved_sp, %%sp\n\t"
|
619
|
|
- "popw %%gs\n\t"
|
620
|
|
- "popw %%fs\n\t"
|
621
|
|
- "popw %%es\n\t"
|
622
|
|
- "popw %%ds\n\t" )
|
|
626
|
+ /* Return via saved address */
|
|
627
|
+ "jmp *%%cs:int13_saved_retaddr\n\t")
|
623
|
628
|
: "=d" ( discard_d ) : "d" ( drive )
|
624
|
629
|
: "eax", "ebx", "ecx", "esi", "edi", "ebp" );
|
625
|
630
|
|