init_librm() and prot_call() are now real-mode far calls.

install() now calls relocate(), moves the protected-mode code to the new
location, and calls hide_etherboot().
This commit is contained in:
Michael Brown
2006-05-25 00:06:45 +00:00
parent 4d81b48504
commit 89da833c5d
4 changed files with 120 additions and 90 deletions

View File

@@ -393,7 +393,8 @@ static void hook_int13 ( void ) {
"\nint13_wrapper:\n\t" "\nint13_wrapper:\n\t"
"orb $0, %%al\n\t" /* clear CF and OF */ "orb $0, %%al\n\t" /* clear CF and OF */
"pushl %0\n\t" /* call int13() */ "pushl %0\n\t" /* call int13() */
"data32 call prot_call\n\t" "pushw %%cs\n\t"
"call prot_call\n\t"
"jo 1f\n\t" /* chain if OF not set */ "jo 1f\n\t" /* chain if OF not set */
"pushfw\n\t" "pushfw\n\t"
"lcall *%%cs:int13_vector\n\t" "lcall *%%cs:int13_vector\n\t"

View File

@@ -357,7 +357,8 @@ start_runtime:
.section ".text16", "awx", @progbits .section ".text16", "awx", @progbits
1: 1:
pushl $main pushl $main
data32 call prot_call pushw %cs
call prot_call
popl %eax /* discard */ popl %eax /* discard */
/* Boot next device */ /* Boot next device */

View File

@@ -21,6 +21,7 @@
.arch i386 .arch i386
.section ".prefix.lib", "awx", @progbits .section ".prefix.lib", "awx", @progbits
.section ".data16", "aw", @progbits
/**************************************************************************** /****************************************************************************
* install_block (real-mode near call) * install_block (real-mode near call)
@@ -164,6 +165,47 @@ install_basemem:
ret ret
.size install_basemem, . - install_basemem .size install_basemem, . - install_basemem
/****************************************************************************
* install_highmem (flat real-mode near call)
*
* Install .text and .data into high memory
*
* Parameters:
* %es:edi : address in high memory
* Returns:
* none
* Corrupts:
* none
****************************************************************************
*/
#ifndef KEEP_IT_REAL
.section ".prefix.lib"
.code16
install_highmem:
/* Preserve registers */
pushl %esi
pushl %edi
pushl %ecx
pushl %edx
/* Install .text and .data to specified address */
movl $_textdata_load_offset, %esi
movl $_textdata_progbits_size, %ecx
movl $_textdata_size, %edx
call install_block
/* Restore registers and interrupt status */
popl %edx
popl %ecx
popl %edi
popl %esi
ret
.size install_highmem, . - install_highmem
#endif /* KEEP_IT_REAL */
/**************************************************************************** /****************************************************************************
* GDT for flat real mode * GDT for flat real mode
* *
@@ -183,11 +225,6 @@ gdt_limit: .word gdt_length - 1
gdt_base: .long 0 gdt_base: .long 0
.word 0 /* padding */ .word 0 /* padding */
real_ds: /* Genuine real mode data segment */
.equ REAL_DS, real_ds - gdt
.word 0xffff, 0
.byte 0, 0x93, 0, 0
flat_ds: /* Flat real mode data segment */ flat_ds: /* Flat real mode data segment */
.equ FLAT_DS, flat_ds - gdt .equ FLAT_DS, flat_ds - gdt
.word 0xffff, 0 .word 0xffff, 0
@@ -200,12 +237,12 @@ gdt_end:
#endif /* KEEP_IT_REAL */ #endif /* KEEP_IT_REAL */
/**************************************************************************** /****************************************************************************
* set_segment_limits (real-mode near call) * flatten_real_mode (real-mode near call)
* *
* Sets limits on the data segments %ds and %es. * Sets 4GB limits on the data segments %ds and %es.
* *
* Parameters: * Parameters:
* %cx : Segment limit ($REAL_DS or $FLAT_DS) * none
**************************************************************************** ****************************************************************************
*/ */
@@ -213,7 +250,7 @@ gdt_end:
.section ".prefix.lib" .section ".prefix.lib"
.code16 .code16
set_segment_limits: flatten_real_mode:
/* Preserve real-mode segment values and temporary registers */ /* Preserve real-mode segment values and temporary registers */
pushw %es pushw %es
pushw %ds pushw %ds
@@ -227,12 +264,18 @@ set_segment_limits:
movl %eax, %cs:gdt_base movl %eax, %cs:gdt_base
lgdt %cs:gdt lgdt %cs:gdt
/* Switch to protected mode, set segment limits, switch back */ /* Switch to protected mode */
movl %cr0, %eax movl %cr0, %eax
orb $CR0_PE, %al orb $CR0_PE, %al
movl %eax, %cr0 movl %eax, %cr0
movw %cx, %ds
movw %cx, %es /* Set flat segment limits */
movw $FLAT_DS, %ax
movw %ax, %ds
movw %ax, %es
/* Switch back to real mode */
movl %cr0, %eax
andb $0!CR0_PE, %al andb $0!CR0_PE, %al
movl %eax, %cr0 movl %eax, %cr0
@@ -241,61 +284,7 @@ set_segment_limits:
popw %ds popw %ds
popw %es popw %es
ret ret
.size set_segment_limits, . - set_segment_limits .size flatten_real_mode, . - flatten_real_mode
#endif /* KEEP_IT_REAL */
/****************************************************************************
* install_highmem (real-mode near call)
*
* Install .text and .data into high memory
*
* Parameters:
* %edi : physical address in high memory
* Returns:
* none
* Corrupts:
* none
****************************************************************************
*/
#ifndef KEEP_IT_REAL
.section ".prefix.lib"
.code16
install_highmem:
/* Preserve registers and interrupt status */
pushfl
pushl %esi
pushl %edi
pushl %ecx
pushl %edx
/* Disable interrupts and flatten real mode */
cli
movw $FLAT_DS, %cx
call set_segment_limits
/* Install .text and .data to specified address */
xorw %cx, %cx
movw %cx, %es
movl $_textdata_load_offset, %esi
movl $_textdata_progbits_size, %ecx
movl $_textdata_size, %edx
call install_block
/* Unflatten real mode */
movw $REAL_DS, %cx
call set_segment_limits
/* Restore registers and interrupt status */
popl %edx
popl %ecx
popl %edi
popl %esi
popfl
ret
.size install_highmem, . - install_highmem
#endif /* KEEP_IT_REAL */ #endif /* KEEP_IT_REAL */
@@ -329,32 +318,71 @@ install_prealloc:
call install_basemem call install_basemem
#ifndef KEEP_IT_REAL #ifndef KEEP_IT_REAL
/* Preserve registers and interrupt status, and disable interrupts */
pushfw
pushw %ds
pushw %es
pushl %esi
pushl %ecx
cli
/* Load up %ds and %es, and set up vectors for far calls to .text16 */
movw %bx, %ds
xorw %si, %si
movw %si, %es
movw %ax, (init_librm_vector+2)
movw %ax, (prot_call_vector+2)
/* Install .text and .data to 2MB mark. Use 2MB to avoid /* Install .text and .data to 2MB mark. Use 2MB to avoid
* problems with A20. * problems with A20.
*/ */
call flatten_real_mode
movl $(2<<20), %edi movl $(2<<20), %edi
call install_highmem call install_highmem
/* Continue executing in .text16 segment */ /* Set up initial protected-mode GDT, call relocate().
movw %bx, %ds * relocate() will return with %esi, %edi and %ecx set up
pushw %cs * ready for the copy to the new location.
pushw $2f */
pushw %ax lcall *init_librm_vector
pushw $1f
lret
.section ".text16", "awx", @progbits
1:
/* Set up protected-mode GDT, call relocate(), reset GDT */
call init_librm
pushl $relocate pushl $relocate
data32 call prot_call lcall *prot_call_vector
addw $4, %sp addw $4, %sp
call init_librm
/* Return to executing in .prefix section */ /* Move code to new location, set up new protected-mode GDT */
lret call flatten_real_mode
.section ".prefix.lib" pushl %edi
2: 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 registers and interrupt status */
popl %ecx
popl %esi
popw %es
popw %ds
popfw
#endif #endif
ret ret
.size install_prealloc, . - install_prealloc .size install_prealloc, . - install_prealloc
#ifndef KEEP_IT_REAL
/* Vectors for far calls to .text16 functions */
.section ".data16"
init_librm_vector:
.word init_librm
.word 0
.size init_librm_vector, . - init_librm_vector
prot_call_vector:
.word prot_call
.word 0
.size prot_call_vector, . - prot_call_vector
#endif

View File

@@ -88,7 +88,7 @@ gdt_end:
.equ gdt_length, gdt_end - gdt .equ gdt_length, gdt_end - gdt
/**************************************************************************** /****************************************************************************
* init_librm (real-mode near call, 16-bit real-mode return address) * init_librm (real-mode far call, 16-bit real-mode far return address)
* *
* Initialise the GDT ready for transitions to protected mode. * Initialise the GDT ready for transitions to protected mode.
* *
@@ -143,7 +143,7 @@ init_librm:
negl %edi negl %edi
popl %ebx popl %ebx
popl %eax popl %eax
ret lret
.section ".text16" .section ".text16"
.code16 .code16
@@ -316,7 +316,7 @@ rm_cs: .word 0
rm_ds: .word 0 rm_ds: .word 0
/**************************************************************************** /****************************************************************************
* prot_call (real-mode near call, 32-bit real-mode return address) * prot_call (real-mode far call, 16-bit real-mode far return address)
* *
* Call a specific C function in the protected-mode code. The * Call a specific C function in the protected-mode code. The
* prototype of the C function must be * prototype of the C function must be
@@ -405,7 +405,7 @@ prot_call:
* zeroes the high word of %esp, and interrupts * zeroes the high word of %esp, and interrupts
* are still disabled at this point. */ * are still disabled at this point. */
popfl popfl
data32 ret lret
/**************************************************************************** /****************************************************************************
* real_call (protected-mode near call, 32-bit virtual return address) * real_call (protected-mode near call, 32-bit virtual return address)