refactor: clean up the virtual memory mappings
authorMinep <zelong56@gmail.com>
Sat, 27 Aug 2022 12:13:52 +0000 (13:13 +0100)
committerMinep <zelong56@gmail.com>
Sat, 27 Aug 2022 12:13:52 +0000 (13:13 +0100)
chores: other code clean up

16 files changed:
docs/img/lunaix-os-mem.png
lunaix-os/hal/pci.c
lunaix-os/includes/lunaix/common.h
lunaix-os/includes/lunaix/mm/cake.h
lunaix-os/includes/lunaix/mm/page.h
lunaix-os/includes/lunaix/sched.h
lunaix-os/kernel/asm/x86/pfault.c
lunaix-os/kernel/k_init.c
lunaix-os/kernel/mm/cake.c
lunaix-os/kernel/mm/dmm.c
lunaix-os/kernel/mm/kalloc.c
lunaix-os/kernel/mm/mmio.c
lunaix-os/kernel/mm/region.c
lunaix-os/kernel/process.c
lunaix-os/kernel/sched.c
lunaix-os/kernel/tty/tty.c

index 75c82a46b874ce7ae3e3fc17546b0979c03b4f3c..dd64890099997887137c7c49e93cbed2232ec12b 100644 (file)
Binary files a/docs/img/lunaix-os-mem.png and b/docs/img/lunaix-os-mem.png differ
index 893a0bbd00920a833a997e74b319a752f19635f2..aa6acd16f036ff0adb8b2c864a0370a54ae750a9 100644 (file)
@@ -167,12 +167,12 @@ __pci_bar_read(struct twimap* map)
     }
 
     twimap_printf(
-      map, "[%d] base=%p, size=%p, ", bar_index, bar->start, bar->size);
+      map, "[%d] base=%.8p, size=%.8p, ", bar_index, bar->start, bar->size);
 
     if ((bar->type & BAR_TYPE_MMIO)) {
         twimap_printf(map, "mmio");
         if ((bar->type & BAR_TYPE_CACHABLE)) {
-            twimap_printf(map, ", cachable");
+            twimap_printf(map, ", prefetchable");
         }
     } else {
         twimap_printf(map, "io");
index 4c8c794f8a1026851d5583c232eb1cf0491b6acd..8873a73ba35b12f90959381cfa0ea5f5be69862e 100644 (file)
@@ -1,24 +1,23 @@
 #ifndef __LUNAIX_CONSTANTS_H
 #define __LUNAIX_CONSTANTS_H
 
-#define KSTACK_SIZE (64 << 10)
+#define MEM_1MB 0x100000
+#define MEM_4MB 0x400000
+
+#define KSTACK_SIZE MEM_1MB
 #define KSTACK_START ((0x3FFFFFU - KSTACK_SIZE) + 1)
 #define KSTACK_TOP 0x3FFFF0U
 
 #define KERNEL_MM_BASE 0xC0000000
-#define MEM_1MB 0x100000
-#define MEM_4MB 0x400000
 
 #define KCODE_MAX_SIZE MEM_4MB
-#define KHEAP_START (KERNEL_MM_BASE + KCODE_MAX_SIZE)
-#define KHEAP_SIZE_MB 256
+// #define KHEAP_START (KERNEL_MM_BASE + KCODE_MAX_SIZE)
+// #define KHEAP_SIZE_MB 256
 
 #define PROC_TABLE_SIZE_MB 4
-#define PROC_START (KHEAP_START + (KHEAP_SIZE_MB * MEM_1MB))
+#define PROC_START (KERNEL_MM_BASE + KCODE_MAX_SIZE)
 
-#define VGA_BUFFER_VADDR (PROC_START + (PROC_TABLE_SIZE_MB * MEM_1MB))
-#define VGA_BUFFER_PADDR 0xB8000
-#define VGA_BUFFER_SIZE 4096
+#define VGA_FRAMEBUFFER 0xB8000
 
 #define KCODE_SEG 0x08
 #define KDATA_SEG 0x10
index 6a3aa392238e38cfb358f59849dd4adc007161f6..81321f87b898c7ce1b6bd05b50f35d342dc5d8ff 100644 (file)
@@ -7,6 +7,10 @@
 
 #define PILE_CACHELINE 1
 
+struct cake_pile;
+
+typedef void (*pile_cb)(struct cake_pile*, void*);
+
 struct cake_pile
 {
     struct llist_header piles;
@@ -20,6 +24,8 @@ struct cake_pile
     unsigned int pieces_per_cake;
     unsigned int pg_per_cake;
     char pile_name[PILE_NAME_MAXLEN];
+
+    pile_cb ctor;
 };
 
 typedef unsigned int piece_index_t;
@@ -49,6 +55,9 @@ cake_new_pile(char* name,
               unsigned int pg_per_cake,
               int options);
 
+void
+cake_set_constructor(struct cake_pile* pile, pile_cb ctor);
+
 /**
  * @brief 拿一块儿蛋糕
  *
@@ -73,4 +82,9 @@ cake_init();
 void
 cake_export();
 
+/********** some handy constructor ***********/
+
+void
+cake_ctor_zeroing(struct cake_pile* pile, void* piece);
+
 #endif /* __LUNAIX_VALLOC_H */
index 8883a6b70eab665206c42d63f23678205cac1e7f..ad7354245d36a172e766665e96e4b938eb38939b 100644 (file)
@@ -99,7 +99,7 @@ extern void __pg_mount_point;
 
 /* 四个页挂载点,两个页目录挂载点: 用于临时创建&编辑页表 */
 #define PG_MOUNT_RANGE(l1_index) (701 <= l1_index && l1_index <= 703)
-#define PD_MOUNT_1 (VGA_BUFFER_VADDR + MEM_4MB)
+#define PD_MOUNT_1 (PROC_START + MEM_4MB)
 #define PG_MOUNT_BASE (PD_MOUNT_1 + MEM_4MB)
 #define PG_MOUNT_1 (PG_MOUNT_BASE)
 #define PG_MOUNT_2 (PG_MOUNT_BASE + 0x1000)
index 021b55e9e68a58830d5b08b2dd1b6fa8e4fcdd79..c1ffddd110a72f6f756555bf0621dee0a6fe405d 100644 (file)
@@ -5,7 +5,7 @@
 
 struct scheduler
 {
-    struct proc_info* _procs;
+    struct proc_info** _procs;
     int procs_index;
     unsigned int ptable_len;
 };
index 6df3182622bce973794b360cb01cb91f5e138843..fcd52cc26480058f3a83b2144e8b46ee0b2c949a 100644 (file)
@@ -108,14 +108,8 @@ int
 do_kernel(v_mapping* mapping)
 {
     uintptr_t addr = mapping->va;
-    if (addr >= KHEAP_START && addr < PROC_START) {
-        // This is kernel heap page
-        uintptr_t pa = pmm_alloc_page(KERNEL_PID, 0);
-        *mapping->pte = (*mapping->pte & 0xfff) | pa | PG_PRESENT;
-        cpu_invplg(mapping->pte);
-        cpu_invplg(addr);
-        goto done;
-    }
+
+    // TODO
 
     return 0;
 done:
index b7c5668bd68ce2cb26bd9485381f0efe85e6effd..a82df947d16a40f6164508b60fb90f1ff75c0e52 100644 (file)
@@ -5,6 +5,7 @@
 #include <lunaix/foptions.h>
 #include <lunaix/input.h>
 #include <lunaix/lxconsole.h>
+#include <lunaix/mm/mmio.h>
 #include <lunaix/mm/page.h>
 #include <lunaix/mm/pmm.h>
 #include <lunaix/mm/vmm.h>
@@ -56,9 +57,6 @@ _kernel_pre_init()
 
     setup_memory((multiboot_memory_map_t*)_k_init_mb_info->mmap_addr, map_size);
 
-    tty_init((void*)VGA_BUFFER_VADDR);
-    tty_set_theme(VGA_COLOR_WHITE, VGA_COLOR_BLACK);
-
     __kernel_ptd = cpu_rcr3();
 
     tmp = (struct proc_info){ .page_table = __kernel_ptd };
@@ -73,6 +71,9 @@ _kernel_init()
     cake_init();
     valloc_init();
 
+    tty_init(ioremap(VGA_FRAMEBUFFER, PG_SIZE));
+    tty_set_theme(VGA_COLOR_WHITE, VGA_COLOR_BLACK);
+
     vfs_init();
     fsm_init();
     input_init();
@@ -193,22 +194,7 @@ setup_memory(multiboot_memory_map_t* map, size_t map_size)
 
     // 将内核占据的页,包括前1MB,hhk_init 设为已占用
     size_t pg_count = V2P(&__kernel_end) >> PG_SIZE_BITS;
-    pmm_mark_chunk_occupied(KERNEL_PID, 0, pg_count, 0);
-
-    size_t vga_buf_pgs = VGA_BUFFER_SIZE >> PG_SIZE_BITS;
-
-    // 首先,标记VGA部分为已占用,并且锁定
-    pmm_mark_chunk_occupied(
-      KERNEL_PID, VGA_BUFFER_PADDR >> PG_SIZE_BITS, vga_buf_pgs, PP_FGLOCKED);
-
-    // 重映射VGA文本缓冲区(以后会变成显存,i.e., framebuffer)
-    for (size_t i = 0; i < vga_buf_pgs; i++) {
-        vmm_set_mapping(PD_REFERENCED,
-                        VGA_BUFFER_VADDR + (i << PG_SIZE_BITS),
-                        VGA_BUFFER_PADDR + (i << PG_SIZE_BITS),
-                        PG_PREM_URW,
-                        VMAP_NULL);
-    }
+    pmm_mark_chunk_occupied(KERNEL_PID, 0, pg_count, PP_FGLOCKED);
 
     for (uintptr_t i = &__usrtext_start; i < &__usrtext_end; i += PG_SIZE) {
         vmm_set_mapping(PD_REFERENCED, i, V2P(i), PG_PREM_UR, VMAP_NULL);
index 5aa9bef0d97a4e259c9f666431fa71c12a5065fb..5e03d347706c8943b08c9f2792aecb9d7765aad7 100644 (file)
@@ -120,6 +120,12 @@ cake_new_pile(char* name,
     return pile;
 }
 
+void
+cake_set_constructor(struct cake_pile* pile, pile_cb ctor)
+{
+    pile->ctor = ctor;
+}
+
 void*
 cake_grab(struct cake_pile* pile)
 {
@@ -147,8 +153,14 @@ cake_grab(struct cake_pile* pile)
         llist_append(&pile->partial, &pos->cakes);
     }
 
-    return (void*)((uintptr_t)pos->first_piece +
-                   found_index * pile->piece_size);
+    void* ptr =
+      (void*)((uintptr_t)pos->first_piece + found_index * pile->piece_size);
+
+    if (pile->ctor) {
+        pile->ctor(pile, ptr);
+    }
+
+    return ptr;
 }
 
 int
@@ -188,4 +200,10 @@ found:
     }
 
     return 1;
+}
+
+void
+cake_ctor_zeroing(struct cake_pile* pile, void* piece)
+{
+    memset(piece, 0, pile->piece_size);
 }
