[ipxe-devel] iPXE working on 486(386?) hardware, hanging on init_librm

Michael Brown mcb30 at ipxe.org
Wed Feb 2 16:20:45 UTC 2022

On 02/02/2022 15:52, Nikolai Zhubr wrote:
>> https://github.com/ipxe/ipxe/commit/bc35b24e3
>> This was a fun problem to debug!
> Oh, nice. The commit log was an entertaining reading!
> I'll try to re-test it on some 486 as time permits later.
> Now as the effect appeared to be still clearly algorythmic rather than 
> some hidden timing/caching/pipelining mystery, it probably could be 
> implemented in bochs so as emulated 486 also behaves the same way? For 
> me it'd look quite usefull.

Go for it!  It looks as though the relevant code in bochs is in 

  // CS segment in real mode always allows full access
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p        = 1;
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment  = 1;
  BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type =

To get behaviour roughly equivalent to what I observed (and what 
external articles such as http://www.rcollins.org/ddj/Aug98/Aug98.html 
suggest), you'd want to skip the setting of .cache.type (and possibly 
also .cache.p and .cache.segment) in that method, and add code in 
jmp_far16() and jmp_far32() to set .cache.type either before or after 
the call to load_seg_reg().

It should be possible to test by using the bochs magic breakpoint 
instruction ("xchgw %bx,%bx") to break into the bochs debugger 
immediately after the "Return to (flat) real mode" in iPXE's 
libprefix.S.  With the changes outlined above, you should be able to 
observe in the debugger that you have a non-writable code segment (type 
BX_CODE_EXEC_READ_ACCESSED) after the "lret", which then becomes a 
writable segment (type BX_DATA_READ_WRITE_ACCESSED) after the "ljmp".


More information about the ipxe-devel mailing list