diff --git a/README.md b/README.md
index 65d767473ab9d42adc0b18df7cabd03c93ec832e..634b0abb82e54dfd964568f28400820426e532a9 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 0000000000000000000000000000000000000000..68077539661904946081b172046aa14d1fed9330
--- /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 6eab67984e5dd914bd828cdf3f2a952de6b696f5..ffb9f25fc7249da41f5f5fcf35c6fbd9a6fc161e 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 576ca5a33264f8ff16693df72a50f0b57adbea2a..3fe843826534ca35677e932b3a6c262ed281a400 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);