\ No newline at end of file
index 651c6fce6c8852229e256e1dc0300b0a3c841ca2..edc28efadeb77ec6f7c16b2a16a038849f9ef84d 100644 (file)
@@ -50,13 +50,11 @@ dmm_init(heap_context_t* heap)
     heap->brk = heap->start;
     mutex_init(&heap->lock);
 
-    int perm = PG_ALLOW_USER;
-    if (heap->brk >= KHEAP_START) {
-        perm = 0;
-    }
-
-    return vmm_set_mapping(
-             PD_REFERENCED, heap->brk, 0, PG_WRITE | perm, VMAP_NULL) != NULL;
+    return vmm_set_mapping(PD_REFERENCED,
+                           heap->brk,
+                           0,
+                           PG_WRITE | PG_ALLOW_USER,
+                           VMAP_NULL) != NULL;
 }
 
 int
index 6b5b878d12a5b188270af05f0fa096de78a3a79e..aec1001a6cf3bde3e7974aeb109bf4ce4bfaf62e 100644 (file)
@@ -1,3 +1,6 @@
+
+/**** DO NOT USE ****/
+
 /**
  * @file kalloc.c
  * @author Lunaixsky
  * @copyright Copyright (c) 2022
  *
  */
-#include <lunaix/mm/dmm.h>
-#include <lunaix/mm/kalloc.h>
-#include <lunaix/mm/vmm.h>
-
-#include <lunaix/common.h>
-#include <lunaix/spike.h>
-
-#include <klibc/string.h>
+// #include <lunaix/mm/dmm.h>
+// #include <lunaix/mm/kalloc.h>
+// #include <lunaix/mm/vmm.h>
 
