From ad90ecc92908bafd8200b0b73ad96c3999700fbf Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Sun, 15 Oct 2023 20:29:21 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B5=D0=B1=D0=BE=D0=BB=D1=8C=D1=88?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- configs/limine.cfg | 3 +- deploy_to_sdc.sh | 2 +- include/mem.h | 5 +- include/sys.h | 3 +- include/version.h | 2 +- kernel/mem.cpp | 181 ++++++++++++++++++++++++++++++++------ kernel/mod.cpp | 4 - modlib/system.h | 1 - modules/helloworld/main.c | 17 +--- 9 files changed, 165 insertions(+), 53 deletions(-) diff --git a/configs/limine.cfg b/configs/limine.cfg index ea0df43..2fd7f3b 100644 --- a/configs/limine.cfg +++ b/configs/limine.cfg @@ -8,7 +8,8 @@ BACKGROUND_PATH=boot:///boot.png #TERM_FONT_SIZE=8x16 :BMOSP (KASLR on) - RESOLUTION=640x480 + #RESOLUTION=640x480 + #RESOLUTION=1024x768 PROTOCOL=limine KASLR=no KERNEL_PATH=boot:///kernel.elf diff --git a/deploy_to_sdc.sh b/deploy_to_sdc.sh index 80a690f..3d2926e 100755 --- a/deploy_to_sdc.sh +++ b/deploy_to_sdc.sh @@ -1,2 +1,2 @@ #!/bin/sh -sudo dd if=mseos.hdd of=/dev/sdc \ No newline at end of file +sudo dd if=bmosp.hdd of=/dev/sdc \ No newline at end of file diff --git a/include/mem.h b/include/mem.h index 5c3edcb..f1542c8 100644 --- a/include/mem.h +++ b/include/mem.h @@ -1,5 +1,6 @@ namespace mem { void init( ); -void *alloc_block( ); -void free_block(void *block); +void *frame_alloc(uint64_t wanted_frames); +void frame_free(void *ptr, uint64_t frames); +void *frame_calloc(uint64_t frames); } // namespace mem \ No newline at end of file diff --git a/include/sys.h b/include/sys.h index a5f279b..aa4d9ef 100644 --- a/include/sys.h +++ b/include/sys.h @@ -1,5 +1,6 @@ #include +extern "C" { typedef struct { void (*fb_printf)(char *str, ...); } env_t; @@ -22,7 +23,6 @@ typedef struct { char *message; int err_code; uint64_t func_count; - module_func_t *func[]; } module_info_t; typedef struct { @@ -42,3 +42,4 @@ typedef struct { uint8_t day; uint8_t second; } time_t; +} \ No newline at end of file diff --git a/include/version.h b/include/version.h index 6763c58..a014a58 100644 --- a/include/version.h +++ b/include/version.h @@ -1,3 +1,3 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 1 -#define VERSION_BUILD 61 +#define VERSION_BUILD 98 diff --git a/kernel/mem.cpp b/kernel/mem.cpp index 377496d..c45507e 100644 --- a/kernel/mem.cpp +++ b/kernel/mem.cpp @@ -4,6 +4,7 @@ #include #define BLOCK_SIZE 4096 +#define HHDM_OFFSET (hhdm_request.response->offset) static volatile struct limine_memmap_request memmap_request = { .id = LIMINE_MEMMAP_REQUEST, @@ -16,11 +17,13 @@ static volatile struct limine_hhdm_request hhdm_request = { .response = (struct limine_hhdm_response *)0 }; -namespace mem { - -#define HHDM_OFFSET (hhdm_request.response->offset) - -struct limine_memmap_response *memmap_response; +struct mem_entry { + struct mem_entry *next; + bool free; + size_t size; + uint8_t data[0]; +}; +typedef struct mem_entry mem_entry_t; // Битовая карта для отслеживания занятых и свободных фреймов памяти uint8_t *bitmap; @@ -39,23 +42,28 @@ uint64_t highest = 0; // Количество записей в карте памяти uint64_t mmmap_count = 0; -// Массив с описаниями типов памяти -char memory_types[8][82] = { +const char memory_types[8][82] = { "Доступно", "Зарезервировано", "ACPI, можно освободить", "ACPI NVS", "Плохая память", "Загрузчик, можно освободить", "Ядро и модули", "Буфер кадра" }; -void free(void *ptr, uint64_t frames) { +struct limine_memmap_response *memmap_response; + +static mem_entry_t *first_node; + +namespace mem { + +void frame_free(void *addr, uint64_t frames) { // Проход по фреймам памяти и очистка битов в битовой карте - uint64_t frame = (uint64_t)ptr / BLOCK_SIZE; + uint64_t frame = (uint64_t)addr / BLOCK_SIZE; for (uint64_t i = frame; i < frames + frame; i++) { BIT_CLEAR(i); } - bitmap_available++; + bitmap_available += frames; } // Функция выделения памяти -void *alloc(uint64_t wanted_frames) { - void *ptr; +void *frame_alloc(uint64_t wanted_frames) { + void *addr; uint64_t available_frames = 0; for (uint64_t frame = 1; frame < limit; frame++) { @@ -70,17 +78,123 @@ void *alloc(uint64_t wanted_frames) { for (i = 0; i < wanted_frames; i++) { BIT_SET(frame - i); } frame -= i - 1; - ptr = (void *)(BLOCK_SIZE * frame); - return ptr; + addr = (void *)(BLOCK_SIZE * frame); + bitmap_available -= wanted_frames; + return addr; } } return NULL; } -void *calloc(uint64_t frames) { - void *ptr = alloc(frames); - tool::memset(ptr + HHDM_OFFSET, 0, frames * BLOCK_SIZE); - return ptr; +void *frame_calloc(uint64_t frames) { + void *addr = frame_alloc(frames); + tool::memset(addr + HHDM_OFFSET, 0, frames * BLOCK_SIZE); + return addr; +} + +void add_block(void *addr, size_t size) { + mem_entry_t *new_entry = (mem_entry_t *)addr; + + new_entry->size = size - sizeof(mem_entry_t); + new_entry->free = true; + + if (first_node == NULL) { + first_node = new_entry; + new_entry->next = NULL; + } else { + mem_entry_t *curr = first_node; + while (curr->next != NULL) { curr = curr->next; } + + curr->next = new_entry; + new_entry->next = NULL; + } +} + +void alloc_init(void *address, size_t length) { + first_node = (mem_entry_t *)address; + + first_node->size = length - sizeof(mem_entry_t); + first_node->free = true; + first_node->next = NULL; +} + +void merge_blocks(mem_entry_t *start) { + if (!start->free) return; + mem_entry_t *block = start; + while (block->next && block->next->free) { + block->size += block->next->size + sizeof(mem_entry_t); + block->next = block->next->next; + } +} + +void *alloc_align(size_t size, size_t alignment) { + mem_entry_t *curr = first_node; + + while (curr) { + if (curr->free) { + void *addr = curr->data + alignment - 1; + addr -= (uintptr_t)addr % alignment + sizeof(mem_entry_t); + mem_entry_t *second = (mem_entry_t *)addr; + if (curr->size >= (second->data - curr->data + size)) { + mem_entry_t *third = (mem_entry_t *)(second->data + size); + + third->size = curr->size - (third->data - curr->data); + third->next = curr->next; + third->free = 1; + + second->size = size; + second->next = third; + second->free = 0; + + if (curr != second) { + curr->next = second; + curr->size = (uintptr_t)second - (uintptr_t)curr->data; + curr->free = 1; + } + + return second->data; + } + } + + curr = curr->next; + } + + return NULL; +} + +void *alloc(size_t size) { + return alloc_align(size, 1); +} + +void free(void *addr) { + mem_entry_t *curr = first_node, *prev = NULL; + while (curr != NULL) { + if (curr->data == addr) { + curr->free = 1; + merge_blocks(prev ? prev : curr); + return; + } + prev = curr; + curr = curr->next; + } +} + +void *realloc(void *addr, size_t size) { + if (size == 0) { + free(addr); + return NULL; + } + + if (addr == NULL) { return alloc(size); } + + void *new_addr = alloc(size); + + if (new_addr == NULL) { return NULL; } + + tool::memcpy(new_addr, addr, size); + free(addr); + + return new_addr; } // Инициализация менеджера памяти @@ -98,9 +212,13 @@ void init( ) { // fb::printf("\t%d: 0x%x\tдлина: 0x%x\tтип: %s\n", i + 1, // mmaps[i]->base, mmaps[i]->length, memory_types[mmaps[i]->type]); - - // Пропускаем записи, не являющиеся доступными памятью - if (!mmaps[i]->type == LIMINE_MEMMAP_USABLE) { continue; } + if (mmaps[i]->type == LIMINE_MEMMAP_FRAMEBUFFER) { + fb::printf("На видеопамять BIOS/UEFI выделено: %u мегабайт + %u " + "килобайт\n", + mmaps[i]->length / 1024 / 1024, + (mmaps[i]->length / 1024) % 1024); + } + if (!(mmaps[i]->type == LIMINE_MEMMAP_USABLE)) { continue; } usable += mmaps[i]->length; uint64_t top = mmaps[i]->base + mmaps[i]->length; @@ -129,21 +247,26 @@ void init( ) { for (uint64_t t = 0; t < mmaps[i]->length; t += BLOCK_SIZE) { bitmap_limit++; } - if (!(mmaps[i]->type == LIMINE_MEMMAP_USABLE || - mmaps[i]->type == LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE)) { - continue; - } + + if (!(mmaps[i]->type == LIMINE_MEMMAP_USABLE)) { continue; } for (uint64_t t = 0; t < mmaps[i]->length; t += BLOCK_SIZE) { - free((void *)mmaps[i]->base + t, 1); + frame_free((void *)mmaps[i]->base + t, 1); } } - fb::printf("%u МБ объем доступной памяти, %u МБ объем виртуальной памяти\n", - usable / 1024 / 1024, available / 1024 / 1024); - fb::printf("%u / %u блоков доступно\n", bitmap_available, bitmap_limit); fb::printf("Размер битовой карты: %u\n", bitmap_size); + for (uint64_t i = 0; i < 256; i++) { + alloc_init(frame_alloc(100), 100 * BLOCK_SIZE); + } + fb::printf("%u мегабайт выделено в динамичную память\n", + (256 * 100 * BLOCK_SIZE) / 1024 / 1024); + fb::printf("%u МБ объем доступной памяти, %u МБ объем виртуальной памяти\n", + (bitmap_available * BLOCK_SIZE) / 1024 / 1024, + available / 1024 / 1024); + + fb::printf("%u / %u блоков доступно\n", bitmap_available, bitmap_limit); } } // namespace mem \ No newline at end of file diff --git a/kernel/mod.cpp b/kernel/mod.cpp index a0a5a9b..300b4b6 100644 --- a/kernel/mod.cpp +++ b/kernel/mod.cpp @@ -21,10 +21,6 @@ typedef struct { uint16_t e_shstrndx; } elf64_header_t; -typedef struct { - void (*fb_printf)(char *str, ...); -} env_t; - env_t main_env; void *elf_entry(void *module_bin, uint64_t size) { diff --git a/modlib/system.h b/modlib/system.h index 3a2ddf1..d5b8976 100644 --- a/modlib/system.h +++ b/modlib/system.h @@ -26,7 +26,6 @@ typedef struct { char *message; int err_code; uint64_t func_count; - module_func_t *func[]; } module_info_t; typedef struct { diff --git a/modules/helloworld/main.c b/modules/helloworld/main.c index 449ec45..37e5bc5 100644 --- a/modules/helloworld/main.c +++ b/modules/helloworld/main.c @@ -2,21 +2,12 @@ const char name[] = "Привет мир!"; const char message[] = "Привет из модуля!"; -module_info_t info; +module_info_t info = { .name = (char *)&name, + .message = (char *)&message, + .err_code = 2023, + .func_count = 1 }; env_t *env; -void hello( ) {} -module_func_t func_table[] = { "hello", hello }; - module_info_t *_start(env_t *env) { - fb_printf = env->fb_printf; - fb_printf("[hello]message=[%s]\n", message); - - info.name = (char *)&name; - info.message = (char *)&message; - info.func_count = 1; - info.func = &func_table; - info.err_code = 2023; - return &info; } \ No newline at end of file