Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
710 views
in Technique[技术] by (71.8m points)

x86 - (NASM) (80x86) Bootloader NEEDS xor ax, ax

I am learning how to make a bootloader from osdev. I'm using NASM to assemble my code, and a x86 machine to run my bootloader. This is a little piece of code which prints a character and enter in a infinite loop:

BITS 16

xor ax, ax

mov ah, 0x0E
mov al, 0x41
int 0x10

jmp $

times 510-($-$$) db 0x00
db 0x55
db 0xAA

My question is: why doesn't the code run when I comment the 'xor ax, ax' instruction? As you can see in the code above, the ax value is changed to store the interrupt parameters, so the code should run without the xor instruction...

Extra notes:

  • I'm assembly the code under Xubuntu with this command: nasm -f bin -o main.bin main.asm

  • I'm storing the 512-bytes machine code onto a pen drive with this command: sudo dd if=main.bin of=/dev/sdb

  • My computer is able to start from a pen drive

Thank you so much.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In theory you wouldn't need a BPB when writing a MBR and not a VBR1, and the presence of the xor ax, ax instruction wouldn't influence the booting.
You should include a xor bh, bh however (more on Int 10/AH=0Eh)


Sadly this is just theory.

Specially for USB devices a BPB is implicitly assumed by some firmware, including the full FDC descriptor (with a valid OS name).
Many thanks to Michael Petch for stressing this out.

Since the introduction of UEFI implementations, particularly the parts dealing with CSM (Compatibility Support Module), i.e. legacy booting, writing a fully supported MBR has became tricky.

The firmware will sometimes try to automatically detect what boot mode to use and since all UEFI devices are also legacy devices per specification, the firmware must rely on some quirk to tell them apart.

My firmware detect a device as "legacy", even when explicitly told so, only when at least one of these is true:

  • There is a bootable, non empty, partition in the MBR partition table.
    The starting/ending address, either in CHS or LBA, are not checked at all.
  • The first instruction is a xor ax, ax (in either forms: 33 C0 or 31 C0). This is because the first thing most bootloaders do is to set the segment registers to zero through AX.

There may be other "signatures", like a jump at the first bytes, but I haven't tested them (yet).

If the firmware fails to detect the device as legacy and it is not a UEFI compliant device, it will be skipped.


You can use the xor ax, ax (in which case I suggest using of db 33h, 0c0h and a comment for documentation) or by adding a dummy partition entry, as shown below.

BITS 16
ORG 7c00h                       ;Soon or later you'll need this

 xor bh, bh
 mov ah, 0x0E
 mov al, 0x41
 int 0x10

_loop:
 hlt                            ;Be eco-friendly
jmp _loop

 ;Pad to the first PTE (Partition Table Entry), it is at 1beh
 TIMES 01beh-($-$$) db 00h

 dd 80h                         ;Bootable partition at CHS 0:0:0 (Which is illegal but not checked)
 db 01h                         ;Non empty partition (Type 1 is MS-DOS 2.0 FAT)

 ;Pad to the end of the sector minus 2
 TIMES 510-($-$$) db 00h
 dw 0aa55h                      ;Signature

1 According to the parameters of the dd command.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...