-#include <stdint.h>
+// #include <lunaix/common.h>
+// #include <lunaix/spike.h>
 
-extern uint8_t __kernel_heap_start;
+// #include <klibc/string.h>
 
-void*
-lx_malloc_internal(heap_context_t* heap, size_t size);
-
-void
-place_chunk(uint8_t* ptr, size_t size);
+// #include <stdint.h>
 
-void
-lx_free_internal(void* ptr);
+// extern uint8_t __kernel_heap_start;
+
+// void*
+// lx_malloc_internal(heap_context_t* heap, size_t size);
+
+// void
+// place_chunk(uint8_t* ptr, size_t size);
 
-void*
-coalesce(uint8_t* chunk_ptr);
+// void
+// lx_free_internal(void* ptr);
 
-void*
-lx_grow_heap(heap_context_t* heap, size_t sz);
+// void*
+// coalesce(uint8_t* chunk_ptr);
+
+// void*
+// lx_grow_heap(heap_context_t* heap, size_t sz);
 
-/*
-    At the beginning, we allocate an empty page and put our initial marker
+// /*
+//     At the beginning, we allocate an empty page and put our initial marker
 
-    | 4/1 | 0/1 |
-    ^     ^ brk
-    start
+//     | 4/1 | 0/1 |
+//     ^     ^ brk
+//     start
 
-    Then, expand the heap further, with HEAP_INIT_SIZE (evaluated to 4096, i.e.,
-   1 pg size) This will allocate as much pages and override old epilogue marker
-   with a free region hdr and put new epilogue marker. These are handled by
-   lx_grow_heap which is internally used by alloc to expand the heap at many
-   moment when needed.
+//     Then, expand the heap further, with HEAP_INIT_SIZE (evaluated to 4096,
+//     i.e.,
+//    1 pg size) This will allocate as much pages and override old epilogue
+//    marker with a free region hdr and put new epilogue marker. These are
+//    handled by lx_grow_heap which is internally used by alloc to expand the
+//    heap at many moment when needed.
 
-    | 4/1 | 4096/0 |   .......   | 4096/0 | 0/1 |
-    ^     ^ brk_old                       ^
-    start                                 brk
+//     | 4/1 | 4096/0 |   .......   | 4096/0 | 0/1 |
+//     ^     ^ brk_old                       ^
+//     start                                 brk
 
-    Note: the brk always point to the beginning of epilogue.
-*/
+//     Note: the brk always point to the beginning of epilogue.
+// */
 
-static heap_context_t kheap;
+// static heap_context_t kheap;
 
