How does this assembly bootloader code work?

2019-08-12 04:04发布

问题:

I have the following code in a file (kernel.asm):

bits 32
section .text
        ;multiboot spec
        align 4
        dd 0x1BADB002               ;magic
        dd 0x00                     ;flags
        dd - (0x1BADB002 + 0x00)    ;checksum. m+f+c should be zero

global start
extern k_main                       ;this is defined in the c file

start:
    cli                             ;block interrupts
    mov esp, stack_space            ;set stack pointer
    call k_main
    hlt                             ;halt the CPU

section .bss
resb 8192                           ;8KB for stack
stack_space:

align 4
dd 0x1BADB002               ;magic
dd 0x00                     ;flags
dd - (0x1BADB002 + 0x00)    ;checksum. m+f+c should be zero

I have tested the code, linked it with the kernel and it works fine.

What does align 4 mean? I think it has something to do with memory.

If the line dd 0x1BADB002 defines a hexadecimal address meaning 'bad boot', why is it there if the operating system loads fine?

The next line dd 0x00, I'm assuming sets all of the flags to 0?

dd - (0x1BADB002 + 0x00): seems to be doing a similar thing to the second line adding 0 to the address 0xBADB002. What does the minus mean before the brackets? Does the minus mean that something is being subtracted? If so, how can something be subtracted if there is nothing to subtract it from? Also, why is 0 being added to 0xBADB002? Isn't it the same thing as 0xBADB002? Does it make a difference if it is added or not?

I'm also confused as to why this works, because it's in 32 bit and the computer starts in 16 bit real mode. Is the computer just executing the 32 bit code and calling the kernel?

Thanks in advance

回答1:

There is a standard for loading various x86 kernels using a boot loader; called as Multiboot specification.

GRUB will only load our kernel if it complies with the Multiboot spec.

According to the spec, the kernel must contain a header (known as Multiboot header) within its first 8 KiloBytes.

Further, This Multiboot header must contain 3 fields that are 4 byte aligned namely:

a magic field: containing the magic number 0x1BADB002, to identify the header.
a flags field: We will not care about this field. We will simply set it to zero.
a checksum field: the checksum field when added to the fields ‘magic’ and ‘flags’ must give zero.