diff --git a/src/arch/i386/interface/pxe/pxe_call.c b/src/arch/i386/interface/pxe/pxe_call.c index 3a5f4c75..3ccb7fb5 100644 --- a/src/arch/i386/interface/pxe/pxe_call.c +++ b/src/arch/i386/interface/pxe/pxe_call.c @@ -347,6 +347,9 @@ __cdecl void pxe_loader_call ( struct i386_all_regs *ix86 ) { /* Copy parameter block from caller */ copy_from_user ( ¶ms, uparams, 0, sizeof ( params ) ); + /* Fill in ROM segment address */ + ppxe.UNDIROMID.segment = ix86->segs.ds; + /* Set default status in case child routine fails to do so */ params.Status = PXENV_STATUS_FAILURE; diff --git a/src/arch/i386/interface/pxe/pxe_entry.S b/src/arch/i386/interface/pxe/pxe_entry.S index 204894ef..c55e581f 100644 --- a/src/arch/i386/interface/pxe/pxe_entry.S +++ b/src/arch/i386/interface/pxe/pxe_entry.S @@ -35,7 +35,7 @@ ppxe: .byte 0 /* StructCksum */ .byte 0 /* StructRev */ .byte 0 /* reserved_1 */ - .word 0, 0 /* UNDIROMID */ + .word undiheader, 0 /* UNDIROMID */ .word 0, 0 /* BaseROMID */ .word pxe_entry_sp, 0 /* EntryPointSP */ .word pxe_entry_esp, 0 /* EntryPointESP */ @@ -55,6 +55,11 @@ pxe_segments: .equ pxe_length, . - ppxe .size ppxe, . - ppxe + /* Define undiheader=0 as a weak symbol for non-ROM builds */ + .section ".weak" + .weak undiheader +undiheader: + /**************************************************************************** * PXENV+ structure **************************************************************************** diff --git a/src/arch/i386/prefix/romprefix.S b/src/arch/i386/prefix/romprefix.S index 90ddd106..f9b9e169 100644 --- a/src/arch/i386/prefix/romprefix.S +++ b/src/arch/i386/prefix/romprefix.S @@ -112,7 +112,8 @@ prodstr_separator: prodstr_pci_id: .asciz "xx:xx.x)" /* Filled in by init code */ .size prodstr, . - prodstr - + + .globl undiheader undiheader: .ascii "UNDI" /* Signature */ .byte undiheader_len /* Length of structure */ @@ -524,18 +525,22 @@ undiloader: /* Save registers */ pushl %esi pushl %edi + pushw %ds pushw %es pushw %bx + /* ROM segment address to %ds */ + pushw %cs + popw %ds /* UNDI loader parameter structure address into %es:%di */ movw %sp, %bx - movw %ss:16(%bx), %di - movw %ss:18(%bx), %es + movw %ss:18(%bx), %di + movw %ss:20(%bx), %es /* Install to specified real-mode addresses */ pushw %di movw %es:12(%di), %bx movw %es:14(%di), %ax - movl %cs:image_source, %esi - movl %cs:decompress_to, %edi + movl image_source, %esi + movl decompress_to, %edi call install_prealloc popw %di /* Call UNDI loader C code */ @@ -550,6 +555,7 @@ undiloader: /* Restore registers and return */ popw %bx popw %es + popw %ds popl %edi popl %esi lret diff --git a/src/arch/i386/scripts/i386.lds b/src/arch/i386/scripts/i386.lds index a5a01056..7d63dae6 100644 --- a/src/arch/i386/scripts/i386.lds +++ b/src/arch/i386/scripts/i386.lds @@ -30,6 +30,16 @@ SECTIONS { * */ + /* + * Weak symbols that need zero values if not otherwise defined + */ + + . = 0; + .weak : AT ( 0 ) { + *(.weak) + } + _assert = ASSERT ( ( . == 0 ), ".weak is non-zero length" ); + /* * The prefix */