-int
-kalloc_init()
-{
-    kheap.start = KHEAP_START;
-    kheap.brk = NULL;
-    kheap.max_addr =
-      (void*)PROC_START; // 在新的布局中,堆结束的地方即为进程表开始的地方
-
-    for (size_t i = 0; i < KHEAP_SIZE_MB >> 2; i++) {
-        vmm_set_mapping(PD_REFERENCED,
-                        (uintptr_t)kheap.start + (i << 22),
-                        0,
-                        PG_PREM_RW,
-                        VMAP_NOMAP);
-    }
-
-    if (!dmm_init(&kheap)) {
-        return 0;
-    }
-
-    SW(kheap.start, PACK(4, M_ALLOCATED));
-    SW(kheap.start + WSIZE, PACK(0, M_ALLOCATED));
-    kheap.brk += WSIZE;
-
-    return lx_grow_heap(&kheap, HEAP_INIT_SIZE) != NULL;
-}
-
-void*
-lxmalloc(size_t size)
-{
-    mutex_lock(&kheap.lock);
-    void* r = lx_malloc_internal(&kheap, size);
-    mutex_unlock(&kheap.lock);
-
-    return r;
-}
-
-void*
-lxcalloc(size_t n, size_t elem)
-{
-    size_t pd = n * elem;
-
-    // overflow detection
-    if (pd < elem || pd < n) {
-        return NULL;
-    }
-
-    void* ptr = lxmalloc(pd);
-    if (!ptr) {
-        return NULL;
-    }
-
-    return memset(ptr, 0, pd);
-}
-
-void
-lxfree(void* ptr)
-{
-    if (!ptr) {
-        return;
-    }
-    mutex_lock(&kheap.lock);
-
-    uint8_t* chunk_ptr = (uint8_t*)ptr - WSIZE;
-    uint32_t hdr = LW(chunk_ptr);
-    size_t sz = CHUNK_S(hdr);
-    uint8_t* next_hdr = chunk_ptr + sz;
-
-    // make sure the ptr we are 'bout to free makes sense
-    //   the size trick is stolen from glibc's malloc/malloc.c:4437 ;P
-
-    assert_msg(((uintptr_t)ptr < (uintptr_t)(-sz)) && !((uintptr_t)ptr & 0x3),
-               "free(): invalid pointer");
-
-    assert_msg(sz > WSIZE, "free(): invalid size");
-
-    SW(chunk_ptr, hdr & ~M_ALLOCATED);
-    SW(FPTR(chunk_ptr, sz), hdr & ~M_ALLOCATED);
-    SW(next_hdr, LW(next_hdr) | M_PREV_FREE);
-
-    coalesce(chunk_ptr);
-
-    mutex_unlock(&kheap.lock);
-}
-
-void*
-lx_malloc_internal(heap_context_t* heap, size_t size)
-{
-    // Simplest first fit approach.
-
-    if (!size) {
-        return NULL;
-    }
-
-    uint8_t* ptr = heap->start;
-    // round to largest 4B aligned value
-    //  and space for header
-    size = ROUNDUP(size + WSIZE, BOUNDARY);
-    while (ptr < (uint8_t*)heap->brk) {
-        uint32_t header = *((uint32_t*)ptr);
-        size_t chunk_size = CHUNK_S(header);
-        if (!chunk_size && CHUNK_A(header)) {
-            break;
-        }
-        if (chunk_size >= size && !CHUNK_A(header)) {
-            // found!
-            place_chunk(ptr, size);
-            return BPTR(ptr);
-        }
-        ptr += chunk_size;
-    }
-
-    // if heap is full (seems to be!), then allocate more space (if it's
-    // okay...)
-    if ((ptr = lx_grow_heap(heap, size))) {
-        place_chunk(ptr, size);
-        return BPTR(ptr);
-    }
-
-    // Well, we are officially OOM!
-    return NULL;
-}
-
-void
-place_chunk(uint8_t* ptr, size_t size)
-{
-    uint32_t header = *((uint32_t*)ptr);
-    size_t chunk_size = CHUNK_S(header);
-    *((uint32_t*)ptr) = PACK(size, CHUNK_PF(header) | M_ALLOCATED);
-    uint8_t* n_hdrptr = (uint8_t*)(ptr + size);
-    uint32_t diff = chunk_size - size;
-
-    if (!diff) {
-        // if the current free block is fully occupied
-        uint32_t n_hdr = LW(n_hdrptr);
-        // notify the next block about our avaliability
-        SW(n_hdrptr, n_hdr & ~0x2);
-    } else {
-        // if there is remaining free space left
-        uint32_t remainder_hdr = PACK(diff, M_NOT_ALLOCATED | M_PREV_ALLOCATED);
-        SW(n_hdrptr, remainder_hdr);
-        SW(FPTR(n_hdrptr, diff), remainder_hdr);
-
-        /*
-            | xxxx |      |         |
-
-                        |
-                        v
-
-            | xxxx |                |
-        */
-        coalesce(n_hdrptr);
-    }
-}
-
-void*
-coalesce(uint8_t* chunk_ptr)
-{
-    uint32_t hdr = LW(chunk_ptr);
-    uint32_t pf = CHUNK_PF(hdr);
-    uint32_t sz = CHUNK_S(hdr);
-
-    uint32_t n_hdr = LW(chunk_ptr + sz);
-
-    if (CHUNK_A(n_hdr) && pf) {
-        // case 1: prev is free
-        uint32_t prev_ftr = LW(chunk_ptr - WSIZE);
-        size_t prev_chunk_sz = CHUNK_S(prev_ftr);
-        uint32_t new_hdr = PACK(prev_chunk_sz + sz, CHUNK_PF(prev_ftr));
-        SW(chunk_ptr - prev_chunk_sz, new_hdr);
-        SW(FPTR(chunk_ptr, sz), new_hdr);
-        chunk_ptr -= prev_chunk_sz;
-    } else if (!CHUNK_A(n_hdr) && !pf) {
-        // case 2: next is free
-        size_t next_chunk_sz = CHUNK_S(n_hdr);
-        uint32_t new_hdr = PACK(next_chunk_sz + sz, pf);
-        SW(chunk_ptr, new_hdr);
-        SW(FPTR(chunk_ptr, sz + next_chunk_sz), new_hdr);
-    } else if (!CHUNK_A(n_hdr) && pf) {
-        // case 3: both free
-        uint32_t prev_ftr = LW(chunk_ptr - WSIZE);
-        size_t next_chunk_sz = CHUNK_S(n_hdr);
-        size_t prev_chunk_sz = CHUNK_S(prev_ftr);
-        uint32_t new_hdr =
-          PACK(next_chunk_sz + prev_chunk_sz + sz, CHUNK_PF(prev_ftr));
-        SW(chunk_ptr - prev_chunk_sz, new_hdr);
-        SW(FPTR(chunk_ptr, sz + next_chunk_sz), new_hdr);
-        chunk_ptr -= prev_chunk_sz;
-    }
-
-    // (fall through) case 4: prev and next are not free
-    return chunk_ptr;
-}
-
-void*
-lx_grow_heap(heap_context_t* heap, size_t sz)
-{
-    void* start;
-
-    // The "+ WSIZE" capture the overhead for epilogue marker
-    if (!(start = lxsbrk(heap, sz + WSIZE, 0))) {
-        return NULL;
-    }
-    sz = ROUNDUP(sz, BOUNDARY);
-
-    // minus the overhead for epilogue, keep the invariant.
-    heap->brk -= WSIZE;
-
-    uint32_t old_marker = *((uint32_t*)start);
-    uint32_t free_hdr = PACK(sz, CHUNK_PF(old_marker));
-    SW(start, free_hdr);
-    SW(FPTR(start, sz), free_hdr);
-    SW(NEXT_CHK(start), PACK(0, M_ALLOCATED | M_PREV_FREE));
-
-    return coalesce(start);
-}
\ No newline at end of file
+// int
+// kalloc_init()
+// {
+//     kheap.start = KHEAP_START;
+//     kheap.brk = NULL;
+//     kheap.max_addr =
+//       (void*)PROC_START; // 在新的布局中,堆结束的地方即为进程表开始的地方
+
+//     for (size_t i = 0; i < KHEAP_SIZE_MB >> 2; i++) {
+//         vmm_set_mapping(PD_REFERENCED,
+//                         (uintptr_t)kheap.start + (i << 22),
+//                         0,
+//                         PG_PREM_RW,
+//                         VMAP_NOMAP);
+//     }
+
+//     if (!dmm_init(&kheap)) {
+//         return 0;
+//     }
+
+//     SW(kheap.start, PACK(4, M_ALLOCATED));
+//     SW(kheap.start + WSIZE, PACK(0, M_ALLOCATED));
+//     kheap.brk += WSIZE;
+
+//     return lx_grow_heap(&kheap, HEAP_INIT_SIZE) != NULL;
+// }
+
+// void*
+// lxmalloc(size_t size)
+// {
+//     mutex_lock(&kheap.lock);
+//     void* r = lx_malloc_internal(&kheap, size);
+//     mutex_unlock(&kheap.lock);
+
+//     return r;
+// }
+
+// void*
+// lxcalloc(size_t n, size_t elem)
+// {
+//     size_t pd = n * elem;
+
+//     // overflow detection
+//     if (pd < elem || pd < n) {
+//         return NULL;
+//     }
+
+//     void* ptr = lxmalloc(pd);
+//     if (!ptr) {
+//         return NULL;
+//     }
+
+//     return memset(ptr, 0, pd);
+// }
+
+// void
+// lxfree(void* ptr)
+// {
+//     if (!ptr) {
+//         return;
+//     }
+//     mutex_lock(&kheap.lock);
+
+//     uint8_t* chunk_ptr = (uint8_t*)ptr - WSIZE;
+//     uint32_t hdr = LW(chunk_ptr);
+//     size_t sz = CHUNK_S(hdr);
+//     uint8_t* next_hdr = chunk_ptr + sz;
+
+//     // make sure the ptr we are 'bout to free makes sense
+//     //   the size trick is stolen from glibc's malloc/malloc.c:4437 ;P
+
+//     assert_msg(((uintptr_t)ptr < (uintptr_t)(-sz)) && !((uintptr_t)ptr &
+//     0x3),
+//                "free(): invalid pointer");
+
+//     assert_msg(sz > WSIZE, "free(): invalid size");
+
+//     SW(chunk_ptr, hdr & ~M_ALLOCATED);
+//     SW(FPTR(chunk_ptr, sz), hdr & ~M_ALLOCATED);
+//     SW(next_hdr, LW(next_hdr) | M_PREV_FREE);
+
+//     coalesce(chunk_ptr);
+
+//     mutex_unlock(&kheap.lock);
+// }
+
+// void*
+// lx_malloc_internal(heap_context_t* heap, size_t size)
+// {
+//     // Simplest first fit approach.
+
+//     if (!size) {
+//         return NULL;
+//     }
+
+//     uint8_t* ptr = heap->start;
+//     // round to largest 4B aligned value
+//     //  and space for header
+//     size = ROUNDUP(size + WSIZE, BOUNDARY);
+//     while (ptr < (uint8_t*)heap->brk) {
+//         uint32_t header = *((uint32_t*)ptr);
+//         size_t chunk_size = CHUNK_S(header);
+//         if (!chunk_size && CHUNK_A(header)) {
+//             break;
+//         }
+//         if (chunk_size >= size && !CHUNK_A(header)) {
+//             // found!
+//             place_chunk(ptr, size);
+//             return BPTR(ptr);
+//         }
+//         ptr += chunk_size;
+//     }
+
+//     // if heap is full (seems to be!), then allocate more space (if it's
+//     // okay...)
+//     if ((ptr = lx_grow_heap(heap, size))) {
+//         place_chunk(ptr, size);
+//         return BPTR(ptr);
+//     }
+
+//     // Well, we are officially OOM!
+//     return NULL;
+// }
+
+// void
+// place_chunk(uint8_t* ptr, size_t size)
+// {
+//     uint32_t header = *((uint32_t*)ptr);
+//     size_t chunk_size = CHUNK_S(header);
+//     *((uint32_t*)ptr) = PACK(size, CHUNK_PF(header) | M_ALLOCATED);
+//     uint8_t* n_hdrptr = (uint8_t*)(ptr + size);
+//     uint32_t diff = chunk_size - size;
+
+//     if (!diff) {
+//         // if the current free block is fully occupied
+//         uint32_t n_hdr = LW(n_hdrptr);
+//         // notify the next block about our avaliability
+//         SW(n_hdrptr, n_hdr & ~0x2);
+//     } else {
+//         // if there is remaining free space left
+//         uint32_t remainder_hdr = PACK(diff, M_NOT_ALLOCATED |
+//         M_PREV_ALLOCATED); SW(n_hdrptr, remainder_hdr); SW(FPTR(n_hdrptr,
+//         diff), remainder_hdr);
+
+//         /*
+//             | xxxx |      |         |
+
+//                         |
+//                         v
+
+//             | xxxx |                |
+//         */
+//         coalesce(n_hdrptr);
+//     }
+// }
+
+// void*
+// coalesce(uint8_t* chunk_ptr)
+// {
+//     uint32_t hdr = LW(chunk_ptr);
+//     uint32_t pf = CHUNK_PF(hdr);
+//     uint32_t sz = CHUNK_S(hdr);
+
+//     uint32_t n_hdr = LW(chunk_ptr + sz);
+
+//     if (CHUNK_A(n_hdr) && pf) {
+//         // case 1: prev is free
+//         uint32_t prev_ftr = LW(chunk_ptr - WSIZE);
+//         size_t prev_chunk_sz = CHUNK_S(prev_ftr);
+//         uint32_t new_hdr = PACK(prev_chunk_sz + sz, CHUNK_PF(prev_ftr));
+//         SW(chunk_ptr - prev_chunk_sz, new_hdr);
+//         SW(FPTR(chunk_ptr, sz), new_hdr);
+//         chunk_ptr -= prev_chunk_sz;
+//     } else if (!CHUNK_A(n_hdr) && !pf) {
+//         // case 2: next is free
+//         size_t next_chunk_sz = CHUNK_S(n_hdr);
+//         uint32_t new_hdr = PACK(next_chunk_sz + sz, pf);
+//         SW(chunk_ptr, new_hdr);
+//         SW(FPTR(chunk_ptr, sz + next_chunk_sz), new_hdr);
+//     } else if (!CHUNK_A(n_hdr) && pf) {
+//         // case 3: both free
+//         uint32_t prev_ftr = LW(chunk_ptr - WSIZE);
+//         size_t next_chunk_sz = CHUNK_S(n_hdr);
+//         size_t prev_chunk_sz = CHUNK_S(prev_ftr);
+//         uint32_t new_hdr =
+//           PACK(next_chunk_sz + prev_chunk_sz + sz, CHUNK_PF(prev_ftr));
+//         SW(chunk_ptr - prev_chunk_sz, new_hdr);
+//         SW(FPTR(chunk_ptr, sz + next_chunk_sz), new_hdr);
+//         chunk_ptr -= prev_chunk_sz;
+//     }
+
+//     // (fall through) case 4: prev and next are not free
+//     return chunk_ptr;
+// }
+
+// void*
+// lx_grow_heap(heap_context_t* heap, size_t sz)
+// {
+//     void* start;
+
+//     // The "+ WSIZE" capture the overhead for epilogue marker
+//     if (!(start = lxsbrk(heap, sz + WSIZE, 0))) {
+//         return NULL;
+//     }
+//     sz = ROUNDUP(sz, BOUNDARY);
+
+//     // minus the overhead for epilogue, keep the invariant.
+//     heap->brk -= WSIZE;
+
+//     uint32_t old_marker = *((uint32_t*)start);
+//     uint32_t free_hdr = PACK(sz, CHUNK_PF(old_marker));
+//     SW(start, free_hdr);
+//     SW(FPTR(start, sz), free_hdr);
+//     SW(NEXT_CHK(start), PACK(0, M_ALLOCATED | M_PREV_FREE));
+
+//     return coalesce(start);
+// }
\ No newline at end of file
index 5e0d01e28601b321c94d62914e0d26b006715655..a52dc1bf93251138ccde1670aad6058765dd5d54 100644 (file)
@@ -1,11 +1,19 @@
 #include <lunaix/mm/mmio.h>
 #include <lunaix/mm/pmm.h>
 #include <lunaix/mm/vmm.h>
