The posting
http://www.monkey.org/openbsd/archive2/bugs/200503/msg00001.html
is interesting, as it points out that there has already been a problem
with pxe_call.
> single-stepping back into pxeboot. Five instructions later, I hit the
> lockup point at 4012:403c. The instruction causing the problem is:
>
> addrsize opsize lgdt [ds:0x45e80]
>
> which is the line marked "Load the GDT" in the following code from
> pxe_call.S in the OpenBSD source:
>
> /*
> * real_to_prot()
> *
> * Switch the processor back into protected mode.
> */
> .globl real_to_prot
> real_to_prot:
> .code16
>
> xorw %ax, %ax
> movw %ax, %ds /* Load %ds so we can get at Gdtr */
> data32 addr32 lgdt Gdtr /* Load the GDT */
> ...
>
> Note the address [ds:0x45e80] that this resolves to in the pxeboot binary.
> In particular, note that the offset contains five hexadecimal digits.
> We're allegedly in real-mode at this point. We can't access more than 64k
> in each segment, yet this instruction is trying to access data at an
> offset of approximately 279k. The CPU doesn't like this.
Not sure whether this issue was fixed in OpenBSD yet. That code in OpenBSD3.8 is
/sys/arch/i386/stand/libsa/pxe_call.S
...
/*
* real_to_prot()
*
* Switch the processor back into protected mode.
*/
.globl real_to_prot
real_to_prot:
.code16
movw $LINKADDR >> 4, %ax /* We're linked to LINKADDR/16:0000 */
movw %ax, %ds
data32 addr32 lgdt (Gdtr - LINKADDR) /* Reload the GDT */
movl %cr0, %eax /* Enable protected mode */
orl $CR0_PE, %eax
movl %eax, %cr0
data32 ljmp $S32TEXT, $r2p32 /* Reload %cs, flush pipeline */
r2p32:
.code32
/* Reload 32-bit %ds, %ss, %es */
movl $S32DATA, %eax
mov %ax, %ds
mov %ax, %ss
mov %ax, %es
...
Ah yes, according to CVS log
http://www.openbsd.org/cgi-bin/cvsweb/src/sys/arch/i386/stand/libsa/pxe_call.S
that real/protected mode problem should be patched since v1.2.
But did current v1.3 eventually break it again?
Rolf