mirror of
https://github.com/ipxe/ipxe
synced 2026-02-12 21:29:39 +03:00
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:
@@ -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"
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user