+#include <lunaix/spike.h>
 
 void*
 ioremap(uintptr_t paddr, uint32_t size)
 {
-    return vmm_vmap(paddr, size, PG_PREM_RW | PG_DISABLE_CACHE);
+    void* ptr = vmm_vmap(paddr, size, PG_PREM_RW | PG_DISABLE_CACHE);
+    if (ptr) {
+        pmm_mark_chunk_occupied(KERNEL_PID,
+                                paddr >> PG_SIZE_BITS,
+                                CEIL(size, PG_SIZE_BITS),
+                                PP_FGLOCKED);
+    }
+    return ptr;
 }
 
 void*
index 920c35bbb86a3ea26cf04c247bce0b317128c5e1..bd3b26ec0d5fc1009b0e9cf424869934816d2c03 100644 (file)
@@ -21,7 +21,7 @@ region_release_all(struct mm_region* regions)
 
     llist_for_each(pos, n, &regions->head, head)
     {
-        lxfree(pos);
+        vfree(pos);
     }
 }
 
index 086a5e3105a184ca3ccf784f3f8fb7cba46445f9..e30e46120a21b4e213c4087d10f158cc7352ca99 100644 (file)
@@ -151,7 +151,7 @@ init_proc_user_space(struct proc_info* pcb)
         vmm_set_mapping(PD_MOUNT_1, i, 0, PG_ALLOW_USER | PG_WRITE, VMAP_NULL);
     }
 
