#include "multiboot2.h" #include "fb.h" #include "mem.h" #include #include "klog.h" #include "mm.h" static uint32_t mbinfo[2048]; static void mbinfo_process_tag(const multiboot2_info_tag_t * tag) { switch (tag->type) { case MULTIBOOT2_INFO_BOOT_COMMAND_LINE: { multiboot2_info_boot_command_line_t * cl = (multiboot2_info_boot_command_line_t *)tag; klog_printf("Kernel boot command line: '%s'\n", cl->string); } break; case MULTIBOOT2_INFO_BOOT_LOADER_NAME: { multiboot2_info_boot_loader_name_t * bln = (multiboot2_info_boot_loader_name_t *)tag; klog_printf("Boot loader: '%s'\n", bln->string); } break; case MULTIBOOT2_INFO_MEMORY_MAP: { multiboot2_info_memory_map_t * mmap_info = (multiboot2_info_memory_map_t *)tag; size_t sz = sizeof(mmap_info->header) + sizeof(mmap_info->entry_size) + sizeof(mmap_info->entry_version); multiboot2_info_memory_map_entry_t * entry = &mmap_info->entries[0]; for (;;) { sz += mmap_info->entry_size; if (sz > mmap_info->header.size) { break; } if (entry->type == MULTIBOOT2_MEMORY_MAP_TYPE_RAM) { klog_printf("Memory region %16lx : %16lx\n", entry->base_addr, entry->length); mm_register_ram_region(entry->base_addr, entry->length); } entry = (multiboot2_info_memory_map_entry_t *)((uintptr_t)entry + mmap_info->entry_size); } } break; case MULTIBOOT2_INFO_FRAMEBUFFER_INFO: { multiboot2_info_framebuffer_info_t * fbinfo = (multiboot2_info_framebuffer_info_t *)tag; fb_init((uint32_t *)(uintptr_t)fbinfo->framebuffer_addr, fbinfo->framebuffer_width, fbinfo->framebuffer_height, fbinfo->framebuffer_pitch); } break; } } static void process_tags(const multiboot2_info_tag_t * tag, bool init) { while (tag->type != 0u) { if ((init && (tag->type == MULTIBOOT2_INFO_FRAMEBUFFER_INFO)) || (!init && (tag->type != MULTIBOOT2_INFO_FRAMEBUFFER_INFO))) { mbinfo_process_tag(tag); } tag = multiboot2_info_next_tag(tag); } } bool mbinfo_init(uint32_t mbinfo_addr) { multiboot2_info_header_t * mbinfo_header = (multiboot2_info_header_t *)mbinfo_addr; if (mbinfo_header->total_size <= sizeof(mbinfo)) { memcpy32(mbinfo, mbinfo_header, mbinfo_header->total_size / 4u); multiboot2_info_tag_t * tag = (multiboot2_info_tag_t *)(mbinfo + sizeof(multiboot2_info_header_t) / 4u); process_tags(tag, true); return true; } return false; } void mbinfo_load(void) { multiboot2_info_tag_t * tag = (multiboot2_info_tag_t *)(mbinfo + sizeof(multiboot2_info_header_t) / 4u); process_tags(tag, false); }