asm("mov $_kernel_phys_end,%0" : "=ri"(ptr));
return ptr;
})();
- const os::phys_ptr<os::paging::page> info_start{info.get_phys_addr()};
- const os::phys_ptr<os::paging::page> info_end = info_start + (info->total_size - 1 + 0x1000) / 0x1000; // Number of pages taken, rounded up
+ const os::phys_ptr<os::paging::page> info_start{info.get_phys_addr() / 0x1000 * 0x1000}; // Round start down.
+ const os::phys_ptr<os::paging::page> info_end{(info.get_phys_addr() + info->total_size + 0x1000 - 1) / 0x1000 * 0x1000}; // Round end up.
+ bool info_pages_wholly_usable = false;
os::framebuffer framebuffer;
for (auto it = multiboot2::next(info); it->type != multiboot2::info::type_t::end; it = multiboot2::next(it)) {
switch (it->type) {
case multiboot2::info::type_t::framebuffer_info:
+ os::print("Framebuffer:\n");
+ os::print(multiboot2::framebuffer_addr(it));
+ os::print("->");
+ os::print(multiboot2::framebuffer_addr(it) + multiboot2::framebuffer_pitch(it) * multiboot2::framebuffer_height(it));
+ os::printc('\n');
framebuffer = os::framebuffer(
multiboot2::framebuffer_addr(it),
multiboot2::framebuffer_pitch(it),
);
break;
case multiboot2::info::type_t::memory_map:
- os::println("Memory map:");
for (std::size_t i = 0; i < multiboot2::memory_map_number_of_entries(it); i++) {
- os::print(multiboot2::memory_map_base_addr(it, i));
- os::print("->");
- os::print(multiboot2::memory_map_base_addr(it, i) + multiboot2::memory_map_length(it, i));
- os::printc(':');
- os::printc('0' + multiboot2::memory_map_type(it, i));
- os::printc('\n');
if (multiboot2::memory_map_type(it, i) == 1) {
- const os::phys_ptr<os::paging::page> s{multiboot2::memory_map_base_addr(it, i) == 0 ? 0x1000 : multiboot2::memory_map_base_addr(it, i)};
+ const os::phys_ptr<os::paging::page> s{
+ multiboot2::memory_map_base_addr(it, i) < 0x1000
+ ? 0x1000
+ : (multiboot2::memory_map_base_addr(it, i) + 0x1000 - 1) / 0x1000 * 0x1000
+ };
const os::phys_ptr<os::paging::page> e{multiboot2::memory_map_base_addr(it, i) + multiboot2::memory_map_length(it, i) / 0x1000 * 0x1000};
- if (s == nullptr) {
- }
if (s < e) {
remove_some_mem(
s, e, kernel_start, kernel_end,
}
);
}
+ bool info_usable = true;
+ remove_some_mem(info_start, info_end, s, e, [&info_usable](auto, auto) {
+ info_usable = false;
+ });
+ info_pages_wholly_usable = info_pages_wholly_usable || info_usable;
+ // info_pages_wholly_usable will only be false if no usable RAM section covers all the multiboot info struct.
+ // This allows me to make sure that I don't use any unusable RAM, in the very improbable case where the
+ // multiboot info struct is in a partially usable memory page.
}
}
break;
}
// Deallocate multiboot info structure: not usable anymore.
- page_allocator.deallocate({.ptr = info_start, .size = (info_end.get_phys_addr() - info_start.get_phys_addr()) / 0x1000});
+ if (info_pages_wholly_usable) {
+ page_allocator.deallocate({.ptr = info_start, .size = (info_end.get_phys_addr() - info_start.get_phys_addr()) / 0x1000});
+ } else if (info_start + 1 < info_end - 1) {
+ // Ignore the first and last blocks: ensures all the RAM is truly usable.
+ page_allocator.deallocate({.ptr = info_start + 1, .size = (info_end.get_phys_addr() - info_start.get_phys_addr()) / 0x1000 - 2});
+ }
- os::println("RAM:");
+ os::print("RAM:\n");
page_allocator.print_all();
for (std::size_t x = 0; x < framebuffer.get_width(); x++) {