-    // todo: other uspace initialization stuff
+    // TODO other uspace initialization stuff
 
     vmm_unmount_pd(PD_MOUNT_1);
 }
index 2274238061df347181a092c2008b560d2af46ddf..9061e8032c156bcdd61d7c5b30df2b73e66e4dba 100644 (file)
@@ -4,6 +4,7 @@
 #include <hal/apic.h>
 #include <hal/cpu.h>
 
+#include <lunaix/mm/cake.h>
 #include <lunaix/mm/kalloc.h>
 #include <lunaix/mm/pmm.h>
 #include <lunaix/mm/valloc.h>
@@ -16,7 +17,8 @@
 #include <lunaix/syscall.h>
 #include <lunaix/syslog.h>
 
-#define MAX_PROCESS 512
+#define PROC_TABLE_SIZE 8192
+#define MAX_PROCESS (PROC_TABLE_SIZE / sizeof(uintptr_t))
 
 volatile struct proc_info* __current;
 
@@ -24,20 +26,25 @@ struct proc_info dummy;
 
 struct scheduler sched_ctx;
 
+struct cake_pile* proc_pile;
+
 LOG_MODULE("SCHED")
 
 void
 sched_init()
 {
-    size_t pg_size = ROUNDUP(sizeof(struct proc_info) * MAX_PROCESS, 0x1000);
+    // size_t pg_size = ROUNDUP(sizeof(struct proc_info) * MAX_PROCESS, 0x1000);
 
-    for (size_t i = 0; i <= pg_size; i += 4096) {
-        uintptr_t pa = pmm_alloc_page(KERNEL_PID, PP_FGPERSIST);
-        vmm_set_mapping(
-          PD_REFERENCED, PROC_START + i, pa, PG_PREM_RW, VMAP_NULL);
-    }
+    // for (size_t i = 0; i <= pg_size; i += 4096) {
+    //     uintptr_t pa = pmm_alloc_page(KERNEL_PID, PP_FGPERSIST);
+    //     vmm_set_mapping(
+    //       PD_REFERENCED, PROC_START + i, pa, PG_PREM_RW, VMAP_NULL);
+    // }
+
+    proc_pile = cake_new_pile("proc", sizeof(struct proc_info), 1, 0);
+    cake_set_constructor(proc_pile, cake_ctor_zeroing);
 
-    sched_ctx = (struct scheduler){ ._procs = (struct proc_info*)PROC_START,
+    sched_ctx = (struct scheduler){ ._procs = vzalloc(PROC_TABLE_SIZE),
                                     .ptable_len = 0,
                                     .procs_index = 0 };
 }
@@ -80,7 +87,7 @@ can_schedule(struct proc_info* proc)
 void
 check_sleepers()
 {
-    struct proc_info* leader = &sched_ctx._procs[0];
+    struct proc_info* leader = sched_ctx._procs[0];
     struct proc_info *pos, *n;
     time_t now = clock_systime();
     llist_for_each(pos, n, &leader->sleep.sleepers, sleep.sleepers)
@@ -132,8 +139,8 @@ schedule()
 redo:
     do {
         ptr = (ptr + 1) % sched_ctx.ptable_len;
-        next = &sched_ctx._procs[ptr];
-    } while (next->state != PS_READY && ptr != prev_ptr);
+        next = sched_ctx._procs[ptr];
+    } while (!next || (next->state != PS_READY && ptr != prev_ptr));
 
     sched_ctx.procs_index = ptr;
 
@@ -162,9 +169,9 @@ __DEFINE_LXSYSCALL1(unsigned int, sleep, unsigned int, seconds)
         return (__current->sleep.wakeup_time - clock_systime()) / 1000U;
     }
 
