Wrong Multiboot Information

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
leventkaya
Posts: 7
Joined: Tue Apr 04, 2023 9:00 am

Wrong Multiboot Information

Post by leventkaya »

Hello I am trying to get multiboot information from grub for creating physical memory manager.
this is my multiboot code:

part of loader.asm:

Code: Select all

MBOOT_PAGE_ALIGN    equ 1<<0    ; Load kernel and modules on a page boundary
MBOOT_MEM_INFO      equ 1<<1    ; Provide your kernel with memory info
MBOOT_HEADER_MAGIC  equ 0x1BADB002 ; Multiboot Magic value
MBOOT_HEADER_FLAGS  equ MBOOT_PAGE_ALIGN | MBOOT_MEM_INFO
MBOOT_CHECKSUM      equ -(MBOOT_HEADER_MAGIC + MBOOT_HEADER_FLAGS)

[BITS 32]
global start
start:
    mov esp, _sys_stack
    mov ebx, mboot
    push ebx
    jmp stublet

ALIGN 4  ; Ensure proper alignment for the Multiboot header

global mboot
extern code
extern bss
extern end

mboot:
    dd  MBOOT_HEADER_MAGIC      ; GRUB will search for this value on each
                                ; 4-byte boundary in your kernel file
    dd  MBOOT_HEADER_FLAGS      ; How GRUB should load your file / settings
    dd  MBOOT_CHECKSUM          ; To ensure that the above values are correct
    
    dd  mboot                   ; Location of this descriptor
    dd  code                    ; Start of kernel '.text' (code) section.
    dd  bss                     ; End of kernel '.data' section.
    dd  end                     ; End of kernel.
    dd  start                   ; Kernel entry point (initial EIP).

extern kernel_main
stublet:
    call kernel_main
    jmp $
multiboot.h:

Code: Select all

#ifndef _MULTIBOOT_H
#define _MULTIBOOT_H

#define MULTIBOOT_FLAG_MEM 0x001
#define MULTIBOOT_FLAG_DEVICE 0x002
#define MULTIBOOT_FLAG_CMDLINE 0x004
#define MULTIBOOT_FLAG_MODS 0x008
#define MULTIBOOT_FLAG_AOUT 0x010
#define MULTIBOOT_FLAG_ELF 0x020
#define MULTIBOOT_FLAG_MMAP 0x040
#define MULTIBOOT_FLAG_CONFIG 0x080
#define MULTIBOOT_FLAG_LOADER 0x100
#define MULTIBOOT_FLAG_APM 0x200
#define MULTIBOOT_FLAG_VBE 0x400

#include <stdint.h>

typedef struct multiboot_info_t {
	uint32_t flags;
	uint32_t mem_lower;
	uint32_t mem_upper;
	uint32_t boot_device;
	uint32_t cmdline;
	uint32_t mods_count;
	uint32_t mods_addr;
	uint32_t num;
	uint32_t size;
	uint32_t addr;
	uint32_t shndx;
	uint32_t mmap_length;
	uint32_t mmap_addr;
	uint32_t drives_length;
	uint32_t drives_addr;
	uint32_t config_table;
	uint32_t boot_loader_name;
	uint32_t apm_table;
	uint32_t vbe_control_info;
	uint32_t vbe_mode_info;
	uint32_t vbe_mode;
	uint32_t vbe_interface_seg;
	uint32_t vbe_interface_off;
	uint32_t vbe_interface_len;
} __attribute__((packed)) multiboot_info_t;

#endif
kernel.c:

Code: Select all

#include "../include/kernel.h"

void kernel_main(multiboot_info_t *mbi)
{
	terminal_init();
	qemu_init_debug();
	gdt_init();
	idt_init();
	timer_init(50);
	keyboard_init();
	get_cpu_info();

	uint32_t mbi_flags = mbi->flags;
	uint32_t mbi_lower = mbi->mem_lower;
	uint32_t mbi_upper = mbi->mem_upper;

	printf("flags: 0x%x\n", mbi_flags);
	printf("lower memory: 0x%u kb\n",
	       mbi_lower); // Use %u for unsigned integers
	printf("upper memory: %u kb\n",
	       mbi_upper); // Use %u for unsigned integers

	printf("mmap_length: %u\n", mbi->mmap_length);
	printf("mmap_addr: %u\n", mbi->mmap_addr);

	// set_mode(320, 200, 8);
	// clear_screen_withcolor(0x04);
}
and this is my multiboot information:
mbi_ss.png
mbi_ss.png (8.9 KiB) Viewed 4353 times
The flag is correct but the memory details are not i guess. I dont understand which part is wrong. Thank you for any help.
nullplan
Member
Member
Posts: 1643
Joined: Wed Aug 30, 2017 8:24 am

Re: Wrong Multiboot Information

Post by nullplan »

You are mixing up multiboot info and multiboot header. Multiboot info is given by the bootloader in EBX on entry to the kernel, and you know that EBX is valid if EAX on entry happens to be 0x2BADB002. Normally you do something like this in loader.asm:

Code: Select all

start:
  mov esp, _sys_stack ; I do hope that symbol is the upper end of the stack!
  push ebx
  push eax
  call kernel_main
.spin:
  cli
  hlt
  jmp .spin
And then your kernel_main has two args: the magic and the multiboot info pointer. If the magic is not 0x2BADB002, the multiboot info is not valid.

Note that if the kernel ever uses SSE, you must ensure 16 byte stack alignment before the call instruction. But that you can do by adjusting the initial ESP downward by 8 bytes.
Carpe diem!
Post Reply