Grub multiboot2 loading multiboot header inside .bss section

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
slg
Posts: 2
Joined: Thu May 13, 2021 4:56 pm

Grub multiboot2 loading multiboot header inside .bss section

Post by slg »

Recently I've been developing a 64-bit higher half kernel and using grub as bootloader. Everything up to jumping to C code works perfectly (paging, high mem, etc). The issue comes when I start parsing the multiboot2 info struct, the mbi pointer points to an address that is inside .bss section of my binary. I don't see anything strange I in my elf sections:

Code: Select all

$ objdump -h KeaKernel          

KeaKernel:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .boot         00000340  0000000000100000  0000000000100000  00000190  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .text         00000974  ffffffff80101000  0000000000101000  000004d0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .rodata       000002a0  ffffffff80102000  0000000000102000  00000e48  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .data         00000000  ffffffff80103000  ffffffff80103000  000010e8  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .bss          00005048  ffffffff80103000  0000000000103000  00002000  2**12
                  ALLOC
(... debug sections)
Here is my linker script:

Code: Select all

#include <linker.h>

_KERNEL_PHYS = 0x100000;
_KERNEL_VMA  = KERNEL_VMA;  // 0xffffffff80000000

OUTPUT_ARCH(i386:x86-64)
OUTPUT_FORMAT(elf64-x86-64)

ENTRY(_entry)

SECTIONS {
    /* Bootstrap code, only ASM allowed */

    . = _KERNEL_PHYS;

    .boot ALIGN(64) : {
        *(.mb2)
        *(.boot.text)
        *(.boot.data)
        . = ALIGN(64);
        boot_stack_bottom = .;
        . += 128;
        boot_stack_top = .;
        *(.boot.bss)
    }

    . += _KERNEL_VMA;

    /* Add a symbol that indicates the start address of the kernel. */
    _kernel_start = .;

    .text ALIGN (4K) : AT (ADDR (.text) - _KERNEL_VMA) {
		_text_start = .;
        *(.text)
		_text_end = .;
    }

    .rodata ALIGN (4K) : AT (ADDR (.rodata) - _KERNEL_VMA) {
        _rodata_start = .;
        *(.rodata)
        *(.rodata.str1.1)
        . = ALIGN(8);
        *(.rodata.str1.8)
        _rodata_end = .;
    }

    .data ALIGN (4K) : AT (ADDR (.data) - _KERNEL_VMA) {
        *(.data)
    }

    .bss ALIGN (4K) : AT (ADDR (.bss) - _KERNEL_VMA) {
        _bss_start_ = .;
        *(COMMON)
        *(.bss)
        _bss_end_ = .;
    }

    /* Add a symbol that indicates the end address of the kernel. */
    _kernel_end = .;
}
When I use gdb to check things, I see the mbi pointer points to 0x00108000 (which I add _KERNEL_VMA to get its high mem addr). However, my .bss section starts at 0x00103000 and it's 0x5048 bytes long, which ends at 0x00108048. At this address I have some defined structs which we can check by inspecting the symbol table:

Code: Select all

$ objdump -t KeaKernel | rg -i bss 
ffffffff80103000 l     O .bss	00000000000002c8 boot_info
ffffffff80105000 l     O .bss	0000000000000001 pml4t
ffffffff80106000 l     O .bss	0000000000000001 pdpt
ffffffff80107000 l     O .bss	0000000000000001 pdt
ffffffff80108000 l     O .bss	0000000000000014 tty_info
ffffffff80108018 l     O .bss	0000000000000030 kp_info
ffffffff80103300 g     O .bss	0000000000001000 kernel_stack
ffffffff80103000 g       .bss	0000000000000000 _bss_start_
ffffffff80108048 g       .bss	0000000000000000 _bss_end_
ffffffff80108048 g       .bss	0000000000000000 _kernel_end
At this point, I don't know if the issue is on my side or if grub is wrongly parsing my elf and putting mbi inside it. Any tip or hint will be a great help.
slg
Posts: 2
Joined: Thu May 13, 2021 4:56 pm

Re: Grub multiboot2 loading multiboot header inside .bss sec

Post by slg »

slg wrote:When I use gdb to check things, I see the mbi pointer points to 0x00108000 (which I add _KERNEL_VMA to get its high mem addr).
I implemented an ASM itoa function to print the pointer in early boot, I discovered the mbi points to 0x0010a900 instead of 0x00108000. So it's my mistake at some part of the code. Sorry to make this post anticipated.
Post Reply