mirror of https://github.com/ipxe/ipxe.git
Merge branch 'pxerom-pmm'
commit
08b19abf94
|
@ -17,6 +17,10 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
.arch i386
|
||||||
|
.section ".prefix.lib", "awx", @progbits
|
||||||
|
.section ".data16", "aw", @progbits
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* High memory temporary load address
|
* High memory temporary load address
|
||||||
*
|
*
|
||||||
|
@ -27,24 +31,125 @@
|
||||||
* We use the start of an even megabyte so that we don't have to worry
|
* We use the start of an even megabyte so that we don't have to worry
|
||||||
* about the current state of the A20 line.
|
* about the current state of the A20 line.
|
||||||
*
|
*
|
||||||
* We use 4MB rather than 2MB because there is at least one commercial
|
* We use 4MB rather than 2MB because some PXE stack / PMM BIOS
|
||||||
* PXE ROM ("Broadcom UNDI, PXE-2.1 (build 082) v2.0.4") which stores
|
* combinations are known to place data required by other UNDI ROMs
|
||||||
* data required by the UNDI ROM loader (yes, the ROM loader; that's
|
* loader around the 2MB mark.
|
||||||
* the component which should be impossible to damage short of
|
|
||||||
* screwing with the MMU) around the 2MB mark. Sadly, this is not a
|
|
||||||
* joke.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
#define HIGHMEM_LOADPOINT ( 4 << 20 )
|
.globl HIGHMEM_LOADPOINT
|
||||||
|
.equ HIGHMEM_LOADPOINT, ( 4 << 20 )
|
||||||
|
|
||||||
/* Image compression enabled */
|
/* Image compression enabled */
|
||||||
#define COMPRESS 1
|
#define COMPRESS 1
|
||||||
|
|
||||||
#define CR0_PE 1
|
#define CR0_PE 1
|
||||||
|
|
||||||
.arch i386
|
/*****************************************************************************
|
||||||
.section ".prefix.lib", "awx", @progbits
|
* Utility function: print character (with LF -> LF,CR translation)
|
||||||
.section ".data16", "aw", @progbits
|
*
|
||||||
|
* Parameters:
|
||||||
|
* %al : character to print
|
||||||
|
* Returns:
|
||||||
|
* Nothing
|
||||||
|
* Corrupts:
|
||||||
|
* %ax
|
||||||
|
*****************************************************************************
|
||||||
|
*/
|
||||||
|
.section ".prefix.lib"
|
||||||
|
.code16
|
||||||
|
.globl print_character
|
||||||
|
print_character:
|
||||||
|
/* Preserve registers */
|
||||||
|
pushw %bx
|
||||||
|
pushw %bp
|
||||||
|
/* Print character */
|
||||||
|
movw $0x0007, %bx /* page 0, attribute 7 (normal) */
|
||||||
|
movb $0x0e, %ah /* write char, tty mode */
|
||||||
|
cmpb $0x0a, %al /* '\n'? */
|
||||||
|
jne 1f
|
||||||
|
int $0x10
|
||||||
|
movb $0x0d, %al
|
||||||
|
1: int $0x10
|
||||||
|
/* Restore registers and return */
|
||||||
|
popw %bp
|
||||||
|
popw %bx
|
||||||
|
ret
|
||||||
|
.size print_character, . - print_character
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Utility function: print a NUL-terminated string
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* %ds:si : string to print
|
||||||
|
* Returns:
|
||||||
|
* %ds:si : character after terminating NUL
|
||||||
|
*****************************************************************************
|
||||||
|
*/
|
||||||
|
.section ".prefix.lib"
|
||||||
|
.code16
|
||||||
|
.globl print_message
|
||||||
|
print_message:
|
||||||
|
/* Preserve registers */
|
||||||
|
pushw %ax
|
||||||
|
/* Print string */
|
||||||
|
1: lodsb
|
||||||
|
testb %al, %al
|
||||||
|
je 2f
|
||||||
|
call print_character
|
||||||
|
jmp 1b
|
||||||
|
2: /* Restore registers and return */
|
||||||
|
popw %ax
|
||||||
|
ret
|
||||||
|
.size print_message, . - print_message
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Utility functions: print hex digit/byte/word/dword
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* %al (low nibble) : digit to print
|
||||||
|
* %al : byte to print
|
||||||
|
* %ax : word to print
|
||||||
|
* %eax : dword to print
|
||||||
|
* Returns:
|
||||||
|
* Nothing
|
||||||
|
*****************************************************************************
|
||||||
|
*/
|
||||||
|
.section ".prefix.lib"
|
||||||
|
.code16
|
||||||
|
.globl print_hex_dword
|
||||||
|
print_hex_dword:
|
||||||
|
rorl $16, %eax
|
||||||
|
call print_hex_word
|
||||||
|
rorl $16, %eax
|
||||||
|
/* Fall through */
|
||||||
|
.size print_hex_dword, . - print_hex_dword
|
||||||
|
.globl print_hex_word
|
||||||
|
print_hex_word:
|
||||||
|
xchgb %al, %ah
|
||||||
|
call print_hex_byte
|
||||||
|
xchgb %al, %ah
|
||||||
|
/* Fall through */
|
||||||
|
.size print_hex_word, . - print_hex_word
|
||||||
|
.globl print_hex_byte
|
||||||
|
print_hex_byte:
|
||||||
|
rorb $4, %al
|
||||||
|
call print_hex_nibble
|
||||||
|
rorb $4, %al
|
||||||
|
/* Fall through */
|
||||||
|
.size print_hex_byte, . - print_hex_byte
|
||||||
|
.globl print_hex_nibble
|
||||||
|
print_hex_nibble:
|
||||||
|
/* Preserve registers */
|
||||||
|
pushw %ax
|
||||||
|
/* Print digit (technique by Norbert Juffa <norbert.juffa@amd.com> */
|
||||||
|
andb $0x0f, %al
|
||||||
|
cmpb $10, %al
|
||||||
|
sbbb $0x69, %al
|
||||||
|
das
|
||||||
|
call print_character
|
||||||
|
/* Restore registers and return */
|
||||||
|
popw %ax
|
||||||
|
ret
|
||||||
|
.size print_hex_nibble, . - print_hex_nibble
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* pm_call (real-mode near call)
|
* pm_call (real-mode near call)
|
||||||
|
@ -70,8 +175,9 @@
|
||||||
#ifndef KEEP_IT_REAL
|
#ifndef KEEP_IT_REAL
|
||||||
|
|
||||||
/* GDT for protected-mode calls */
|
/* GDT for protected-mode calls */
|
||||||
.section ".data16"
|
.section ".prefix.lib"
|
||||||
.align 16
|
.align 16
|
||||||
|
pm_call_vars:
|
||||||
gdt:
|
gdt:
|
||||||
gdt_limit: .word gdt_length - 1
|
gdt_limit: .word gdt_length - 1
|
||||||
gdt_base: .long 0
|
gdt_base: .long 0
|
||||||
|
@ -92,18 +198,24 @@ gdt_end:
|
||||||
.equ gdt_length, . - gdt
|
.equ gdt_length, . - gdt
|
||||||
.size gdt, . - gdt
|
.size gdt, . - gdt
|
||||||
|
|
||||||
.section ".data16"
|
.section ".prefix.lib"
|
||||||
.align 16
|
.align 16
|
||||||
pm_saved_gdt:
|
pm_saved_gdt:
|
||||||
.long 0, 0
|
.long 0, 0
|
||||||
.size pm_saved_gdt, . - pm_saved_gdt
|
.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"
|
.section ".prefix.lib"
|
||||||
.code16
|
.code16
|
||||||
pm_call:
|
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
|
pushfl
|
||||||
sgdt pm_saved_gdt
|
|
||||||
pushw %gs
|
pushw %gs
|
||||||
pushw %fs
|
pushw %fs
|
||||||
pushw %es
|
pushw %es
|
||||||
|
@ -112,27 +224,43 @@ pm_call:
|
||||||
pushw %cs
|
pushw %cs
|
||||||
pushw $99f
|
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 */
|
/* Set up GDT bases */
|
||||||
pushl %eax
|
pushl %eax
|
||||||
pushw %bx
|
pushl %edi
|
||||||
xorl %eax, %eax
|
xorl %eax, %eax
|
||||||
movw %ds, %ax
|
movw %ss, %ax
|
||||||
shll $4, %eax
|
shll $4, %eax
|
||||||
addl $gdt, %eax
|
movzwl %bp, %edi
|
||||||
movl %eax, gdt_base
|
leal PM_CALL_VAR(gdt)(%eax, %edi), %eax
|
||||||
|
movl %eax, PM_CALL_VAR(gdt_base)(%bp)
|
||||||
movw %cs, %ax
|
movw %cs, %ax
|
||||||
movw $pm_cs, %bx
|
movw $PM_CALL_VAR(pm_cs), %di
|
||||||
call set_seg_base
|
call set_seg_base
|
||||||
movw %ss, %ax
|
movw %ss, %ax
|
||||||
movw $pm_ss, %bx
|
movw $PM_CALL_VAR(pm_ss), %di
|
||||||
call set_seg_base
|
call set_seg_base
|
||||||
popw %bx
|
popl %edi
|
||||||
popl %eax
|
popl %eax
|
||||||
|
|
||||||
/* Switch CPU to protected mode and load up segment registers */
|
/* Switch CPU to protected mode and load up segment registers */
|
||||||
pushl %eax
|
pushl %eax
|
||||||
cli
|
cli
|
||||||
lgdt gdt
|
lgdt PM_CALL_VAR(gdt)(%bp)
|
||||||
movl %cr0, %eax
|
movl %cr0, %eax
|
||||||
orb $CR0_PE, %al
|
orb $CR0_PE, %al
|
||||||
movl %eax, %cr0
|
movl %eax, %cr0
|
||||||
|
@ -168,18 +296,19 @@ pm_call:
|
||||||
popw %es
|
popw %es
|
||||||
popw %fs
|
popw %fs
|
||||||
popw %gs
|
popw %gs
|
||||||
lgdt pm_saved_gdt
|
lgdt PM_CALL_VAR(pm_saved_gdt)(%bp)
|
||||||
popfl
|
popfl
|
||||||
|
movw %bp, %sp
|
||||||
|
popw %bp
|
||||||
ret
|
ret
|
||||||
.size pm_call, . - pm_call
|
.size pm_call, . - pm_call
|
||||||
|
|
||||||
set_seg_base:
|
set_seg_base:
|
||||||
rolw $4, %ax
|
rolw $4, %ax
|
||||||
movw %ax, 2(%bx)
|
movw %ax, 2(%bp,%di)
|
||||||
andw $0xfff0, 2(%bx)
|
andw $0xfff0, 2(%bp,%di)
|
||||||
movb %al, 4(%bx)
|
movb %al, 4(%bp,%di)
|
||||||
andb $0x0f, 4(%bx)
|
andb $0x0f, 4(%bp,%di)
|
||||||
ret
|
ret
|
||||||
.size set_seg_base, . - set_seg_base
|
.size set_seg_base, . - set_seg_base
|
||||||
|
|
||||||
|
@ -196,7 +325,7 @@ set_seg_base:
|
||||||
* %ecx : length
|
* %ecx : length
|
||||||
* Returns:
|
* Returns:
|
||||||
* %ds:esi : next source address
|
* %ds:esi : next source address
|
||||||
* %ds:esi : next destination address
|
* %es:edi : next destination address
|
||||||
* Corrupts:
|
* Corrupts:
|
||||||
* None
|
* None
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
|
@ -211,24 +340,57 @@ copy_bytes:
|
||||||
.size copy_bytes, . - 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
|
* Install block to specified address
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* %ds:esi : source address (must be a multiple of 16)
|
* %esi : source physical address (must be a multiple of 16)
|
||||||
* %es:edi : destination address
|
* %edi : destination physical address (must be a multiple of 16)
|
||||||
* %ecx : length of (decompressed) data
|
* %ecx : length of (decompressed) data
|
||||||
* %edx : total length of block (including any uninitialised data portion)
|
* %edx : total length of block (including any uninitialised data portion)
|
||||||
* Returns:
|
* Returns:
|
||||||
* %ds:esi : next source address (will be a multiple of 16)
|
* %esi : next source physical address (will be a multiple of 16)
|
||||||
* Corrupts:
|
* Corrupts:
|
||||||
* %edi, %ecx, %edx
|
* none
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
*/
|
*/
|
||||||
.section ".prefix.lib"
|
.section ".prefix.lib"
|
||||||
.code16
|
.code16
|
||||||
install_block:
|
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
|
#if COMPRESS
|
||||||
/* Decompress source to destination */
|
/* Decompress source to destination */
|
||||||
call decompress16
|
call decompress16
|
||||||
|
@ -249,6 +411,28 @@ install_block:
|
||||||
addl $0xf, %esi
|
addl $0xf, %esi
|
||||||
andl $~0xf, %esi
|
andl $~0xf, %esi
|
||||||
|
|
||||||
|
|
||||||
|
#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
|
ret
|
||||||
.size install_block, . - install_block
|
.size install_block, . - install_block
|
||||||
|
|
||||||
|
@ -270,6 +454,7 @@ install_block:
|
||||||
*/
|
*/
|
||||||
.section ".prefix.lib"
|
.section ".prefix.lib"
|
||||||
.code16
|
.code16
|
||||||
|
.globl alloc_basemem
|
||||||
alloc_basemem:
|
alloc_basemem:
|
||||||
/* FBMS => %ax as segment address */
|
/* FBMS => %ax as segment address */
|
||||||
movw $0x40, %ax
|
movw $0x40, %ax
|
||||||
|
@ -295,98 +480,16 @@ alloc_basemem:
|
||||||
ret
|
ret
|
||||||
.size alloc_basemem, . - alloc_basemem
|
.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:
|
|
||||||
* %edi, %ecx, %edx
|
|
||||||
****************************************************************************
|
|
||||||
*/
|
|
||||||
.section ".prefix.lib"
|
|
||||||
.code16
|
|
||||||
install_basemem:
|
|
||||||
/* Preserve registers */
|
|
||||||
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
|
|
||||||
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:
|
|
||||||
* %edi, %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)
|
* install (real-mode near call)
|
||||||
* install_prealloc (real-mode near call)
|
|
||||||
*
|
*
|
||||||
* Install all text and data segments.
|
* Install all text and data segments.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* %ax : .text16 segment address (install_prealloc only)
|
* none
|
||||||
* %bx : .data16 segment address (install_prealloc only)
|
|
||||||
* Returns:
|
* Returns:
|
||||||
* %ax : .text16 segment address
|
* %ax : .text16 segment address
|
||||||
* %bx : .data16 segment address
|
* %bx : .data16 segment address
|
||||||
* %edi : .text physical address (if applicable)
|
|
||||||
* Corrupts:
|
* Corrupts:
|
||||||
* none
|
* none
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
|
@ -395,38 +498,69 @@ install_highmem:
|
||||||
.code16
|
.code16
|
||||||
.globl install
|
.globl install
|
||||||
install:
|
install:
|
||||||
|
/* Preserve registers */
|
||||||
|
pushl %esi
|
||||||
|
pushl %edi
|
||||||
/* Allocate space for .text16 and .data16 */
|
/* Allocate space for .text16 and .data16 */
|
||||||
call alloc_basemem
|
call alloc_basemem
|
||||||
|
/* Image source = %cs:0000 */
|
||||||
|
xorl %esi, %esi
|
||||||
|
/* Image destination = HIGHMEM_LOADPOINT */
|
||||||
|
movl $HIGHMEM_LOADPOINT, %edi
|
||||||
|
/* Install text and data segments */
|
||||||
|
call install_prealloc
|
||||||
|
/* Restore registers and return */
|
||||||
|
popl %edi
|
||||||
|
popl %esi
|
||||||
|
ret
|
||||||
.size install, . - install
|
.size install, . - install
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* install_prealloc (real-mode near call)
|
||||||
|
*
|
||||||
|
* Install all text and data segments.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* %ax : .text16 segment address
|
||||||
|
* %bx : .data16 segment address
|
||||||
|
* %esi : Image source physical address (or zero for %cs:0000)
|
||||||
|
* %edi : Decompression temporary area physical address
|
||||||
|
* Corrupts:
|
||||||
|
* none
|
||||||
|
****************************************************************************
|
||||||
|
*/
|
||||||
|
.section ".prefix.lib"
|
||||||
|
.code16
|
||||||
.globl install_prealloc
|
.globl install_prealloc
|
||||||
install_prealloc:
|
install_prealloc:
|
||||||
/* Save registers */
|
/* Save registers */
|
||||||
|
pushal
|
||||||
pushw %ds
|
pushw %ds
|
||||||
pushw %es
|
pushw %es
|
||||||
pushl %esi
|
|
||||||
pushl %ecx
|
|
||||||
pushl %edx
|
|
||||||
|
|
||||||
/* Sanity: clear the direction flag asap */
|
/* Sanity: clear the direction flag asap */
|
||||||
cld
|
cld
|
||||||
|
|
||||||
/* Calculate physical address of payload (i.e. first source) */
|
/* Calculate physical address of payload (i.e. first source) */
|
||||||
xorl %esi, %esi
|
testl %esi, %esi
|
||||||
|
jnz 1f
|
||||||
movw %cs, %si
|
movw %cs, %si
|
||||||
shll $4, %esi
|
shll $4, %esi
|
||||||
addl $_payload_offset, %esi
|
1: addl $_payload_offset, %esi
|
||||||
|
|
||||||
/* Install .text16 */
|
/* Install .text16 and .data16 */
|
||||||
movw %ax, %es
|
pushl %edi
|
||||||
movw $_text16_size, %cx
|
movzwl %ax, %edi
|
||||||
movw %cx, %dx
|
shll $4, %edi
|
||||||
call install_basemem
|
movl $_text16_size, %ecx
|
||||||
|
movl %ecx, %edx
|
||||||
/* Install .data16 */
|
call install_block /* .text16 */
|
||||||
movw %bx, %es
|
movzwl %bx, %edi
|
||||||
movw $_data16_progbits_size, %cx
|
shll $4, %edi
|
||||||
movw $_data16_size, %dx
|
movl $_data16_progbits_size, %ecx
|
||||||
call install_basemem
|
movl $_data16_size, %edx
|
||||||
|
call install_block /* .data16 */
|
||||||
|
popl %edi
|
||||||
|
|
||||||
/* Set up %ds for access to .data16 */
|
/* Set up %ds for access to .data16 */
|
||||||
movw %bx, %ds
|
movw %bx, %ds
|
||||||
|
@ -440,12 +574,9 @@ install_prealloc:
|
||||||
* prior to reading the E820 memory map and relocating
|
* prior to reading the E820 memory map and relocating
|
||||||
* properly.
|
* properly.
|
||||||
*/
|
*/
|
||||||
movl $HIGHMEM_LOADPOINT, %edi
|
|
||||||
movl $_textdata_progbits_size, %ecx
|
movl $_textdata_progbits_size, %ecx
|
||||||
movl $_textdata_size, %edx
|
movl $_textdata_size, %edx
|
||||||
pushl %edi
|
call install_block
|
||||||
call install_highmem
|
|
||||||
popl %edi
|
|
||||||
|
|
||||||
/* Initialise librm at current location */
|
/* Initialise librm at current location */
|
||||||
movw %ax, (init_librm_vector+2)
|
movw %ax, (init_librm_vector+2)
|
||||||
|
@ -473,11 +604,9 @@ install_prealloc:
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* Restore registers */
|
/* Restore registers */
|
||||||
popl %edx
|
|
||||||
popl %ecx
|
|
||||||
popl %esi
|
|
||||||
popw %es
|
popw %es
|
||||||
popw %ds
|
popw %ds
|
||||||
|
popal
|
||||||
ret
|
ret
|
||||||
.size install_prealloc, . - install_prealloc
|
.size install_prealloc, . - install_prealloc
|
||||||
|
|
||||||
|
|
|
@ -320,112 +320,6 @@ print_free_basemem:
|
||||||
finished:
|
finished:
|
||||||
jmp run_etherboot
|
jmp run_etherboot
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Subroutine: print character (with LF -> LF,CR translation)
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* %al : character to print
|
|
||||||
* Returns:
|
|
||||||
* Nothing
|
|
||||||
*****************************************************************************
|
|
||||||
*/
|
|
||||||
print_character:
|
|
||||||
/* Preserve registers */
|
|
||||||
pushw %ax
|
|
||||||
pushw %bx
|
|
||||||
pushw %bp
|
|
||||||
/* Print character */
|
|
||||||
movw $0x0007, %bx /* page 0, attribute 7 (normal) */
|
|
||||||
movb $0x0e, %ah /* write char, tty mode */
|
|
||||||
cmpb $0x0a, %al /* '\n'? */
|
|
||||||
jne 1f
|
|
||||||
int $0x10
|
|
||||||
movb $0x0d, %al
|
|
||||||
1: int $0x10
|
|
||||||
/* Restore registers and return */
|
|
||||||
popw %bp
|
|
||||||
popw %bx
|
|
||||||
popw %ax
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Subroutine: print a NUL-terminated string
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* %ds:%si : string to print
|
|
||||||
* Returns:
|
|
||||||
* Nothing
|
|
||||||
*****************************************************************************
|
|
||||||
*/
|
|
||||||
print_message:
|
|
||||||
/* Preserve registers */
|
|
||||||
pushw %ax
|
|
||||||
pushw %si
|
|
||||||
/* Print string */
|
|
||||||
1: lodsb
|
|
||||||
testb %al, %al
|
|
||||||
je 2f
|
|
||||||
call print_character
|
|
||||||
jmp 1b
|
|
||||||
2: /* Restore registers and return */
|
|
||||||
popw %si
|
|
||||||
popw %ax
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Subroutine: print hex digit
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* %al (low nibble) : digit to print
|
|
||||||
* Returns:
|
|
||||||
* Nothing
|
|
||||||
*****************************************************************************
|
|
||||||
*/
|
|
||||||
print_hex_nibble:
|
|
||||||
/* Preserve registers */
|
|
||||||
pushw %ax
|
|
||||||
/* Print digit (technique by Norbert Juffa <norbert.juffa@amd.com> */
|
|
||||||
andb $0x0f, %al
|
|
||||||
cmpb $10, %al
|
|
||||||
sbbb $0x69, %al
|
|
||||||
das
|
|
||||||
call print_character
|
|
||||||
/* Restore registers and return */
|
|
||||||
popw %ax
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Subroutine: print hex byte
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* %al : byte to print
|
|
||||||
* Returns:
|
|
||||||
* Nothing
|
|
||||||
*****************************************************************************
|
|
||||||
*/
|
|
||||||
print_hex_byte:
|
|
||||||
rorb $4, %al
|
|
||||||
call print_hex_nibble
|
|
||||||
rorb $4, %al
|
|
||||||
call print_hex_nibble
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Subroutine: print hex word
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* %ax : word to print
|
|
||||||
* Returns:
|
|
||||||
* Nothing
|
|
||||||
*****************************************************************************
|
|
||||||
*/
|
|
||||||
print_hex_word:
|
|
||||||
xchgb %al, %ah
|
|
||||||
call print_hex_byte
|
|
||||||
xchgb %al, %ah
|
|
||||||
call print_hex_byte
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Subroutine: print segment:offset address
|
* Subroutine: print segment:offset address
|
||||||
*
|
*
|
||||||
|
|
|
@ -6,6 +6,11 @@
|
||||||
* table so using a noticeable amount of stack space is a no-no.
|
* table so using a noticeable amount of stack space is a no-no.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define PNP_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) )
|
||||||
|
#define PMM_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'M' << 16 ) + ( 'M' << 24 ) )
|
||||||
|
#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
|
||||||
|
#define PNP_GET_BBS_VERSION 0x60
|
||||||
|
|
||||||
.text
|
.text
|
||||||
.code16
|
.code16
|
||||||
.arch i386
|
.arch i386
|
||||||
|
@ -15,7 +20,9 @@
|
||||||
romheader:
|
romheader:
|
||||||
.word 0xAA55 /* BIOS extension signature */
|
.word 0xAA55 /* BIOS extension signature */
|
||||||
romheader_size: .byte _load_size_sect /* Size in 512-byte blocks */
|
romheader_size: .byte _load_size_sect /* Size in 512-byte blocks */
|
||||||
jmp init_vector /* Initialisation vector */
|
jmp init /* Initialisation vector */
|
||||||
|
checksum:
|
||||||
|
.byte 0
|
||||||
.org 0x16
|
.org 0x16
|
||||||
.word undiheader
|
.word undiheader
|
||||||
.org 0x18
|
.org 0x18
|
||||||
|
@ -72,7 +79,7 @@ pnpheader:
|
||||||
.byte 0x54 /* Device indicator */
|
.byte 0x54 /* Device indicator */
|
||||||
.word 0x0000 /* Boot connection vector */
|
.word 0x0000 /* Boot connection vector */
|
||||||
.word 0x0000 /* Disconnect vector */
|
.word 0x0000 /* Disconnect vector */
|
||||||
.word exec_vector /* Boot execution vector */
|
.word bev_entry /* Boot execution vector */
|
||||||
.word 0x0000 /* Reserved */
|
.word 0x0000 /* Reserved */
|
||||||
.word 0x0000 /* Static resource information vector*/
|
.word 0x0000 /* Static resource information vector*/
|
||||||
.equ pnpheader_len, . - pnpheader
|
.equ pnpheader_len, . - pnpheader
|
||||||
|
@ -98,60 +105,210 @@ undiheader:
|
||||||
.equ undiheader_len, . - undiheader
|
.equ undiheader_len, . - undiheader
|
||||||
.size undiheader, . - undiheader
|
.size undiheader, . - undiheader
|
||||||
|
|
||||||
/* Initialisation vector
|
/* Initialisation (called once during POST)
|
||||||
*
|
*
|
||||||
* Determine whether or not this is a PnP system via a signature
|
* Determine whether or not this is a PnP system via a signature
|
||||||
* check. If it is PnP, return to the PnP BIOS indicating that we are
|
* check. If it is PnP, return to the PnP BIOS indicating that we are
|
||||||
* a boot-capable device; the BIOS will call our boot execution vector
|
* a boot-capable device; the BIOS will call our boot execution vector
|
||||||
* if it wants to boot us. If it is not PnP, hook INT 19.
|
* if it wants to boot us. If it is not PnP, hook INT 19.
|
||||||
*/
|
*/
|
||||||
init_vector:
|
init:
|
||||||
pushw %si
|
/* Preserve registers, clear direction flag, set %ds=%cs */
|
||||||
cmpw $'$'+'P'*256, %es:0(%di)
|
pushaw
|
||||||
jne notpnp
|
|
||||||
cmpw $'n'+'P'*256, %es:2(%di)
|
|
||||||
jne notpnp
|
|
||||||
ispnp:
|
|
||||||
movw $ispnp_message, %si
|
|
||||||
jmp 99f
|
|
||||||
notpnp:
|
|
||||||
pushw %ds
|
pushw %ds
|
||||||
pushw $0
|
pushw %es
|
||||||
popw %ds
|
cld
|
||||||
pushw %cs
|
pushw %cs
|
||||||
pushw $exec_vector
|
|
||||||
popl ( 0x19 * 4 )
|
|
||||||
popw %ds
|
popw %ds
|
||||||
movw $notpnp_message, %si
|
/* Print message as early as possible */
|
||||||
99:
|
movw $init_message, %si
|
||||||
call print_message
|
call print_message
|
||||||
|
/* Check for PnP BIOS */
|
||||||
|
testw $0x0f, %di /* PnP signature must be aligned - bochs */
|
||||||
|
jnz hook_int19 /* uses unalignment to indicate 'fake' PnP. */
|
||||||
|
cmpl $PNP_SIGNATURE, %es:0(%di)
|
||||||
|
jne hook_int19
|
||||||
|
/* Is PnP: print PnP message */
|
||||||
|
movw $init_message_pnp, %si
|
||||||
|
call print_message
|
||||||
|
xchgw %bx, %bx
|
||||||
|
/* Check for BBS */
|
||||||
|
pushw %es:0x1b(%di) /* Real-mode data segment */
|
||||||
|
pushw %ds /* &(bbs_version) */
|
||||||
|
pushw $bbs_version
|
||||||
|
pushw $PNP_GET_BBS_VERSION
|
||||||
|
lcall *%es:0xd(%di)
|
||||||
|
addw $8, %sp
|
||||||
|
testw %ax, %ax
|
||||||
|
jne hook_int19
|
||||||
|
movw $init_message_bbs, %si
|
||||||
|
call print_message
|
||||||
|
jmp hook_bbs
|
||||||
|
/* Not BBS-compliant - must hook INT 19 */
|
||||||
|
hook_int19:
|
||||||
|
movw $init_message_int19, %si
|
||||||
|
call print_message
|
||||||
|
xorw %ax, %ax
|
||||||
|
movw %ax, %es
|
||||||
|
pushw %cs
|
||||||
|
pushw $int19_entry
|
||||||
|
popl %es:( 0x19 * 4 )
|
||||||
|
hook_bbs:
|
||||||
|
/* Check for PMM */
|
||||||
|
movw $( 0xe000 - 1 ), %di
|
||||||
|
pmm_scan:
|
||||||
|
incw %di
|
||||||
|
jz no_pmm
|
||||||
|
movw %di, %es
|
||||||
|
cmpl $PMM_SIGNATURE, %es:0
|
||||||
|
jne pmm_scan
|
||||||
|
xorw %bx, %bx
|
||||||
|
xorw %si, %si
|
||||||
|
movzbw %es:5, %cx
|
||||||
|
1: es lodsb
|
||||||
|
addb %al, %bl
|
||||||
|
loop 1b
|
||||||
|
jnz pmm_scan
|
||||||
|
/* PMM found: print PMM message */
|
||||||
|
movw $init_message_pmm, %si
|
||||||
|
call print_message
|
||||||
|
/* Try to allocate 2MB block via PMM */
|
||||||
|
pushw $0x0006 /* Aligned, extended memory */
|
||||||
|
pushl $0xffffffff /* No handle */
|
||||||
|
pushl $( 0x00200000 / 16 ) /* 2MB in paragraphs */
|
||||||
|
pushw $0x0000 /* pmmAllocate */
|
||||||
|
lcall *%es:7
|
||||||
|
addw $12, %sp
|
||||||
|
testw %dx, %dx /* %ax==0 even on success, since align=2MB */
|
||||||
|
jnz gotpmm
|
||||||
|
movw $init_message_pmm_failed, %si
|
||||||
|
call print_message
|
||||||
|
jmp no_pmm
|
||||||
|
gotpmm: /* PMM allocation succeeded: copy ROM to PMM block */
|
||||||
|
pushal /* PMM presence implies 1kB stack */
|
||||||
|
movw %ax, %es /* %ax=0 already - see above */
|
||||||
|
pushw %dx
|
||||||
|
pushw %ax
|
||||||
|
popl %edi
|
||||||
|
movl %edi, image_source
|
||||||
|
xorl %esi, %esi
|
||||||
|
movzbl romheader_size, %ecx
|
||||||
|
shll $9, %ecx
|
||||||
|
addr32 rep movsb /* PMM presence implies flat real mode */
|
||||||
|
movl %edi, decompress_to
|
||||||
|
/* Shrink ROM and update checksum */
|
||||||
|
xorw %bx, %bx
|
||||||
|
xorw %si, %si
|
||||||
|
movw $_prefix_size_sect, %cx
|
||||||
|
movb %cl, romheader_size
|
||||||
|
shlw $9, %cx
|
||||||
|
1: lodsb
|
||||||
|
addb %al, %bl
|
||||||
|
loop 1b
|
||||||
|
subb %bl, checksum
|
||||||
|
popal
|
||||||
|
no_pmm:
|
||||||
|
/* Print CRLF to terminate messages */
|
||||||
|
movw $'\n', %ax
|
||||||
|
call print_character
|
||||||
|
/* Restore registers */
|
||||||
|
popw %es
|
||||||
|
popw %ds
|
||||||
|
popaw
|
||||||
|
/* Indicate boot capability to PnP BIOS, if present */
|
||||||
movw $0x20, %ax
|
movw $0x20, %ax
|
||||||
popw %si
|
|
||||||
lret
|
lret
|
||||||
.size init_vector, . - init_vector
|
.size init, . - init
|
||||||
|
|
||||||
ispnp_message:
|
init_message:
|
||||||
.asciz "gPXE detected PnP BIOS\r\n"
|
.asciz "gPXE (http://etherboot.org) -"
|
||||||
.size ispnp_message, . - ispnp_message
|
.size init_message, . - init_message
|
||||||
notpnp_message:
|
init_message_pnp:
|
||||||
.asciz "gPXE detected non-PnP BIOS\r\n"
|
.asciz " PnP"
|
||||||
.size notpnp_message, . - notpnp_message
|
.size init_message_pnp, . - init_message_pnp
|
||||||
|
init_message_bbs:
|
||||||
|
.asciz " BBS"
|
||||||
|
.size init_message_bbs, . - init_message_bbs
|
||||||
|
init_message_pmm:
|
||||||
|
.asciz " PMM"
|
||||||
|
.size init_message_pmm, . - init_message_pmm
|
||||||
|
init_message_pmm_failed:
|
||||||
|
.asciz "(failed)"
|
||||||
|
.size init_message_pmm_failed, . - init_message_pmm_failed
|
||||||
|
init_message_int19:
|
||||||
|
.asciz " INT19"
|
||||||
|
.size init_message_int19, . - init_message_int19
|
||||||
|
|
||||||
/* Boot execution vector
|
/* ROM image location
|
||||||
*pciheader_size
|
*
|
||||||
* Called by the PnP BIOS when it wants to boot us, or via the hooked
|
* May be either within option ROM space, or within PMM-allocated block.
|
||||||
* INT 19 if we detected a non-PnP BIOS.
|
|
||||||
*/
|
*/
|
||||||
exec_vector:
|
image_source:
|
||||||
/* Obtain a reasonably-sized stack */
|
.long 0
|
||||||
|
.size image_source, . - image_source
|
||||||
|
|
||||||
|
/* Temporary decompression area
|
||||||
|
*
|
||||||
|
* May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block.
|
||||||
|
*/
|
||||||
|
decompress_to:
|
||||||
|
.long HIGHMEM_LOADPOINT
|
||||||
|
.size decompress_to, . - decompress_to
|
||||||
|
|
||||||
|
/* BBS version
|
||||||
|
*
|
||||||
|
* Filled in by BBS BIOS. We ignore the value.
|
||||||
|
*/
|
||||||
|
bbs_version:
|
||||||
|
.word 0
|
||||||
|
|
||||||
|
/* Boot Execution Vector entry point
|
||||||
|
*
|
||||||
|
* Called by the PnP BIOS when it wants to boot us.
|
||||||
|
*/
|
||||||
|
bev_entry:
|
||||||
|
pushw %cs
|
||||||
|
call exec
|
||||||
|
lret
|
||||||
|
.size bev_entry, . - bev_entry
|
||||||
|
|
||||||
|
/* INT19 entry point
|
||||||
|
*
|
||||||
|
* Called via the hooked INT 19 if we detected a non-PnP BIOS.
|
||||||
|
*/
|
||||||
|
int19_entry:
|
||||||
|
pushw %cs
|
||||||
|
call exec
|
||||||
|
/* No real way to return from INT19 */
|
||||||
|
int $0x18
|
||||||
|
.size int19_entry, . - int19_entry
|
||||||
|
|
||||||
|
/* Execute as a boot device
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
exec: /* Set %ds = %cs */
|
||||||
|
pushw %cs
|
||||||
|
popw %ds
|
||||||
|
|
||||||
|
/* Print message as soon as possible */
|
||||||
|
movw $exec_message, %si
|
||||||
|
call print_message
|
||||||
|
|
||||||
|
/* Store magic word on BIOS stack and remember BIOS %ss:sp */
|
||||||
|
pushl $STACK_MAGIC
|
||||||
|
movw %ss, %dx
|
||||||
|
movw %sp, %bp
|
||||||
|
|
||||||
|
/* Obtain a reasonably-sized temporary stack */
|
||||||
xorw %ax, %ax
|
xorw %ax, %ax
|
||||||
movw %ax, %ss
|
movw %ax, %ss
|
||||||
movw $0x7c00, %sp
|
movw $0x7c00, %sp
|
||||||
|
|
||||||
movw $exec_message, %si
|
/* Install gPXE */
|
||||||
call print_message
|
movl image_source, %esi
|
||||||
|
movl decompress_to, %edi
|
||||||
call install
|
call alloc_basemem
|
||||||
|
call install_prealloc
|
||||||
|
|
||||||
/* Set up real-mode stack */
|
/* Set up real-mode stack */
|
||||||
movw %bx, %ss
|
movw %bx, %ss
|
||||||
|
@ -162,18 +319,28 @@ exec_vector:
|
||||||
pushw $1f
|
pushw $1f
|
||||||
lret
|
lret
|
||||||
.section ".text16", "awx", @progbits
|
.section ".text16", "awx", @progbits
|
||||||
1:
|
1: /* Call main() */
|
||||||
pushl $main
|
pushl $main
|
||||||
pushw %cs
|
pushw %cs
|
||||||
call prot_call
|
call prot_call
|
||||||
popl %eax /* discard */
|
/* No need to clean up stack; we are about to reload %ss:sp */
|
||||||
|
|
||||||
/* Boot next device */
|
/* Restore BIOS stack */
|
||||||
|
movw %dx, %ss
|
||||||
|
movw %bp, %sp
|
||||||
|
|
||||||
|
/* Check magic word on BIOS stack */
|
||||||
|
popl %eax
|
||||||
|
cmpl $STACK_MAGIC, %eax
|
||||||
|
jne 1f
|
||||||
|
/* BIOS stack OK: return to caller */
|
||||||
|
lret
|
||||||
|
1: /* BIOS stack corrupt: use INT 18 */
|
||||||
int $0x18
|
int $0x18
|
||||||
.previous
|
.previous
|
||||||
|
|
||||||
exec_message:
|
exec_message:
|
||||||
.asciz "gPXE starting boot\r\n"
|
.asciz "gPXE starting boot\n"
|
||||||
.size exec_message, . - exec_message
|
.size exec_message, . - exec_message
|
||||||
|
|
||||||
/* UNDI loader
|
/* UNDI loader
|
||||||
|
@ -182,6 +349,7 @@ exec_message:
|
||||||
*/
|
*/
|
||||||
undiloader:
|
undiloader:
|
||||||
/* Save registers */
|
/* Save registers */
|
||||||
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
pushw %es
|
pushw %es
|
||||||
pushw %bx
|
pushw %bx
|
||||||
|
@ -193,6 +361,8 @@ undiloader:
|
||||||
pushw %di
|
pushw %di
|
||||||
movw %es:12(%di), %bx
|
movw %es:12(%di), %bx
|
||||||
movw %es:14(%di), %ax
|
movw %es:14(%di), %ax
|
||||||
|
movl %cs:image_source, %esi
|
||||||
|
movl %cs:decompress_to, %edi
|
||||||
call install_prealloc
|
call install_prealloc
|
||||||
popw %di
|
popw %di
|
||||||
/* Call UNDI loader C code */
|
/* Call UNDI loader C code */
|
||||||
|
@ -208,24 +378,6 @@ undiloader:
|
||||||
popw %bx
|
popw %bx
|
||||||
popw %es
|
popw %es
|
||||||
popl %edi
|
popl %edi
|
||||||
|
popl %esi
|
||||||
lret
|
lret
|
||||||
.size undiloader, . - undiloader
|
.size undiloader, . - undiloader
|
||||||
|
|
||||||
/* Utility function: print string
|
|
||||||
*/
|
|
||||||
print_message:
|
|
||||||
pushw %ax
|
|
||||||
pushw %bx
|
|
||||||
pushw %bp
|
|
||||||
movw $0x0007, %bx
|
|
||||||
1: cs lodsb
|
|
||||||
testb %al, %al
|
|
||||||
je 2f
|
|
||||||
movb $0x0e, %ah /* write char, tty mode */
|
|
||||||
int $0x10
|
|
||||||
jmp 1b
|
|
||||||
2: popw %bp
|
|
||||||
popw %bx
|
|
||||||
popw %ax
|
|
||||||
ret
|
|
||||||
.size print_message, . - print_message
|
|
||||||
|
|
|
@ -257,6 +257,8 @@ SECTIONS {
|
||||||
/*
|
/*
|
||||||
* Values calculated to save code from doing it
|
* Values calculated to save code from doing it
|
||||||
*/
|
*/
|
||||||
|
_prefix_size_pgh = ( ( _prefix_size + 15 ) / 16 );
|
||||||
|
_prefix_size_sect = ( ( _prefix_size + 511 ) / 512 );
|
||||||
_text16_size_pgh = ( ( _text16_size + 15 ) / 16 );
|
_text16_size_pgh = ( ( _text16_size + 15 ) / 16 );
|
||||||
_data16_size_pgh = ( ( _data16_size + 15 ) / 16 );
|
_data16_size_pgh = ( ( _data16_size + 15 ) / 16 );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue