From: Minep Date: Sat, 27 Aug 2022 12:13:52 +0000 (+0100) Subject: refactor: clean up the virtual memory mappings X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/commitdiff_plain/6d75e31596b5ac2e638c8a31c6c2185ee4053b6b?ds=sidebyside refactor: clean up the virtual memory mappings chores: other code clean up --- diff --git a/docs/img/lunaix-os-mem.png b/docs/img/lunaix-os-mem.png index 75c82a4..dd64890 100644 Binary files a/docs/img/lunaix-os-mem.png and b/docs/img/lunaix-os-mem.png differ diff --git a/lunaix-os/hal/pci.c b/lunaix-os/hal/pci.c index 893a0bb..aa6acd1 100644 --- a/lunaix-os/hal/pci.c +++ b/lunaix-os/hal/pci.c @@ -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"); diff --git a/lunaix-os/includes/lunaix/common.h b/lunaix-os/includes/lunaix/common.h index 4c8c794..8873a73 100644 --- a/lunaix-os/includes/lunaix/common.h +++ b/lunaix-os/includes/lunaix/common.h @@ -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 diff --git a/lunaix-os/includes/lunaix/mm/cake.h b/lunaix-os/includes/lunaix/mm/cake.h index 6a3aa39..81321f8 100644 --- a/lunaix-os/includes/lunaix/mm/cake.h +++ b/lunaix-os/includes/lunaix/mm/cake.h @@ -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 */ diff --git a/lunaix-os/includes/lunaix/mm/page.h b/lunaix-os/includes/lunaix/mm/page.h index 8883a6b..ad73542 100644 --- a/lunaix-os/includes/lunaix/mm/page.h +++ b/lunaix-os/includes/lunaix/mm/page.h @@ -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) diff --git a/lunaix-os/includes/lunaix/sched.h b/lunaix-os/includes/lunaix/sched.h index 021b55e..c1ffddd 100644 --- a/lunaix-os/includes/lunaix/sched.h +++ b/lunaix-os/includes/lunaix/sched.h @@ -5,7 +5,7 @@ struct scheduler { - struct proc_info* _procs; + struct proc_info** _procs; int procs_index; unsigned int ptable_len; }; diff --git a/lunaix-os/kernel/asm/x86/pfault.c b/lunaix-os/kernel/asm/x86/pfault.c index 6df3182..fcd52cc 100644 --- a/lunaix-os/kernel/asm/x86/pfault.c +++ b/lunaix-os/kernel/asm/x86/pfault.c @@ -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: diff --git a/lunaix-os/kernel/k_init.c b/lunaix-os/kernel/k_init.c index b7c5668..a82df94 100644 --- a/lunaix-os/kernel/k_init.c +++ b/lunaix-os/kernel/k_init.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/lunaix-os/kernel/mm/cake.c b/lunaix-os/kernel/mm/cake.c index 5aa9bef..5e03d34 100644 --- a/lunaix-os/kernel/mm/cake.c +++ b/lunaix-os/kernel/mm/cake.c @@ -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 diff --git a/lunaix-os/kernel/mm/dmm.c b/lunaix-os/kernel/mm/dmm.c index 651c6fc..edc28ef 100644 --- a/lunaix-os/kernel/mm/dmm.c +++ b/lunaix-os/kernel/mm/dmm.c @@ -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 diff --git a/lunaix-os/kernel/mm/kalloc.c b/lunaix-os/kernel/mm/kalloc.c index 6b5b878..aec1001 100644 --- a/lunaix-os/kernel/mm/kalloc.c +++ b/lunaix-os/kernel/mm/kalloc.c @@ -1,3 +1,6 @@ + +/**** DO NOT USE ****/ + /** * @file kalloc.c * @author Lunaixsky @@ -11,269 +14,271 @@ * @copyright Copyright (c) 2022 * */ -#include -#include -#include - -#include -#include - -#include +// #include +// #include +// #include -#include +// #include +// #include -extern uint8_t __kernel_heap_start; +// #include -void* -lx_malloc_internal(heap_context_t* heap, size_t size); - -void -place_chunk(uint8_t* ptr, size_t size); +// #include -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 diff --git a/lunaix-os/kernel/mm/mmio.c b/lunaix-os/kernel/mm/mmio.c index 5e0d01e..a52dc1b 100644 --- a/lunaix-os/kernel/mm/mmio.c +++ b/lunaix-os/kernel/mm/mmio.c @@ -1,11 +1,19 @@ #include #include #include +#include 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* diff --git a/lunaix-os/kernel/mm/region.c b/lunaix-os/kernel/mm/region.c index 920c35b..bd3b26e 100644 --- a/lunaix-os/kernel/mm/region.c +++ b/lunaix-os/kernel/mm/region.c @@ -21,7 +21,7 @@ region_release_all(struct mm_region* regions) llist_for_each(pos, n, ®ions->head, head) { - lxfree(pos); + vfree(pos); } } diff --git a/lunaix-os/kernel/process.c b/lunaix-os/kernel/process.c index 086a5e3..e30e461 100644 --- a/lunaix-os/kernel/process.c +++ b/lunaix-os/kernel/process.c @@ -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); } diff --git a/lunaix-os/kernel/sched.c b/lunaix-os/kernel/sched.c index 2274238..9061e80 100644 --- a/lunaix-os/kernel/sched.c +++ b/lunaix-os/kernel/sched.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -16,7 +17,8 @@ #include #include -#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中的一种 diff --git a/lunaix-os/kernel/tty/tty.c b/lunaix-os/kernel/tty/tty.c index f197559..b8631b6 100644 --- a/lunaix-os/kernel/tty/tty.c +++ b/lunaix-os/kernel/tty/tty.c @@ -6,7 +6,7 @@ #include #include -vga_attribute* tty_vga_buffer = (vga_attribute*)VGA_BUFFER_PADDR; +vga_attribute* tty_vga_buffer; vga_attribute tty_theme_color = VGA_COLOR_BLACK;