From 934229dfe30d2289c1d5e50d0e986120fbb4aab4 Mon Sep 17 00:00:00 2001 From: Bensong Liu <bensl@microsoft.com> Date: Wed, 30 Dec 2020 18:37:10 +0800 Subject: [PATCH] working on kalloc --- README.md | 2 + kernel/include/kutils.hpp | 80 +++++++++++++++++++++++++++++++++++++++ kernel/include/vga.hpp | 12 +++++- kernel/kernel.cc | 13 +++---- 4 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 kernel/include/kutils.hpp diff --git a/README.md b/README.md index 65d7674..634b0ab 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ Just used this mode to launch 64bit long mode. No paging enabled. 0x1000 - 0x5000 : 64bit long mode paging table**s** 0x00000000 - 0x00200000 : 512 * 4K pages, before the kernel initializing page table in C++. +(0x0 - 0x100000 are used by kernel structures, 0x100000-0x200000 are used by kalloc(), defined in kutils.hpp) + ## bootloader(legacy) disk model 0-511Byte : bootloader.img from boot.asm, MBR flag diff --git a/kernel/include/kutils.hpp b/kernel/include/kutils.hpp new file mode 100644 index 0000000..6807753 --- /dev/null +++ b/kernel/include/kutils.hpp @@ -0,0 +1,80 @@ +#ifndef ROS_KUTILS_HPP +#define ROS_KUTILS_HPP + +#include "stdint.hpp" +#include "stdlib.hpp" + +namespace impl { + constexpr uint64_t kalloc_begin_addr = 0x100000; + constexpr uint64_t kalloc_end_addr = 0x200000; + // Currently 1MB, must be paged. + + struct __attribute__((packed)) free_slot_head_t { + uint32_t size; + uint64_t next; // 0x0 means tail. + }; + static_assert(sizeof(free_slot_head_t) == sizeof(uint32_t) + sizeof(uint64_t)); + + using allocated_slot_head_t = uint32_t; // contains size EXCEPT the head! + + inline void kalloc_init_pool() { + struct __attribute__((packed)) _kalloc_head { + uint32_t magic = 0x12230823; + free_slot_head_t free_slot_head {kalloc_end_addr - kalloc_begin_addr - sizeof(_kalloc_head), 0x0}; + } kalloc_head; + static_assert(sizeof(kalloc_head) == sizeof(uint32_t)*2 + sizeof(uint64_t)); + + memcpy((char *)kalloc_begin_addr, (const char *)&kalloc_head, sizeof(kalloc_head)); + } +} + +inline void *kalloc(const uint32_t requested_size) { + const auto req_size_with_head = requested_size + sizeof(impl::allocated_slot_head_t); + uint64_t prev_slot_addr = 0x0; + auto curr_slot_addr = impl::kalloc_begin_addr + sizeof(impl::free_slot_head_t::size); + while(true) { + auto curr_slot = (impl::free_slot_head_t *)curr_slot_addr; + if(curr_slot->size >= req_size_with_head) { + // Do the alloc + curr_slot->size -= req_size_with_head; + if(curr_slot->size < 32) { + // Give the whole slot + if(prev_slot_addr == 0x0) { + // No previous slot. I am the first one. + // TODO + } + else { + auto prev_slot = (impl::free_slot_head_t *)prev_slot_addr; + prev_slot->next = curr_slot->next; + } + const auto actually_assigned_size = sizeof(impl::free_slot_head_t) + curr_slot->size; + *(impl::allocated_slot_head_t *)curr_slot_addr = actually_assigned_size; + return (char *)curr_slot_addr + sizeof(impl::allocated_slot_head_t); + } + else { + // Shrink the slot. + // TODO + + } + + } + else if (curr_slot->next != 0x0){ + // Failed. Next. + prev_slot_addr = curr_slot_addr; + curr_slot_addr = curr_slot->next; + } + else { + // No memory + return 0x0; + } + + } + +} + +inline void kfree(void *memory) { + +} + +#endif + diff --git a/kernel/include/vga.hpp b/kernel/include/vga.hpp index 6eab679..ffb9f25 100644 --- a/kernel/include/vga.hpp +++ b/kernel/include/vga.hpp @@ -47,4 +47,14 @@ inline void print(const char *cstr, uint8_t color = default_color) { } } -#endif \ No newline at end of file +inline void clear_screen() { + for(auto y = 0; y < 25; ++y) { + for(auto x = 0; x < 80; ++x) { + char c = x%10 + '0'; + char color = x + y*80; + set_char(x, y, ' ', 0x0f); + } + } +} + +#endif diff --git a/kernel/kernel.cc b/kernel/kernel.cc index 576ca5a..3fe8438 100644 --- a/kernel/kernel.cc +++ b/kernel/kernel.cc @@ -2,6 +2,7 @@ #include "include/vga.hpp" #include "include/bus_io.hpp" +#include "include/kutils.hpp" void test_dummy_function() { auto tmp = read_byte_from_bus(0x3f2); @@ -9,14 +10,12 @@ void test_dummy_function() { write_byte_to_bus(0x3f2, tmp); } +void kernel_init() { + impl::kalloc_init_pool(); +} + void main() { - for(auto y = 0; y < 25; ++y) { - for(auto x = 0; x < 80; ++x) { - char c = x%10 + '0'; - char color = x + y*80; - set_char(x, y, ' ', 0x0f); - } - } + clear_screen(); print("Hello world!\n"); print("Hello world!\n", 0xb1); print("Hello world!\n", 0xae); -- GitLab