diff --git a/.gitignore b/.gitignore index c277aeb..293f8dc 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ *.map *.elf metaverse_kernel +kerndisass.txt diff --git a/src/include/libk/multiboot2/bootinfo.h b/src/include/libk/multiboot2/bootinfo.h index 92fbcc7..c20e58b 100644 --- a/src/include/libk/multiboot2/bootinfo.h +++ b/src/include/libk/multiboot2/bootinfo.h @@ -134,7 +134,7 @@ typedef struct __bootinfo_elf_symbols_t * will increment this field. Future version are guranteed to be backward compatible with * older format. Each entry has the following structure: bootinfo_memory_map_entry. * - * ‘size’ contains the size of current entry including this field itself. It may be bigger + * 'size' contains the size of current entry including this field itself. It may be bigger * than 24 bytes in future versions but is guaranteed to be ‘base_addr’ is the starting * physical address. * ‘length’ is the size of the memory region in bytes. @@ -158,7 +158,7 @@ typedef struct __bootinfo_memory_map_t u32 size; u32 entry_size; u32 entry_version; - struct bootinfo_memory_map_entry_t + struct __bootinfo_memory_map_entry_t { u64 base_addr; u64 length; @@ -167,7 +167,9 @@ typedef struct __bootinfo_memory_map_t } DISALIGNED entries[0]; } DISALIGNED bootinfo_memory_map_t; #define bootinfo_memory_map(addr) (bootinfo_memory_map_t *)((usize)(addr) - sizeof(u32)) +#define bootinfo_memory_map_end(addr) ((void *)(addr) + (addr)->size - sizeof(u32)) #define BOOTINFO_MEMORY_MAP_TYPE 6 +typedef struct __bootinfo_memory_map_entry_t bootinfo_memory_map_entry_t; /** Boot loader name * ‘string’ contains the name of a boot loader booting the kernel. The name is a normal diff --git a/src/kernel/arch/x86_64/entry.s b/src/kernel/arch/x86_64/entry.s index 1e4fd12..c259f4a 100644 --- a/src/kernel/arch/x86_64/entry.s +++ b/src/kernel/arch/x86_64/entry.s @@ -21,7 +21,7 @@ multiboot2_header: bootinfo_request_tag: dd 1 dd bootinfo_request_tag_end - bootinfo_request_tag - dd 4 ; basic mamory info + dd 6 ; memory map dd 1 ; boot command line dd 8 ; framebuffer info dd 12 ; efi64 system table pointer diff --git a/src/kernel/main.c b/src/kernel/main.c index 973df5e..50f2fbe 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -3,6 +3,7 @@ #include #include +#include // 通过bootinfo获取临时的帧缓冲区信息 void get_frame_buffer_with_bootinfo(framebuffer *fb, bootinfo_t *bootinfo); @@ -16,12 +17,20 @@ void kmain(void *mb2_bootinfo) // 获取内存信息 void **tags; usize tags_amount; - if ((tags_amount = bootinfo_get_tag(&bootinfo, BOOTINFO_BASIC_MEMORY_INFO_TYPE, &tags)) == 0) + if ((tags_amount = bootinfo_get_tag(&bootinfo, BOOTINFO_MEMORY_MAP_TYPE, &tags)) == 0) { KERNEL_TODO(); } - bootinfo_basic_memory_info_t *meminfo = bootinfo_basic_memory_info(tags[0]); - usize mem_size = 1024 * 1024 + meminfo->mem_upper * 1024; + bootinfo_memory_map_t *meminfo = bootinfo_memory_map(tags[0]); + usize mem_size = 0; + for ( + bootinfo_memory_map_entry_t *it = meminfo->entries; + (void *)it < bootinfo_memory_map_end(meminfo); + it++) + { + if (it->type == 1 || it->type == 3 || it->type == 4 || it->type == 5) + mem_size += it->length; + } // 初始化内存管理模块 mem_manager_t *memm = memm_new(mem_size); @@ -31,10 +40,11 @@ void kmain(void *mb2_bootinfo) framebuffer fb; get_frame_buffer_with_bootinfo(&fb, &bootinfo); + KERNEL_TODO(); tty *tty0 = tty_new(tty_type_raw_framebuffer, tty_mode_text); - tty_set_framebuffer(&tty0, &fb); + tty_set_framebuffer(tty0, &fb); - tty_text_print(&tty0, "Hello Metaverse!\n", gen_color(0xee, 0xee, 0xee), gen_color(0, 0, 0)); + tty_text_print(tty0, "Hello Metaverse!\n", gen_color(0xee, 0xee, 0xee), gen_color(0, 0, 0)); // 初始化内核日志模块 @@ -56,9 +66,9 @@ void get_frame_buffer_with_bootinfo(framebuffer *fb, bootinfo_t *bootinfo) fb->width = fbinfo->framebuffer_width; fb->height = fbinfo->framebuffer_height; fb->pixsize = fbinfo->framebuffer_bpp / 8; - memm_map_pageframes_to( + memm_map_pageframes_to( // TODO 总共需要映射8MB空间,但是它只映射了2MB (u64)fb->pointer, (u64)fb->pointer, fb->width * fb->height * fb->pixsize, false, true); - // TODO fb->type需要确定 + KERNEL_TODO(); } diff --git a/src/kernel/memm/allocator/raw.c b/src/kernel/memm/allocator/raw.c index 5264025..ab92cf6 100644 --- a/src/kernel/memm/allocator/raw.c +++ b/src/kernel/memm/allocator/raw.c @@ -13,45 +13,36 @@ void raw_allocator_new(raw_allocator_t *allocator, usize size) void *raw_allocator_allocate(raw_allocator_t *allocator, usize size, usize align) { - // 搜索 + usize rsize = size; + align_to(rsize, 16); raw_allocator_cell *cell = allocator->cells; - while ((void *)cell < (void *)allocator + allocator->size && - cell->length != 0 && cell->capacity >= size) + while ((void *)cell + cell->capacity + sizeof(raw_allocator_cell) < (void *)allocator + allocator->size) { - cell = (void *)cell + sizeof(raw_allocator_cell) + cell->capacity; + while ( + (void *)cell + cell->capacity + sizeof(raw_allocator_cell) < (void *)allocator + allocator->size && + cell->length != 0) + { + cell = (void *)cell + cell->capacity + sizeof(raw_allocator_cell); + } + if (rsize <= cell->capacity) + break; } - if ((void *)cell >= (void *)allocator + allocator->size) + if ((void *)cell < (void *)allocator + allocator->size) + goto fitable_cell_finded; + else return nullptr; - // 合并 - raw_allocator_cell *next_cell = (void *)cell + sizeof(raw_allocator_cell) + cell->capacity; - while ((void *)next_cell < (void *)allocator + allocator->size && - next_cell->length == 0) - { - cell->capacity += sizeof(raw_allocator_cell) + next_cell->capacity; - next_cell = (void *)next_cell + sizeof(raw_allocator_cell) + next_cell->capacity; - } - - // 分割 - usize allsize = sizeof(raw_allocator_cell) + size; - align_to(allsize, 16); - next_cell = (void *)cell + allsize; - if (allsize + sizeof(raw_allocator_cell) < sizeof(raw_allocator_cell) + cell->capacity) - { - usize nextsize = sizeof(raw_allocator_cell) + cell->capacity - allsize; - next_cell->capacity = nextsize - sizeof(raw_allocator_cell); - next_cell->length = 0; - } - else - { - allsize += 16; - } - - // 分配 - cell->capacity = allsize - sizeof(raw_allocator_cell); +fitable_cell_finded: cell->length = size; - - return &cell->content; + if (rsize < cell->capacity) + { + usize cap = cell->capacity; + cell->capacity = rsize; + raw_allocator_cell *ncell = (void *)cell + cell->capacity + sizeof(raw_allocator_cell); + ncell->capacity = cap - rsize - sizeof(raw_allocator_cell); + ncell->length = 0; + } + return cell->content; } void raw_allocator_free(raw_allocator_t *allocator, void *mem) diff --git a/src/kernel/memm/memm.c b/src/kernel/memm/memm.c index 13b3cb0..10c8986 100644 --- a/src/kernel/memm/memm.c +++ b/src/kernel/memm/memm.c @@ -12,10 +12,10 @@ mem_manager_t *memm_new(usize mem_size) memset(&memory_manager, 0, sizeof(memory_manager)); memory_manager.memory_size = mem_size; memory_manager.page_amount = mem_size / MEMM_PAGE_SIZE; + memory_manager.alloc_only_memory = MEMM_ALLOC_ONLY_MEMORY; usize kernel_initial_size = (usize)&kend; align_to(kernel_initial_size, MEMM_PAGE_SIZE); - memory_manager.alloc_only_memory = MEMM_ALLOC_ONLY_MEMORY; // 配置分配器树 allocator_t *allocator0 = memm_allocator_new( @@ -29,6 +29,7 @@ mem_manager_t *memm_new(usize mem_size) alcatr_ind->allocator = allocator0; alcatr_ind->left = nullptr; alcatr_ind->right = nullptr; + alcatr_ind->owned_allocator = allocator0; memory_manager.allocators = alcatr_ind; @@ -81,8 +82,8 @@ allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid { case MEMM_RAW_ALLOCATOR: raw_allocator_new((void *)allocator->allocator_instance, length - sizeof(allocator_t)); - allocator->allocate = &raw_allocator_allocate; - allocator->free = &raw_allocator_free; + allocator->allocate = raw_allocator_allocate; + allocator->free = raw_allocator_free; break; default: allocator->initialized = false; @@ -171,16 +172,17 @@ void *memm_allocate(usize size, usize pid, allocator_t **allocator) align_to(size, MEMM_PAGE_SIZE); size /= MEMM_PAGE_SIZE; usize allocator_start = find_fitable_pages(size); + if (allocator_start == 0) + return nullptr; // 内存中已经没有可分配的页了 for (usize i = allocator_start; i < allocator_start + size; i++) { bitmap_set(memory_manager.map_with_allocator, i); } - if (allocator_start == 0) - return nullptr; // 内存中已经没有可分配的页了 - memm_map_pageframes_to(allocator_start * MEMM_PAGE_SIZE, allocator_start * MEMM_PAGE_SIZE, - size * MEMM_PAGE_SIZE, - false, // 用户空间标志 - true // 写权限 + memm_map_pageframes_to( + allocator_start * MEMM_PAGE_SIZE, allocator_start * MEMM_PAGE_SIZE, + size * MEMM_PAGE_SIZE, + false, // 用户空间标志 + true // 写权限 ); // 在新映射的页中创建一个分配器 diff --git a/src/libk/multiboot2/bootinfo.c b/src/libk/multiboot2/bootinfo.c index 7a226ee..26e6c3b 100644 --- a/src/libk/multiboot2/bootinfo.c +++ b/src/libk/multiboot2/bootinfo.c @@ -48,7 +48,7 @@ void bootinfo_new(bootinfo_t *bootinfo, void *bootinfo_addr) { bootinfo->map_counts[res.type] = true; } - else if (res.addr && bootinfo->map_counts[res.type] < 16) + else if (res.addr != nullptr && bootinfo->map_counts[res.type] < 16) { // 同类型tag数量只能16个以内 bootinfo->map[res.type][bootinfo->map_counts[res.type]++] = res.addr; }