How to produce a minimal BIOS hello world boot sector with GCC that works from a USB stick on real hardware?

后端 未结 1 1290
终归单人心
终归单人心 2020-12-01 18:29

I have managed to produce a minimal boot sector that works with QEMU 2.0.0 Ubuntu 14.04:

.code16
.global _start
_start:
    cli
    mov $msg, %si
    mov $0x         


        
相关标签:
1条回答
  • 2020-12-01 19:10

    As mentioned by @Jester, I had to zero DS with:

    @@ -4,2 +4,4 @@ _start:
         cli
    +    xor %ax, %ax
    +    mov %ax, %ds
         mov $msg, %si
    

    Note that it is not possible to mov immediates to ds: we must pass through ax: 8086- why can't we move an immediate data into segment register?

    So the root of the problem was difference between QEMU's initial state and that of the real hardware.

    I am now adding the following 16-bit initialization code to all my bootloaders to guarantee a cleaner initial state. Not all of those are mandatory as mentioned by Michael Petch on the comments.

     .code16
    cli
    /* This sets %cs to 0. TODO Is that really needed? */
    ljmp $0, $1f
    1:
    xor %ax, %ax
    /* We must zero %ds for any data access. */
    mov %ax, %ds
    /* The other segments are not mandatory. TODO source */
    mov %ax, %es
    mov %ax, %fs
    mov %ax, %gs
    /*
    TODO What to move into BP and SP? https://stackoverflow.com/questions/10598802/which-value-should-be-used-for-sp-for-booting-process
    Setting BP does not seem mandatory for BIOS.
    */
    mov %ax, %bp
    /* Automatically disables interrupts until the end of the next instruction. */
    mov %ax, %ss
    /* We should set SP because BIOS calls may depend on that. TODO confirm. */
    mov %bp, %sp
    

    I have also found this closely related question: C Kernel - Works fine on VM but not actual computer?

    The Intel Manual Volume 3 System Programming Guide - 325384-056US September 2015 9.10.2 "STARTUP.ASM Listing " contains a large initialization example.

    0 讨论(0)
提交回复
热议问题