mirror of
https://github.com/xcat2/xNBA.git
synced 2025-02-18 03:24:29 +00:00
[prefix] Cope with image source addresses outside base memory
When PMM is used, the gPXE image source will no longer be in base memory. Decompression of .text16 and .data16 can therefore no longer be done in real mode.
This commit is contained in:
parent
9c86a39551
commit
3bf7105cab
@ -175,13 +175,14 @@ print_hex_nibble:
|
||||
#ifndef KEEP_IT_REAL
|
||||
|
||||
/* GDT for protected-mode calls */
|
||||
.section ".data16"
|
||||
.section ".prefix.lib"
|
||||
.align 16
|
||||
pm_call_vars:
|
||||
gdt:
|
||||
gdt_limit: .word gdt_length - 1
|
||||
gdt_base: .long 0
|
||||
.word 0 /* padding */
|
||||
pm_cs: /* 16-bit protected-mode code segment */
|
||||
pm_cs: /* 16-bit protected-mode code segment */
|
||||
.equ PM_CS, pm_cs - gdt
|
||||
.word 0xffff, 0
|
||||
.byte 0, 0x9b, 0x00, 0
|
||||
@ -197,18 +198,24 @@ gdt_end:
|
||||
.equ gdt_length, . - gdt
|
||||
.size gdt, . - gdt
|
||||
|
||||
.section ".data16"
|
||||
.section ".prefix.lib"
|
||||
.align 16
|
||||
pm_saved_gdt:
|
||||
.long 0, 0
|
||||
.size pm_saved_gdt, . - pm_saved_gdt
|
||||
|
||||
.equ pm_call_vars_size, . - pm_call_vars
|
||||
#define PM_CALL_VAR(x) ( -pm_call_vars_size + ( (x) - pm_call_vars ) )
|
||||
|
||||
.section ".prefix.lib"
|
||||
.code16
|
||||
pm_call:
|
||||
/* Preserve registers, flags, GDT, and RM return point */
|
||||
/* Preserve registers, flags, and RM return point */
|
||||
pushw %bp
|
||||
movw %sp, %bp
|
||||
subw $pm_call_vars_size, %sp
|
||||
andw $0xfff0, %sp
|
||||
pushfl
|
||||
sgdt pm_saved_gdt
|
||||
pushw %gs
|
||||
pushw %fs
|
||||
pushw %es
|
||||
@ -217,27 +224,43 @@ pm_call:
|
||||
pushw %cs
|
||||
pushw $99f
|
||||
|
||||
/* Set up local variable block, and preserve GDT */
|
||||
pushw %cx
|
||||
pushw %si
|
||||
pushw %di
|
||||
pushw %ss
|
||||
popw %es
|
||||
movw $pm_call_vars, %si
|
||||
leaw PM_CALL_VAR(pm_call_vars)(%bp), %di
|
||||
movw $pm_call_vars_size, %cx
|
||||
cs rep movsb
|
||||
popw %di
|
||||
popw %si
|
||||
popw %cx
|
||||
sgdt PM_CALL_VAR(pm_saved_gdt)(%bp)
|
||||
|
||||
/* Set up GDT bases */
|
||||
pushl %eax
|
||||
pushw %bx
|
||||
pushl %edi
|
||||
xorl %eax, %eax
|
||||
movw %ds, %ax
|
||||
movw %ss, %ax
|
||||
shll $4, %eax
|
||||
addl $gdt, %eax
|
||||
movl %eax, gdt_base
|
||||
movzwl %bp, %edi
|
||||
leal PM_CALL_VAR(gdt)(%eax, %edi), %eax
|
||||
movl %eax, PM_CALL_VAR(gdt_base)(%bp)
|
||||
movw %cs, %ax
|
||||
movw $pm_cs, %bx
|
||||
movw $PM_CALL_VAR(pm_cs), %di
|
||||
call set_seg_base
|
||||
movw %ss, %ax
|
||||
movw $pm_ss, %bx
|
||||
movw $PM_CALL_VAR(pm_ss), %di
|
||||
call set_seg_base
|
||||
popw %bx
|
||||
popl %edi
|
||||
popl %eax
|
||||
|
||||
/* Switch CPU to protected mode and load up segment registers */
|
||||
pushl %eax
|
||||
cli
|
||||
lgdt gdt
|
||||
lgdt PM_CALL_VAR(gdt)(%bp)
|
||||
movl %cr0, %eax
|
||||
orb $CR0_PE, %al
|
||||
movl %eax, %cr0
|
||||
@ -273,18 +296,19 @@ pm_call:
|
||||
popw %es
|
||||
popw %fs
|
||||
popw %gs
|
||||
lgdt pm_saved_gdt
|
||||
lgdt PM_CALL_VAR(pm_saved_gdt)(%bp)
|
||||
popfl
|
||||
|
||||
movw %bp, %sp
|
||||
popw %bp
|
||||
ret
|
||||
.size pm_call, . - pm_call
|
||||
|
||||
set_seg_base:
|
||||
rolw $4, %ax
|
||||
movw %ax, 2(%bx)
|
||||
andw $0xfff0, 2(%bx)
|
||||
movb %al, 4(%bx)
|
||||
andb $0x0f, 4(%bx)
|
||||
movw %ax, 2(%bp,%di)
|
||||
andw $0xfff0, 2(%bp,%di)
|
||||
movb %al, 4(%bp,%di)
|
||||
andb $0x0f, 4(%bp,%di)
|
||||
ret
|
||||
.size set_seg_base, . - set_seg_base
|
||||
|
||||
@ -301,7 +325,7 @@ set_seg_base:
|
||||
* %ecx : length
|
||||
* Returns:
|
||||
* %ds:esi : next source address
|
||||
* %ds:esi : next destination address
|
||||
* %es:edi : next destination address
|
||||
* Corrupts:
|
||||
* None
|
||||
****************************************************************************
|
||||
@ -316,27 +340,57 @@ copy_bytes:
|
||||
.size copy_bytes, . - copy_bytes
|
||||
|
||||
/****************************************************************************
|
||||
* install_block (real-mode or 16-bit protected-mode near call)
|
||||
* install_block (real-mode near call)
|
||||
*
|
||||
* Install block to specified address
|
||||
*
|
||||
* Parameters:
|
||||
* %ds:esi : source address (must be a multiple of 16)
|
||||
* %es:edi : destination address
|
||||
* %esi : source physical address (must be a multiple of 16)
|
||||
* %edi : destination physical address (must be a multiple of 16)
|
||||
* %ecx : length of (decompressed) data
|
||||
* %edx : total length of block (including any uninitialised data portion)
|
||||
* Returns:
|
||||
* %ds:esi : next source address (will be a multiple of 16)
|
||||
* %esi : next source physical address (will be a multiple of 16)
|
||||
* Corrupts:
|
||||
* %ecx, %edx
|
||||
* none
|
||||
****************************************************************************
|
||||
*/
|
||||
.section ".prefix.lib"
|
||||
.code16
|
||||
install_block:
|
||||
|
||||
#ifdef KEEP_IT_REAL
|
||||
|
||||
/* Preserve registers */
|
||||
pushw %ds
|
||||
pushw %es
|
||||
pushl %ecx
|
||||
pushl %edi
|
||||
|
||||
/* Convert %esi and %edi to segment registers */
|
||||
shrl $4, %esi
|
||||
movw %si, %ds
|
||||
xorw %si, %si
|
||||
shrl $4, %edi
|
||||
movw %di, %es
|
||||
xorw %di, %di
|
||||
|
||||
#else /* KEEP_IT_REAL */
|
||||
|
||||
/* Call self in protected mode */
|
||||
pushw %ax
|
||||
movw $1f, %ax
|
||||
call pm_call
|
||||
popw %ax
|
||||
ret
|
||||
1:
|
||||
/* Preserve registers */
|
||||
pushl %ecx
|
||||
pushl %edi
|
||||
|
||||
#endif /* KEEP_IT_REAL */
|
||||
|
||||
|
||||
#if COMPRESS
|
||||
/* Decompress source to destination */
|
||||
call decompress16
|
||||
@ -357,8 +411,28 @@ install_block:
|
||||
addl $0xf, %esi
|
||||
andl $~0xf, %esi
|
||||
|
||||
/* Restore registers and return */
|
||||
|
||||
#ifdef KEEP_IT_REAL
|
||||
|
||||
/* Convert %ds:esi back to a physical address */
|
||||
movzwl %ds, %cx
|
||||
shll $4, %ecx
|
||||
addl %ecx, %esi
|
||||
|
||||
/* Restore registers */
|
||||
popl %edi
|
||||
popl %ecx
|
||||
popw %es
|
||||
popw %ds
|
||||
|
||||
#else /* KEEP_IT_REAL */
|
||||
|
||||
/* Restore registers */
|
||||
popl %edi
|
||||
popl %ecx
|
||||
|
||||
#endif
|
||||
|
||||
ret
|
||||
.size install_block, . - install_block
|
||||
|
||||
@ -406,87 +480,6 @@ alloc_basemem:
|
||||
ret
|
||||
.size alloc_basemem, . - alloc_basemem
|
||||
|
||||
/****************************************************************************
|
||||
* install_basemem (real-mode near call)
|
||||
*
|
||||
* Install source block into base memory
|
||||
*
|
||||
* Parameters:
|
||||
* %esi : source physical address (must be a multiple of 16)
|
||||
* %es : destination segment address
|
||||
* %cx : length of (decompressed) data
|
||||
* %dx : total length of block (including any uninitialised data portion)
|
||||
* Returns:
|
||||
* %esi : next source physical address (will be a multiple of 16)
|
||||
* Corrupts:
|
||||
* %ecx, %edx
|
||||
****************************************************************************
|
||||
*/
|
||||
.section ".prefix.lib"
|
||||
.code16
|
||||
install_basemem:
|
||||
/* Preserve registers */
|
||||
pushl %edi
|
||||
pushw %ds
|
||||
|
||||
/* Preserve original %esi */
|
||||
pushl %esi
|
||||
|
||||
/* Install to specified address */
|
||||
shrl $4, %esi
|
||||
movw %si, %ds
|
||||
xorw %si, %si
|
||||
xorl %edi, %edi
|
||||
movzwl %cx, %ecx
|
||||
movzwl %dx, %edx
|
||||
call install_block
|
||||
|
||||
/* Fix up %esi for return */
|
||||
popl %ecx
|
||||
addl %ecx, %esi
|
||||
|
||||
/* Restore registers */
|
||||
popw %ds
|
||||
popl %edi
|
||||
ret
|
||||
.size install_basemem, . - install_basemem
|
||||
|
||||
/****************************************************************************
|
||||
* install_highmem (real-mode near call)
|
||||
*
|
||||
* Install source block into high memory
|
||||
*
|
||||
* Parameters:
|
||||
* %esi : source physical address (must be a multiple of 16)
|
||||
* %edi : destination physical address
|
||||
* %ecx : length of (decompressed) data
|
||||
* %edx : total length of block (including any uninitialised data portion)
|
||||
* Returns:
|
||||
* %esi : next source physical address (will be a multiple of 16)
|
||||
* Corrupts:
|
||||
* %ecx, %edx
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef KEEP_IT_REAL
|
||||
|
||||
.section ".prefix.lib"
|
||||
.code16
|
||||
install_highmem:
|
||||
/* Preserve registers */
|
||||
pushw %ax
|
||||
|
||||
/* Install to specified address */
|
||||
movw $install_block, %ax
|
||||
call pm_call
|
||||
|
||||
/* Restore registers */
|
||||
popw %ax
|
||||
ret
|
||||
.size install_highmem, . - install_highmem
|
||||
|
||||
#endif /* KEEP_IT_REAL */
|
||||
|
||||
/****************************************************************************
|
||||
* install (real-mode near call)
|
||||
*
|
||||
@ -555,17 +548,19 @@ install_prealloc:
|
||||
shll $4, %esi
|
||||
1: addl $_payload_offset, %esi
|
||||
|
||||
/* Install .text16 */
|
||||
movw %ax, %es
|
||||
movw $_text16_size, %cx
|
||||
movw %cx, %dx
|
||||
call install_basemem
|
||||
|
||||
/* Install .data16 */
|
||||
movw %bx, %es
|
||||
movw $_data16_progbits_size, %cx
|
||||
movw $_data16_size, %dx
|
||||
call install_basemem
|
||||
/* Install .text16 and .data16 */
|
||||
pushl %edi
|
||||
movzwl %ax, %edi
|
||||
shll $4, %edi
|
||||
movl $_text16_size, %ecx
|
||||
movl %ecx, %edx
|
||||
call install_block /* .text16 */
|
||||
movzwl %bx, %edi
|
||||
shll $4, %edi
|
||||
movl $_data16_progbits_size, %ecx
|
||||
movl $_data16_size, %edx
|
||||
call install_block /* .data16 */
|
||||
popl %edi
|
||||
|
||||
/* Set up %ds for access to .data16 */
|
||||
movw %bx, %ds
|
||||
@ -581,9 +576,7 @@ install_prealloc:
|
||||
*/
|
||||
movl $_textdata_progbits_size, %ecx
|
||||
movl $_textdata_size, %edx
|
||||
pushl %edi
|
||||
call install_highmem
|
||||
popl %edi
|
||||
call install_block
|
||||
|
||||
/* Initialise librm at current location */
|
||||
movw %ax, (init_librm_vector+2)
|
||||
|
Loading…
x
Reference in New Issue
Block a user