diff options
| author | Michael Brown | 2007-01-14 01:53:56 +0100 |
|---|---|---|
| committer | Michael Brown | 2007-01-14 01:53:56 +0100 |
| commit | dca369ddc33d5a7b068182a3ef6f1ca71fbf4960 (patch) | |
| tree | 4af7aea56ba10175bb39c1964a144abf7875e1c5 /src/arch/i386 | |
| parent | Make shutdown functions callable by OS image's exec methods. (diff) | |
| download | ipxe-dca369ddc33d5a7b068182a3ef6f1ca71fbf4960.tar.gz ipxe-dca369ddc33d5a7b068182a3ef6f1ca71fbf4960.tar.xz ipxe-dca369ddc33d5a7b068182a3ef6f1ca71fbf4960.zip | |
Call hide_etherboot() from startup(), rather than requiring the prefix to
do it.
Diffstat (limited to 'src/arch/i386')
| -rw-r--r-- | src/arch/i386/firmware/pcbios/hidemem.c | 16 | ||||
| -rw-r--r-- | src/arch/i386/prefix/libprefix.S | 42 |
2 files changed, 38 insertions, 20 deletions
diff --git a/src/arch/i386/firmware/pcbios/hidemem.c b/src/arch/i386/firmware/pcbios/hidemem.c index fa58135ee..c372246c0 100644 --- a/src/arch/i386/firmware/pcbios/hidemem.c +++ b/src/arch/i386/firmware/pcbios/hidemem.c @@ -128,6 +128,22 @@ void hide_etherboot ( void ) { * possible. */ void unhide_etherboot ( void ) { + + /* If we have more than one hooked interrupt at this point, it + * means that some other vector is still hooked, in which case + * we can't safely unhook INT 15 because we need to keep our + * memory protected. (We expect there to be at least one + * hooked interrupt, because INT 15 itself is still hooked). + */ + if ( hooked_bios_interrupts > 1 ) { + DBG ( "Cannot unhide: %d interrupt vectors still hooked\n", + hooked_bios_interrupts ); + return; + } + + /* Try to unhook INT 15. If it fails, then just leave it + * hooked; it takes care of protecting itself. :) + */ unhook_bios_interrupt ( 0x15, ( unsigned int ) int15, &int15_vector ); } diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S index d1da0b00d..02531211c 100644 --- a/src/arch/i386/prefix/libprefix.S +++ b/src/arch/i386/prefix/libprefix.S @@ -230,7 +230,7 @@ install_highmem: * GDT for flat real mode * * We only ever use this GDT to set segment limits; the bases are - * unused. Also, we only flatten data segments, so we don't need to + * unused. Also, we only change data segments, so we don't need to * worry about the code or stack segments. This makes everything much * simpler. **************************************************************************** @@ -250,6 +250,11 @@ flat_ds: /* Flat real mode data segment */ .word 0xffff, 0 .byte 0, 0x93, 0xcf, 0 +real_ds: /* Normal real mode data segment */ + .equ REAL_DS, real_ds - gdt + .word 0xffff, 0 + .byte 0, 0x93, 0x00, 0 + gdt_end: .equ gdt_length, gdt_end - gdt .size gdt, . - gdt @@ -257,12 +262,12 @@ gdt_end: #endif /* KEEP_IT_REAL */ /**************************************************************************** - * flatten_real_mode (real-mode near call) + * set_real_mode_limits (real-mode near call) * - * Sets 4GB limits on the data segments %ds and %es. + * Sets limits on the data segments %ds and %es. * - * Parameters: - * none + * Parameters: + * %cx : segment type (FLAT_DS for 4GB or REAL_DS for 64kB) **************************************************************************** */ @@ -270,7 +275,7 @@ gdt_end: .section ".prefix.lib" .code16 -flatten_real_mode: +set_real_mode_limits: /* Preserve real-mode segment values and temporary registers */ pushw %es pushw %ds @@ -294,9 +299,8 @@ flatten_real_mode: movl %eax, %cr0 /* Set flat segment limits */ - movw $FLAT_DS, %ax - movw %ax, %ds - movw %ax, %es + movw %cx, %ds + movw %cx, %es /* Switch back to real mode */ movl %cr0, %eax @@ -309,7 +313,7 @@ flatten_real_mode: popw %ds popw %es ret - .size flatten_real_mode, . - flatten_real_mode + .size set_real_mode_limits, . - set_real_mode_limits #endif /* KEEP_IT_REAL */ @@ -369,7 +373,8 @@ install_prealloc: * prior to reading the E820 memory map and relocating * properly. */ - call flatten_real_mode + movw $FLAT_DS, %cx + call set_real_mode_limits movl $HIGHMEM_LOADPOINT, %edi call install_highmem @@ -383,19 +388,16 @@ install_prealloc: addw $4, %sp /* Move code to new location, set up new protected-mode GDT */ - call flatten_real_mode + movw $FLAT_DS, %cx + call set_real_mode_limits pushl %edi es rep addr32 movsb popl %edi lcall *init_librm_vector - - /* Hide Etherboot from BIOS memory map. Note that making this - * protected-mode call will also restore normal (non-flat) - * real mode, as part of the protected-to-real transition. - */ - pushl $hide_etherboot - lcall *prot_call_vector - addw $4, %sp + + /* Restore real-mode segment limits */ + movw $REAL_DS, %cx + call set_real_mode_limits /* Restore registers and interrupt status */ popl %ecx |
