mirror of
https://github.com/ipxe/ipxe
synced 2025-12-29 11:03:15 +03:00
[comboot] Restore the real-mode stack pointer on exit from a COMBOOT image
COMBOOT images use INTs to issue API calls; these end up making calls into gPXE from real mode, and so temporarily change the real-mode stack pointer. When our COMBOOT code uses a longjmp() to implement the various "exit COMBOOT image" API calls, this leaves the real-mode stack pointer stuck with its temporary value, which causes problems if we eventually try to exit out of gPXE back to the BIOS. Fix by adding rmsetjmp() and rmlongjmp() calls (analogous to sigsetjmp()/siglongjmp()); these save and restore the additional state needed for real-mode calls to function correctly.
This commit is contained in:
@@ -67,7 +67,7 @@ extern void int21_wrapper ( void );
|
||||
extern void int22_wrapper ( void );
|
||||
|
||||
/* setjmp/longjmp context buffer used to return after loading an image */
|
||||
jmp_buf comboot_return;
|
||||
rmjmp_buf comboot_return;
|
||||
|
||||
/* Replacement image when exiting with COMBOOT_EXIT_RUN_KERNEL */
|
||||
struct image *comboot_replacement_image;
|
||||
@@ -235,7 +235,7 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
|
||||
* Terminate program interrupt handler
|
||||
*/
|
||||
static __asmcall void int20 ( struct i386_all_regs *ix86 __unused ) {
|
||||
longjmp ( comboot_return, COMBOOT_EXIT );
|
||||
rmlongjmp ( comboot_return, COMBOOT_EXIT );
|
||||
}
|
||||
|
||||
|
||||
@@ -248,7 +248,7 @@ static __asmcall void int21 ( struct i386_all_regs *ix86 ) {
|
||||
switch ( ix86->regs.ah ) {
|
||||
case 0x00:
|
||||
case 0x4C: /* Terminate program */
|
||||
longjmp ( comboot_return, COMBOOT_EXIT );
|
||||
rmlongjmp ( comboot_return, COMBOOT_EXIT );
|
||||
break;
|
||||
|
||||
case 0x01: /* Get Key with Echo */
|
||||
@@ -347,13 +347,13 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
|
||||
DBG ( "COMBOOT: executing command '%s'\n", cmd );
|
||||
system ( cmd );
|
||||
DBG ( "COMBOOT: exiting after executing command...\n" );
|
||||
longjmp ( comboot_return, COMBOOT_EXIT_COMMAND );
|
||||
rmlongjmp ( comboot_return, COMBOOT_EXIT_COMMAND );
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0004: /* Run default command */
|
||||
/* FIXME: just exit for now */
|
||||
longjmp ( comboot_return, COMBOOT_EXIT_COMMAND );
|
||||
rmlongjmp ( comboot_return, COMBOOT_EXIT_COMMAND );
|
||||
break;
|
||||
|
||||
case 0x0005: /* Force text mode */
|
||||
@@ -552,7 +552,7 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
|
||||
* part of the COMBOOT program's memory space.
|
||||
*/
|
||||
DBG ( "COMBOOT: exiting to run kernel...\n" );
|
||||
longjmp ( comboot_return, COMBOOT_EXIT_RUN_KERNEL );
|
||||
rmlongjmp ( comboot_return, COMBOOT_EXIT_RUN_KERNEL );
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user