Hi, I've created a boot-sector which works just fine when loaded directly from BIOS, but doesn't work when loaded by ipxe:
0: b8 ad de mov ax,0xdead 3: a3 10 7c mov ds:0x7c10,ax
0xdead is not written to 0000:7c10. The reason is that BIOS have data segment register initialized to zero, while ipxe leaves it dirty before the jump to boot sector code.
After adding to boot sector some code to initialize DS register, my code works well:
0: b8 00 00 mov ax,0x0 3: 8e d8 mov ds,ax 5: b8 ad de mov ax,0xdead 8: a3 10 7c mov ds:0x7c10,ax
Is such behaviour intentional, or it is a bug? Who is responsible for segment registers initialization?
Thanks,
On 14/02/16 10:52, Victor Kaplansky wrote:
I've created a boot-sector which works just fine when loaded directly from BIOS, but doesn't work when loaded by ipxe:
0: b8 ad de mov ax,0xdead 3: a3 10 7c mov ds:0x7c10,ax
0xdead is not written to 0000:7c10. The reason is that BIOS have data segment register initialized to zero, while ipxe leaves it dirty before the jump to boot sector code.
After adding to boot sector some code to initialize DS register, my code works well:
0: b8 00 00 mov ax,0x0 3: 8e d8 mov ds,ax 5: b8 ad de mov ax,0xdead 8: a3 10 7c mov ds:0x7c10,ax
Is such behaviour intentional, or it is a bug? Who is responsible for segment registers initialization?
I'm not aware of any standard describing the content of %ds when jumping to a boot sector at 0000:7c00. Every boot sector that I have encountered explicitly initialises %ds (and %es, and %ss:%sp) to known values.
Your boot sector should probably do likewise.
Michael
On Sun, Feb 14, 2016 at 12:41:31PM +0000, Michael Brown wrote:
On 14/02/16 10:52, Victor Kaplansky wrote:
I've created a boot-sector which works just fine when loaded directly from BIOS, but doesn't work when loaded by ipxe:
0: b8 ad de mov ax,0xdead 3: a3 10 7c mov ds:0x7c10,ax
0xdead is not written to 0000:7c10. The reason is that BIOS have data segment register initialized to zero, while ipxe leaves it dirty before the jump to boot sector code.
After adding to boot sector some code to initialize DS register, my code works well:
0: b8 00 00 mov ax,0x0 3: 8e d8 mov ds,ax 5: b8 ad de mov ax,0xdead 8: a3 10 7c mov ds:0x7c10,ax
Is such behaviour intentional, or it is a bug? Who is responsible for segment registers initialization?
I'm not aware of any standard describing the content of %ds when jumping to a boot sector at 0000:7c00. Every boot sector that I have encountered explicitly initialises %ds (and %es, and %ss:%sp) to known values.
Sounds reasonable wrt %ds, but I think %ss:%sp at least is initialized by PXE, isn't it?
PXE spec says (4.4.5 Client State at Bootstrap Execution Time (Remote.0)):
On entry to the NBP: ! CS:IP must contain the value 0:7C00h. ! ES:BX must contain the address of the PXENV+ structure. ! SS:[SP+4] must contain the segment:offset address of the !PXE structure. ! EDX is no longer used. ! SS:SP is to contain the address of the beginning of the unused portion of the PXE services stack. ! There must be at least 1.5KB of free stack space for the NBP.
Your boot sector should probably do likewise.
Michael
On 14/02/16 15:26, Michael S. Tsirkin wrote:
I'm not aware of any standard describing the content of %ds when jumping to a boot sector at 0000:7c00. Every boot sector that I have encountered explicitly initialises %ds (and %es, and %ss:%sp) to known values.
Sounds reasonable wrt %ds, but I think %ss:%sp at least is initialized by PXE, isn't it?
PXE spec says (4.4.5 Client State at Bootstrap Execution Time (Remote.0)):
On entry to the NBP: ! CS:IP must contain the value 0:7C00h. ! ES:BX must contain the address of the PXENV+ structure. ! SS:[SP+4] must contain the segment:offset address of the !PXE structure. ! EDX is no longer used. ! SS:SP is to contain the address of the beginning of the unused portion of the PXE services stack. ! There must be at least 1.5KB of free stack space for the NBP.
That's for execution of a PXE NBP, rather than a (SAN-booted) disk boot sector.
Michael
On Sun, Feb 14, 2016 at 03:40:51PM +0000, Michael Brown wrote:
On 14/02/16 15:26, Michael S. Tsirkin wrote:
I'm not aware of any standard describing the content of %ds when jumping to a boot sector at 0000:7c00. Every boot sector that I have encountered explicitly initialises %ds (and %es, and %ss:%sp) to known values.
Sounds reasonable wrt %ds, but I think %ss:%sp at least is initialized by PXE, isn't it?
PXE spec says (4.4.5 Client State at Bootstrap Execution Time (Remote.0)):
On entry to the NBP: ! CS:IP must contain the value 0:7C00h. ! ES:BX must contain the address of the PXENV+ structure. ! SS:[SP+4] must contain the segment:offset address of the !PXE structure. ! EDX is no longer used. ! SS:SP is to contain the address of the beginning of the unused portion of the PXE services stack. ! There must be at least 1.5KB of free stack space for the NBP.
That's for execution of a PXE NBP, rather than a (SAN-booted) disk boot sector.
Michael
I actually thought the initial post was about iPXE calling NBP (starting at location 07C00h) with a non-zero DS, not about booting from disk.
Rephrasing the original question, do you think %DS should be zeroed when NBP is called then?
On 14/02/16 15:53, Michael S. Tsirkin wrote:
That's for execution of a PXE NBP, rather than a (SAN-booted) disk boot sector.
I actually thought the initial post was about iPXE calling NBP (starting at location 07C00h) with a non-zero DS, not about booting from disk.
The initial post mentioned a "boot sector which works just fine when loaded directly from BIOS, but doesn't work when loaded by iPXE". That can only be referring to a disk boot sector, not a PXE NBP. (For a start, the BIOS has no way to directly load a PXE NBP.)
Rephrasing the original question,
It's not a rephrasing; it's an entirely different question.
do you think %DS should be zeroed when NBP is called then?
Not according to the PXE spec.
As far as I can tell, the initial value of %ds is undefined for both a PXE NBP and a BIOS boot sector.
Michael
On Sun, Feb 14, 2016 at 05:36:38PM +0000, Michael Brown wrote:
On 14/02/16 15:53, Michael S. Tsirkin wrote:
That's for execution of a PXE NBP, rather than a (SAN-booted) disk boot sector.
I actually thought the initial post was about iPXE calling NBP (starting at location 07C00h) with a non-zero DS, not about booting from disk.
The initial post mentioned a "boot sector which works just fine when loaded directly from BIOS, but doesn't work when loaded by iPXE". That can only be referring to a disk boot sector, not a PXE NBP. (For a start, the BIOS has no way to directly load a PXE NBP.)
Rephrasing the original question,
It's not a rephrasing; it's an entirely different question.
True - I was just curious since there are similarities between NBP and boot sector (e.g. both are loaded at 7c00) so sometimes the same code can work as both a boot sector and an NBP.
do you think %DS should be zeroed when NBP is called then?
Not according to the PXE spec.
As far as I can tell, the initial value of %ds is undefined for both a PXE NBP and a BIOS boot sector.
Michael
Thanks,
On 14/02/16 19:52, Michael S. Tsirkin wrote:
On Sun, Feb 14, 2016 at 05:36:38PM +0000, Michael Brown wrote:
On 14/02/16 15:53, Michael S. Tsirkin wrote:
do you think %DS should be zeroed when NBP is called then?
Not according to the PXE spec.
As far as I can tell, the initial value of %ds is undefined for both a PXE NBP and a BIOS boot sector.
Thanks,
Out of interest: did this question arise as a purely academic curiosity, or is there some product in existence which creates a boot sector that relies on %ds==0?
Michael
On Mon, Feb 15, 2016 at 01:07:09AM +0000, Michael Brown wrote:
On 14/02/16 19:52, Michael S. Tsirkin wrote:
On Sun, Feb 14, 2016 at 05:36:38PM +0000, Michael Brown wrote:
On 14/02/16 15:53, Michael S. Tsirkin wrote:
do you think %DS should be zeroed when NBP is called then?
Not according to the PXE spec.
As far as I can tell, the initial value of %ds is undefined for both a PXE NBP and a BIOS boot sector.
Thanks,
Out of interest: did this question arise as a purely academic curiosity, or is there some product in existence which creates a boot sector that relies on %ds==0?
Michael
FWIW QEMU has a unit test with a boot sector that relies on %ds=0: https://git.kernel.org/cgit/virt/kvm/mst/qemu.git/tree/tests/bios-tables-tes... (search for boot_sector in this file).
It's a test, not a product though, and would be easy to change not to rely on this.
On Mon, Feb 15, 2016 at 08:43:18AM +0200, Michael S. Tsirkin wrote:
On Mon, Feb 15, 2016 at 01:07:09AM +0000, Michael Brown wrote:
On 14/02/16 19:52, Michael S. Tsirkin wrote:
On Sun, Feb 14, 2016 at 05:36:38PM +0000, Michael Brown wrote:
On 14/02/16 15:53, Michael S. Tsirkin wrote:
do you think %DS should be zeroed when NBP is called then?
Not according to the PXE spec.
As far as I can tell, the initial value of %ds is undefined for both a PXE NBP and a BIOS boot sector.
Thanks,
Out of interest: did this question arise as a purely academic curiosity, or is there some product in existence which creates a boot sector that relies on %ds==0?
Michael
FWIW QEMU has a unit test with a boot sector that relies on %ds=0: https://git.kernel.org/cgit/virt/kvm/mst/qemu.git/tree/tests/bios-tables-tes... (search for boot_sector in this file).
It's a test, not a product though, and would be easy to change not to rely on this.
FYI, I agree with Michael Brown - I know of no spec requiring %ds (nor most of the other cpu registers) to be initialized when invoking the boot sector. SeaBIOS does currently zero most registers, but this was done for general "data cleanliness" reasons. I would recommend that bootloaders not rely on any particular initial cpu state.
-Kevin