#include #include "console.h" #include "multiboot2.h" #include "panic.h" #include "util.h" static void *multiboot_find_tag(uptr multiboot_info, u32 type) { uptr next = multiboot_info + 8; while (true) { multiboot_tag *tag = (multiboot_tag*)next; if (tag->type == MULTIBOOT_TAG_TYPE_END) { return NULL; } if (tag->type == type) { return tag; } next = align(next + tag->size, MULTIBOOT_TAG_ALIGN); } } #define MAX_REGIONS 64 typedef struct { u64 base_address; u64 length; } region; extern uptr kernel_start; extern uptr kernel_end; static region regions[MAX_REGIONS] = {0}; static size_t region_count = 0; static void find_memory_regions(uptr multiboot_info) { multiboot_tag_mmap *tag = multiboot_find_tag(multiboot_info, MULTIBOOT_TAG_TYPE_MMAP); if (tag == NULL) { boot_panic("Multiboot did not provide mmap tag"); } u32 entry_count = (tag->size - 16) / tag->entry_size; u8 *entry_ptr = (u8*)tag->entries; for (u32 i = 0; i < entry_count; ++i) { multiboot_mmap_entry *entry = (multiboot_mmap_entry*)entry_ptr; if (entry->type == MULTIBOOT_MEMORY_AVAILABLE) { if (region_count >= MAX_REGIONS) { boot_panic("Too many memory regions"); } regions[region_count++] = (region){ entry->base_address, entry->length }; } entry_ptr += tag->entry_size; } } void c_start(u32 magic, uptr multiboot_info) { console_clear(); if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { boot_panic("Expected bootloader magic 0x%x, got 0x%x", MULTIBOOT_BOOTLOADER_MAGIC, magic); } find_memory_regions(multiboot_info); for (size_t i = 0; i < region_count; i++) { kprintf("Memory region %d: base=0x%X, length=0x%X\n", i, regions[i].base_address, regions[i].length); } }