diff --git a/kernel/src/init/init.cpp b/kernel/src/init/init.cpp index 02d08d6..c92347b 100644 --- a/kernel/src/init/init.cpp +++ b/kernel/src/init/init.cpp @@ -34,6 +34,33 @@ static void step(const char* name, T&& fn) { print("\n"); } +template +static void for_each_boot_reserved_range(Fn&& fn) { + fn(paddr_t{0}, page_size); + + const multiboot::info* mb = multiboot::get_multiboot_info(); + uint64_t info_phys = reinterpret_cast(mb) - high_base; + fn(paddr_t{info_phys}, mb->total_size); + + multiboot::visit_all(mb, [&](const multiboot::tag_module* module) { + fn(paddr_t{module->mod_start}, module->mod_end - module->mod_start); + }); +} + +static bool is_in_boot_reserved_range(paddr_t ptr, size_t size) { + bool res = false; + for_each_boot_reserved_range([&](paddr_t start, size_t length) { + if(length == 0) { + return; + } + if(ptr.address < start.address + length && + start.address < ptr.address + size) { + res = true; + } + }); + return res; +} + optional findInitialMemoryPages(const multiboot::tag_mmap* multiboot_info, size_t count) { const auto* base = reinterpret_cast(multiboot_info->entries); const auto* end = reinterpret_cast(multiboot_info) + multiboot_info->size; @@ -49,7 +76,8 @@ optional findInitialMemoryPages(const multiboot::tag_mmap* multiboot_in continue; } for(auto ptr = start_ptr; ptr < (end_ptr - page_size * (count - 1)); ptr += page_size) { - if(!is_in_reserved_section(paddr_t{ptr}, page_size)) { + if(!is_in_reserved_section(paddr_t{ptr}, page_size) && + !is_in_boot_reserved_range(paddr_t{ptr}, page_size)) { return paddr_t{ptr}; } } @@ -98,6 +126,17 @@ void PhysicalAllocator::init(const multiboot::tag_mmap* multiboot_info) { }); }); + step("boot_reserved", [&]() { + for_each_boot_reserved_range([&](paddr_t start, size_t length){ + if(length == 0) { + return; + } + auto start_ptr = start.address & ~(page_size - 1); + auto end_ptr = (start.address + length + page_size - 1) & ~(page_size - 1); + alloc.force({paddr_t{start_ptr}, (end_ptr - start_ptr) / page_size}, false); + }); + }); + alloc.force({page, 1}, false); PhysicalAllocator::getInstance() = alloc;