2

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

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • 2
    This is a multiboot compliant image. The `magic/flags/checksum` are parts of the multiboot header. This has to be booted using a loader that understands multiboot and switches to 32 bit protected mode for you (such as `grub`). PS: Don't get me wrong, but if you can't even find out what `align` means by yourself, you should probably not be looking at such advanced stuff yet. – Jester Dec 09 '15 at 16:25
  • Please read [this](http://arjunsreedharan.org/post/82710718100/kernel-101-lets-write-a-kernel) post, it explians much better than any possible answer I could write. Moreover, be aware of the differences between `NASM` directives such as `global` and a x86 syntax such as `dd`. – 0x90 Dec 09 '15 at 16:37
  • Mulitboot compliant ELF objects like the one you are creating here have some rules to follow. A Mulitboot image must contain a specific header that among other things declares the capabilities of the multiboot code, uses a magic value 0x1BADB002 so a multiboot loader can confirm what it is loading is multiboot compliant. There is a requirement that the header information fall within the first 8k of the exectuable and that it is aligned to a 4 byte boundary. Failure to use `align 4` before the header will likely cause the multiboot loader to see your executable as non-mulitboot compliant – Michael Petch Dec 09 '15 at 16:38
  • The multiboot specification can be found here: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html . It documents the multiboot header structure and what each of the fields means. – Michael Petch Dec 09 '15 at 16:40
  • 1
    `dd - (0x1BADB002 + 0x00)` is actually saying add the two values 0x1BADB002 and 0x00 and then negate the result (similar to multiplying by -1) and yes `0x1BADB002 and 0x00` = 0x1BADB002 . Usually what you do is add the flags value to 0x1BADB002. In this case flags is 0x00. Depending on the functionality your boorloader needs it isn't 0x00. I think they have done it for clarity. Although this isn't the preferred way. – Michael Petch Dec 09 '15 at 16:41
  • The code appears to be 32-bit which is correct since a multiboot compliant bootloader will put the machine into protected mode set up with a default _GDT_, enabling the A20 gate and then jumping into the specified starting point of the ELF object. After the BIOS loads a boot sector it is in 16-bit real mode (or unreal mode), but a mulitboot loader puts the machine in 32-bit protected mode before calling your kernel. – Michael Petch Dec 09 '15 at 16:46
  • 1
    `dd - (0x1BADB002 + 0x00) ;checksum. m+f+c should be zero` tells you `m + f + c` should be zero. That's the sum of the two `dd` items above this one, plus this one. This one is the negation of the sum of the two above it. Thus, `m + f + c` is, indeed, zero. – lurker Dec 09 '15 at 16:46
  • 1
    @MichaelPetch sorry I was in error, not looking at it straight... – lurker Dec 09 '15 at 16:47

1 Answers1

5

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.
SynAck
  • 427
  • 5
  • 19