+    struct proc_info* root_proc = sched_ctx._procs[0];
     __current->sleep.wakeup_time = clock_systime() + seconds * 1000;
-    llist_append(&sched_ctx._procs[0].sleep.sleepers,
-                 &__current->sleep.sleepers);
+    llist_append(&root_proc->sleep.sleepers, &__current->sleep.sleepers);
 
     __current->intr_ctx.registers.eax = seconds;
     __current->state = PS_BLOCKED;
@@ -178,9 +185,9 @@ __DEFINE_LXSYSCALL1(unsigned int, alarm, unsigned int, seconds)
 
     __current->sleep.alarm_time = seconds ? now + seconds * 1000 : 0;
 
+    struct proc_info* root_proc = sched_ctx._procs[0];
     if (llist_empty(&__current->sleep.sleepers)) {
-        llist_append(&sched_ctx._procs[0].sleep.sleepers,
-                     &__current->sleep.sleepers);
+        llist_append(&root_proc->sleep.sleepers, &__current->sleep.sleepers);
     }
 
     return prev_ddl ? (prev_ddl - now) / 1000 : 0;
@@ -259,8 +266,7 @@ struct proc_info*
 alloc_process()
 {
     pid_t i = 0;
-    for (; i < sched_ctx.ptable_len && sched_ctx._procs[i].state != PS_DESTROY;
-         i++)
+    for (; i < sched_ctx.ptable_len && sched_ctx._procs[i]; i++)
         ;
 
     if (i == MAX_PROCESS) {
@@ -271,8 +277,7 @@ alloc_process()
         sched_ctx.ptable_len++;
     }
 
-    struct proc_info* proc = &sched_ctx._procs[i];
-    memset(proc, 0, sizeof(*proc));
+    struct proc_info* proc = cake_grab(proc_pile);
 
     proc->state = PS_CREATED;
     proc->pid = i;
@@ -286,13 +291,15 @@ alloc_process()
     llist_init_head(&proc->sleep.sleepers);
     waitq_init(&proc->waitqueue);
 
+    sched_ctx._procs[i] = proc;
+
     return proc;
 }
 
 void
 commit_process(struct proc_info* process)
 {
-    assert(process == &sched_ctx._procs[process->pid]);
+    assert(process == sched_ctx._procs[process->pid]);
 
     if (process->state != PS_CREATED) {
         __current->k_status = EINVAL;
@@ -301,7 +308,7 @@ commit_process(struct proc_info* process)
 
     // every process is the child of first process (pid=1)
     if (!process->parent) {
-        process->parent = &sched_ctx._procs[1];
+        process->parent = sched_ctx._procs[1];
     }
 
     llist_append(&process->parent->children, &process->siblings);
@@ -321,8 +328,9 @@ destroy_process(pid_t pid)
         __current->k_status = EINVAL;
         return;
     }
-    struct proc_info* proc = &sched_ctx._procs[index];
-    proc->state = PS_DESTROY;
+    struct proc_info* proc = sched_ctx._procs[index];
+    sched_ctx._procs[index] = 0;
+
     llist_delete(&proc->siblings);
 
     for (size_t i = 0; i < VFS_MAX_FD; i++) {
@@ -345,6 +353,8 @@ destroy_process(pid_t pid)
 
     vmm_unmount_pd(PD_MOUNT_1);
 
+    cake_release(proc_pile, proc);
+
     return pid;
 }
 
@@ -364,7 +374,7 @@ get_process(pid_t pid)
     if (index < 0 || index > sched_ctx.ptable_len) {
         return NULL;
     }
-    return &sched_ctx._procs[index];
+    return sched_ctx._procs[index];
 }
 
 int
@@ -374,7 +384,7 @@ orphaned_proc(pid_t pid)
         return 0;
     if (pid >= sched_ctx.ptable_len)
         return 0;
-    struct proc_info* proc = &sched_ctx._procs[pid];
+    struct proc_info* proc = sched_ctx._procs[pid];
     struct proc_info* parent = proc->parent;
 
     // 如果其父进程的状态是terminated 或 destroy中的一种
index f197559e8b6a41607180bdea361c1e83dcfcbba1..b8631b6482c935cf313702746ac045033caa87a3 100644 (file)
@@ -6,7 +6,7 @@
 #include <lunaix/tty/tty.h>
 #include <stdint.h>
 
-vga_attribute* tty_vga_buffer = (vga_attribute*)VGA_BUFFER_PADDR;
+vga_attribute* tty_vga_buffer;
 
 vga_attribute tty_theme_color = VGA_COLOR_BLACK;