#include "utils.hpp"
#include "serial.hpp"
+namespace detail {
+ template <typename F> concept func_on_mem = std::invocable<F, os::phys_ptr<os::paging::page>, os::phys_ptr<os::paging::page>>;
+}
+
+void remove_some_mem(os::phys_ptr<os::paging::page> mem_start,
+ os::phys_ptr<os::paging::page> mem_end,
+ os::phys_ptr<os::paging::page> remove_start,
+ os::phys_ptr<os::paging::page> remove_end,
+ detail::func_on_mem auto callback
+ ) {
+ if (remove_start <= mem_start && mem_start < remove_end && remove_end < mem_end) {
+ // Removes start:
+ callback(remove_end, mem_end);
+ } else if (mem_start < remove_start && remove_start < mem_end && mem_end <= remove_end) {
+ // Removes end:
+ callback(mem_start, remove_start);
+ } else if (remove_start <= mem_start && mem_end <= remove_end) {
+ // Removes all:
+ } else if (mem_start < remove_start && remove_end < mem_end) {
+ // Removes middle:
+ callback(mem_start, remove_start);
+ callback(remove_end, mem_end);
+ } else {
+ // Remove nothing:
+ callback(mem_start, mem_end);
+ }
+}
+
extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_start> info) {
os::assert(magic == 0x36D76289, "Incorrect magic number: wasn't booted with multiboot2.");
asm("mov $page_list_one_past_end - 0xFFFFFFFF80000000,%0" : "=ri"(ram_ptr));
return ram_ptr;
})()};
- {
- os::phys_ptr<os::paging::page> ram_ptr = nullptr;
- asm("mov $test_ram - 0xFFFFFFFF80000000,%0" : "=ri"(ram_ptr));
- page_allocator.deallocate({.ptr = ram_ptr, .size = 256});
- }
+ const os::phys_ptr<os::paging::page> kernel_start = ([]() {
+ os::phys_ptr<os::paging::page> ptr = nullptr;
+ asm("mov $_kernel_phys_start,%0" : "=ri"(ptr));
+ return ptr;
+ })();
+ const os::phys_ptr<os::paging::page> kernel_end = ([]() {
+ os::phys_ptr<os::paging::page> ptr = nullptr;
+ 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
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:
);
break;
case multiboot2::info::type_t::memory_map:
- os::println("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> 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,
+ [&page_allocator, info_start, info_end] (auto s, auto e) {
+ remove_some_mem(
+ s, e, info_start, info_end,
+ [&page_allocator] (auto s, auto e) {
+ page_allocator.deallocate({.ptr = s, .size = (e.get_phys_addr() - s.get_phys_addr()) / 0x1000});
+ }
+ );
+ }
+ );
+ }
+ }
+ }
break;
default: 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});
+
+ os::println("RAM:");
+ page_allocator.print_all();
+
for (std::size_t x = 0; x < framebuffer.get_width(); x++) {
for (std::size_t y = 0; y < framebuffer.get_height(); y++) {
framebuffer.putpixel(x, y, {
inline const std::uint8_t* color_info(os::phys_ptr<const info> ptr) {
return reinterpret_cast<const std::uint8_t*>(&ptr->rest[24]);
}
+
+ inline std::uint32_t memory_map_entry_size(os::phys_ptr<const info> ptr) {
+ return *reinterpret_cast<const std::uint32_t*>(&ptr->rest[0]);
+ }
+ inline std::uint32_t memory_map_entry_version(os::phys_ptr<const info> ptr) {
+ return *reinterpret_cast<const std::uint32_t*>(&ptr->rest[4]);
+ }
+ inline std::size_t memory_map_number_of_entries(os::phys_ptr<const info> ptr) {
+ return (ptr->size - 16) / memory_map_entry_size(ptr);
+ }
+ inline std::uint64_t memory_map_base_addr(os::phys_ptr<const info> ptr, std::size_t index) {
+ return *reinterpret_cast<const std::uint64_t*>(&ptr->rest[8 + memory_map_entry_size(ptr) * index + 0]);
+ }
+ inline std::uint64_t memory_map_length(os::phys_ptr<const info> ptr, std::size_t index) {
+ return *reinterpret_cast<const std::uint64_t*>(&ptr->rest[8 + memory_map_entry_size(ptr) * index + 8]);
+ }
+ inline std::uint32_t memory_map_type(os::phys_ptr<const info> ptr, std::size_t index) {
+ return *reinterpret_cast<const std::uint32_t*>(&ptr->rest[8 + memory_map_entry_size(ptr) * index + 16]);
+ }
#endif // __cplusplus
#ifdef __cplusplus