Problem parsing Multiboot2 struct
Posted: Sat Jun 04, 2022 2:42 am
Following the wiki and tutorials I've successfully managed to boot my kernel and print using BIOS in long mode, however now I want to use a GOP framebuffer. I'm stuck trying to draw anything.
This is how my multiboot_header looks like:
This works, as the QEMU window resizes to 640x480.
Since I'm using long mode, I pass rbx to rdi before calling the kernel function:
And this is how I try to parse the struct, adapting a minimal version from the Multiboot2 specification example (I also dropped in multiboot2.h) and using a method from the wiki to draw a pixel:
The pixel isn't drawn and QEMU restarts after a while. Please help
EDIT: After going back to BIOS output and trying to just parse the multiboot header, the problem seems to occur when updating the tag value in the for loop. It enters the loop once and then triple faults.
This is how my multiboot_header looks like:
Code: Select all
section .multiboot_header
align 8
header_start:
dd 0xe85250d6 ; magic
dd 0
dd header_end - header_start
dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start)) ; checksum
; framebuffer
dw 5
dw 0
dd 20
dd 640
dd 480
dd 32
dw 0 ; end tag
dw 0 ; flags
dd 8 ; required
header_end:
Since I'm using long mode, I pass rbx to rdi before calling the kernel function:
Code: Select all
global long_mode_start
section .text
bits 64
long_mode_start:
mov ax, 0
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov rdi, rbx
extern kernel_main
call kernel_main
hlt
Code: Select all
#include <stdint.h>
#include "multiboot2.h"
extern "C" void kernel_main(unsigned long mbi_addr) {
auto addr = mbi_addr;
for (auto tag = (struct multiboot_tag *) ((uint8_t *) addr + 8);
tag->type != MULTIBOOT_TAG_TYPE_END;
tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag + ((tag->size + 7) & ~7))) {
switch (tag->type) {
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: {
auto *tagfb = (struct multiboot_tag_framebuffer *) tag;
auto *fb = (multiboot_uint64_t *) (unsigned long) tagfb->common.framebuffer_addr;
*((uint32_t *) (fb + 4 * tagfb->common.framebuffer_pitch * 100 + 4 * 100)) = 0xFFFFFFFF;
break;
}
}
}
}
EDIT: After going back to BIOS output and trying to just parse the multiboot header, the problem seems to occur when updating the tag value in the for loop. It enters the loop once and then triple faults.