From f214c92430d7814967dd69559aacfb928b8d7889 Mon Sep 17 00:00:00 2001 From: Aren Elchinyan Date: Tue, 17 Sep 2024 10:05:22 +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 --- TODO.md | 2 +- include/arch.h | 4 +++- include/mod.h | 1 + include/sys.h | 6 +++++- include/version.h | 2 +- kernel/cpu/idt.c | 2 ++ kernel/cpu/task.c | 31 +++++++------------------------ kernel/mem.c | 8 ++------ kernel/mod.c | 23 ++++++++++++++++++----- kernel/start.c | 22 +++++++++++++++++++++- kernel/sys.c | 4 +++- modlib/lib/system.c | 6 +++++- modlib/system.h | 4 +++- modlib/types.h | 13 ++++++++----- modules/cpubench/main.c | 1 + modules/helloworld/main.c | 1 + modules/imfs/main.c | 1 + modules/ios/main.c | 8 +++++++- modules/pci/main.c | 1 + modules/pci/pci_data.c | 7 ++++--- modules/ps2/main.c | 1 + run.sh | 2 +- 22 files changed, 97 insertions(+), 53 deletions(-) diff --git a/TODO.md b/TODO.md index edb8608..9f5a924 100644 --- a/TODO.md +++ b/TODO.md @@ -85,4 +85,4 @@ - [ ] Настройка окружения - [ ] Сборка из исходного кода - [ ] Привет мир! -- [ ] Написание драйвера \ No newline at end of file +- [ ] Написание драйвера diff --git a/include/arch.h b/include/arch.h index a880637..436d949 100644 --- a/include/arch.h +++ b/include/arch.h @@ -14,7 +14,7 @@ #include #include -#define STACK_SIZE 16 * 1024 // 16 килобайт на стек +#define STACK_SIZE 32 * 1024 // 16 килобайт на стек typedef struct task { uint64_t rax, rbx, rcx, rdx; @@ -26,6 +26,8 @@ typedef struct task { uint64_t id; char *id_str; void *stack; + void *entry; + uint64_t status; // 0 - на удаление 1 - работает struct task *last; struct task *next; diff --git a/include/mod.h b/include/mod.h index 2bb29b7..8cfae5f 100644 --- a/include/mod.h +++ b/include/mod.h @@ -126,6 +126,7 @@ void mod_after_init( ); void mod_list_show( ); module_info_t *mod_find(char *tag); module_info_t *mod_list_get(uint64_t *count); +void mod_update_info(env_t *ret); void *elf_entry(void *module_bin); void *elf_parse(elf64_header_t *head); diff --git a/include/sys.h b/include/sys.h index 64f5eb7..0f228e0 100644 --- a/include/sys.h +++ b/include/sys.h @@ -10,6 +10,7 @@ #ifndef SYS_H #define SYS_H +#include #include typedef struct { @@ -65,8 +66,9 @@ typedef struct { void *env; // env_t } __attribute__((packed)) module_info_t; -typedef struct { +typedef struct env_t_s { uint64_t offset; + uint64_t id; void (*log_printf)(char *str, ...); // Временная функция framebuffer_t (*alloc_framebuffer)( ); void (*free_framebuffer)(framebuffer_t *frame); @@ -80,6 +82,8 @@ typedef struct { uint64_t (*new_thread)(void (*func)(void *), char *name, void *arg); void (*delete_thread)( ); time_t (*get_time)( ); + void (*set_int)(uint8_t vector, void (*handler)(void *)); + void (*mod_update_info)(struct env_t_s *ret); module_info_t *ret; } __attribute__((packed)) env_t; diff --git a/include/version.h b/include/version.h index 2877895..0ef5cf9 100644 --- a/include/version.h +++ b/include/version.h @@ -1,3 +1,3 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 -#define VERSION_BUILD 162 +#define VERSION_BUILD 202 diff --git a/kernel/cpu/idt.c b/kernel/cpu/idt.c index affa8c7..5b53eb5 100644 --- a/kernel/cpu/idt.c +++ b/kernel/cpu/idt.c @@ -82,6 +82,8 @@ static void exception_handler(struct frame state) { stk = stk->rbp; } + mod_list_show( ); + asm volatile("cli"); asm volatile("hlt"); } diff --git a/kernel/cpu/task.c b/kernel/cpu/task.c index 1003743..73d7966 100644 --- a/kernel/cpu/task.c +++ b/kernel/cpu/task.c @@ -57,6 +57,8 @@ uint64_t task_new_thread(void (*func)(void *), char *name, void *arg) { tool_memset(new_task, 0, sizeof(task_t)); new_task->stack = stack; + new_task->entry = func; + new_task->status = 1; uint64_t stack_top = STACK_SIZE; stack[--stack_top] = (uint64_t)stack; @@ -98,36 +100,16 @@ void task_del(uint64_t id) { } LOG("Удаление потока ID: %u, %s\n", current_task->id, current_task->id_str); - task_t *prev = task->last; - task_t *next = task->next; + task->status = 0; - prev->next = next; - next->last = prev; - - mem_free(task->stack); - mem_free(task); - - if (task == current_task) { - current_task = next; - if (full_init) { task_switch( ); } - } + for (;;) { task_switch( ); } } void task_del_current( ) { LOG("Удаление потока ID: %u, %s\n", current_task->id, current_task->id_str); - task_t *prev = current_task->last; - task_t *next = current_task->next; + current_task->status = 0; - prev->next = next; - next->last = prev; - - LOG("Очистка потока ID: %u, %s\n", current_task->id, current_task->id_str); - mem_free(current_task->stack); - mem_free(current_task); - - LOG("Смена ID: %u, %s\n", next->id, next->id_str); - current_task = next; - if (full_init) { task_switch( ); } + for (;;) { task_switch( ); } } void task_after_init( ) { @@ -161,6 +143,7 @@ void task_init( ) { kernel_task->rsp = rsp; kernel_task->cr3 = cr3; kernel_task->cpu_time = 100; + kernel_task->status = 1; kernel_task->cpu_time_expired = kernel_task->cpu_time; current_task = kernel_task; diff --git a/kernel/mem.c b/kernel/mem.c index 139d899..02d7b84 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -51,11 +51,9 @@ static uint64_t mmmap_count = 0; extern task_t *current_task; extern uint64_t full_init; -#ifdef DEBUG_MEM static const char memory_types[8][82] = { "Доступно", "Зарезервировано", "ACPI, можно освободить", "ACPI NVS", "Плохая память", "Загрузчик, можно освободить", "Ядро и модули", "Буфер кадра" }; -#endif static struct limine_memmap_response *memmap_response; @@ -65,15 +63,13 @@ void mem_dump_memory( ) { mem_entry_t *curr = first_node; while (curr) { -#ifdef DEBUG_MEM if (curr->next) { - LOG("->0x%x | %u мегабайт | %s | 0x%x | поток %u\n", &curr->data, (curr->size) / 1024 / 1024, + LOG("->0x%x | %u килобайт | %s | 0x%x | поток %u\n", &curr->data, (curr->size) / 1024, curr->free ? memory_types[0] : memory_types[1], curr->next, curr->task_id); } else { - LOG("->0x%x | %u мегабайт | %s | поток %u | Это последний блок\n", &curr->data, (curr->size) / 1024 / 1024, + LOG("->0x%x | %u килобайт | %s | поток %u | Это последний блок\n", &curr->data, (curr->size) / 1024, curr->free ? memory_types[0] : memory_types[1], curr->task_id); } -#endif curr = curr->next; } } diff --git a/kernel/mod.c b/kernel/mod.c index 8668e3e..67da2d1 100644 --- a/kernel/mod.c +++ b/kernel/mod.c @@ -32,14 +32,14 @@ uint64_t bootpng_size; // Вывод списка модулей в отладчик void mod_list_show( ) { for (uint64_t i = 0; i < modules_count; i++) { - LOG("Имя: %s\n", module_list[i].name); - LOG("Описание модуля: %s\n", module_list[i].message); + LOG("Имя: %s\n", module_list[i].name ? module_list[i].name : "(NULL)"); + LOG("Описание модуля: %s\n", module_list[i].message ? module_list[i].message : "(NULL)"); LOG("Тип модуля: %u\n", module_list[i].type); LOG("Код ошибки модуля: %u\n", module_list[i].err_code); if (module_list[i].data_size) { LOG("Размер данных: %u\n", module_list[i].data_size); - LOG("Адрес данных: 0x%x\n", module_list[i].data); + LOG("Адрес данных: 0x%x\n", module_list[i].data ? module_list[i].data : 0); } } } @@ -63,7 +63,9 @@ module_info_t *mod_list_get(uint64_t *count) { // Поиск модуля по тегу module_info_t *mod_find(char *tag) { for (uint64_t i = 0; i < modules_count; i++) { - if (tool_str_contains(module_list[i].name, tag)) { return &module_list[i]; } + if (module_list[i].name) { + if (tool_str_contains(module_list[i].name, tag)) { return &module_list[i]; } + } } return (module_info_t *)NULL; @@ -128,7 +130,7 @@ void mod_init( ) { main_env = (env_t *)mem_alloc(sizeof(env_t)); tool_memset(main_env, 0, sizeof(env_t)); main_env->offset = (uint64_t)module_ptr->address; - + main_env->id = modules_count; sys_install(main_env); uint64_t id = task_new_thread((void (*)(void *))module_init, module_list[i].name, main_env); @@ -144,6 +146,17 @@ void mod_init( ) { LOG("Модулей обработано: %u\n", modules_count); } +void mod_update_info(env_t *env) { + module_list[env->id].name = env->ret->name; + module_list[env->id].message = env->ret->message; + module_list[env->id].data_size = env->ret->data_size; + module_list[env->id].data = env->ret->data; + module_list[env->id].get_func = env->ret->get_func; + module_list[env->id].after_init = env->ret->after_init; + module_list[env->id].irq = env->ret->irq; + module_list[env->id].irq_handler = env->ret->irq_handler; +} + // Добавление модуля void mod_add(module_info_t module) { if (modules_count == 0) { diff --git a/kernel/start.c b/kernel/start.c index a9bf536..baaf7f3 100644 --- a/kernel/start.c +++ b/kernel/start.c @@ -47,5 +47,25 @@ void _start( ) { LOG("Готово! Для выхода из симуляции удерживайте: ESCAPE\n"); asm volatile("sti"); - for (;;) { asm volatile("hlt"); } + for (;;) { + task_t *task = current_task; + + // Поиск задачи по ID + do { + task = task->next; + if (task->status == 0) { + LOG("УДАЛЕНИЕ %u(%s)\n", task->id, task->id_str); + task_t *prev = task->last; + task_t *next = task->next; + + // Обновляем связи в двусвязном списке + prev->next = next; + next->last = prev; + + // Освобождаем память, выделенную под стек и структуру текущего потока + mem_free(task->stack); + mem_free(task); + } + } while (task->id != 0); + } } \ No newline at end of file diff --git a/kernel/sys.c b/kernel/sys.c index de928f7..ec28c67 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -60,9 +60,11 @@ env_t *sys_install(env_t *module) { module->get_info = &sys_get_info; module->get_module = &sys_get_module; module->mod_list_get = &mod_list_get; - module->new_thread = task_new_thread; + module->new_thread = &task_new_thread; module->delete_thread = &task_del_current; module->get_time = &rtc_get_time; + module->set_int = &idt_set_int; + module->mod_update_info = &mod_update_info; module->ret = NULL; return module; diff --git a/modlib/lib/system.c b/modlib/lib/system.c index 8c15e32..116e887 100644 --- a/modlib/lib/system.c +++ b/modlib/lib/system.c @@ -19,9 +19,11 @@ void (*free_framebuffer)(framebuffer_t *frame); void (*exit)(int code); int (*get_error)( ); sys_info_t *(*get_info)( ); -uint64_t (*new_thread)(void (*func)(void *), char *name); +uint64_t (*new_thread)(void (*func)(void *), char *name, void *arg); void (*delete_thread)( ); time_t (*get_time)( ); +void (*mod_update_info)(env_t *ret); +void (*set_int)(uint8_t vector, void (*func)(void *)); uint64_t offset; void init_env(env_t *loader_env) { @@ -42,6 +44,8 @@ void init_env(env_t *loader_env) { new_thread = loader_env->new_thread; delete_thread = loader_env->delete_thread; get_time = loader_env->get_time; + mod_update_info = loader_env->mod_update_info; + set_int = loader_env->set_int; } void *realloc(void *addr, size_t size) { diff --git a/modlib/system.h b/modlib/system.h index 598b9c3..08086c5 100644 --- a/modlib/system.h +++ b/modlib/system.h @@ -22,9 +22,11 @@ extern void (*free_framebuffer)(framebuffer_t *frame); extern void (*exit)(int code); extern int (*get_error)( ); extern sys_info_t *(*get_info)( ); -extern uint64_t (*new_thread)(void (*func)(void *), char *name); +extern uint64_t (*new_thread)(void (*func)(void *), char *name, void *arg); extern void (*delete_thread)( ); extern time_t (*get_time)( ); +extern void (*mod_update_info)(env_t *ret); +extern void (*set_int)(uint8_t vector, void (*func)(void *)); extern uint64_t offset; void init_env(env_t *loader_env); diff --git a/modlib/types.h b/modlib/types.h index 54a6bab..4afbfa8 100644 --- a/modlib/types.h +++ b/modlib/types.h @@ -99,14 +99,16 @@ typedef struct { void *data; int64_t err_code; uint64_t module_id; - uint8_t irq; - int_entry_t irq_handler; + uint8_t irq; // Номер прерывания + void *irq_handler; // Адрес обработчика прерываний void *(*get_func)(uint64_t id); void (*after_init)( ); + void *env; // env_t } __attribute__((packed)) module_info_t; -typedef struct { +typedef struct env_t_s { uint64_t offset; + uint64_t id; void (*log_printf)(char *str, ...); // Временная функция framebuffer_t (*alloc_framebuffer)( ); void (*free_framebuffer)(framebuffer_t *frame); @@ -117,10 +119,11 @@ typedef struct { sys_info_t *(*get_info)( ); module_info_t *(*get_module)(char *module_id); module_info_t *(*mod_list_get)(uint64_t *count); - uint64_t (*new_thread)(void (*func)(void *), char *name); + uint64_t (*new_thread)(void (*func)(void *), char *name, void *arg); void (*delete_thread)( ); time_t (*get_time)( ); + void (*set_int)(uint8_t vector, int_entry_t handler); + void (*mod_update_info)(struct env_t_s *ret); module_info_t *ret; } __attribute__((packed)) env_t; - #endif // types.h diff --git a/modules/cpubench/main.c b/modules/cpubench/main.c index 4ae91dc..a3ec17d 100644 --- a/modules/cpubench/main.c +++ b/modules/cpubench/main.c @@ -88,5 +88,6 @@ void __attribute__((section(".minit"))) init(env_t *env) { .irq_handler = 0, .get_func = 0, .after_init = 0 }); + mod_update_info(env); delete_thread( ); } \ No newline at end of file diff --git a/modules/helloworld/main.c b/modules/helloworld/main.c index aad9193..90b3362 100644 --- a/modules/helloworld/main.c +++ b/modules/helloworld/main.c @@ -77,5 +77,6 @@ void __attribute__((section(".minit"))) init(env_t *env) { .irq_handler = 0, .get_func = 0, .after_init = 0 }); + mod_update_info(env); delete_thread( ); } diff --git a/modules/imfs/main.c b/modules/imfs/main.c index bd40ab2..51857fb 100644 --- a/modules/imfs/main.c +++ b/modules/imfs/main.c @@ -166,5 +166,6 @@ void __attribute__((section(".minit"))) init(env_t *env) { .irq_handler = 0, .get_func = 0, .after_init = 0 }); + mod_update_info(env); delete_thread( ); } diff --git a/modules/ios/main.c b/modules/ios/main.c index 018d5b2..09385e8 100644 --- a/modules/ios/main.c +++ b/modules/ios/main.c @@ -5,6 +5,7 @@ static uint64_t *mod_count = NULL; static uint64_t app_count = 0; static module_info_t *app_list = NULL; static char (*getc)( ) = NULL; +env_t *env; static inline int is_digit(char c) { if (c >= '0' && c <= '9') { return 1; } @@ -44,6 +45,7 @@ void ios_main( ) { if (select == app_count + 1) { log_printf("Выход\n"); + mod_update_info(env); delete_thread( ); for (;;) { asm volatile("hlt"); } } @@ -70,6 +72,7 @@ static void main( ) { if (app_list == NULL) { log_printf("Ошибка выделения памяти для app_list!\n"); delete_thread( ); + mod_update_info(env); for (;;) { asm volatile("hlt"); } } @@ -89,6 +92,7 @@ static void main( ) { log_printf("Модулей-программ не обнаружено!\n"); free(app_list); delete_thread( ); + mod_update_info(env); } else { app_list = realloc(app_list, app_count * sizeof(module_info_t)); ios_main( ); @@ -98,7 +102,8 @@ static void main( ) { for (;;) { asm volatile("hlt"); } } -void __attribute__((section(".minit"))) init(env_t *env) { +void __attribute__((section(".minit"))) init(env_t *envm) { + env = envm; init_env(env); env->ret = &((module_info_t){ .name = (char *)"[IOS]", @@ -112,5 +117,6 @@ void __attribute__((section(".minit"))) init(env_t *env) { .irq_handler = 0, .get_func = 0, .after_init = main }); + mod_update_info(env); delete_thread( ); } diff --git a/modules/pci/main.c b/modules/pci/main.c index c9aeeef..5fb5273 100644 --- a/modules/pci/main.c +++ b/modules/pci/main.c @@ -144,5 +144,6 @@ void __attribute__((section(".minit"))) init(env_t *env) { scan( ); env->ret = &mod; + mod_update_info(env); delete_thread( ); } \ No newline at end of file diff --git a/modules/pci/pci_data.c b/modules/pci/pci_data.c index 5433e63..e8c9485 100644 --- a/modules/pci/pci_data.c +++ b/modules/pci/pci_data.c @@ -59,8 +59,8 @@ static void print_vendors(uint64_t num_vendors, vendor_t **vendor_list) { } } -module_info_t mod = { .name = (char *)"[PCI][ADAPTER]", - .message = (char *)"PCI данные", +module_info_t mod = { .name = "[PCI][ADAPTER]", + .message = "PCI данные", .type = 0, .data_size = 0, .data = 0, @@ -86,6 +86,7 @@ void __attribute__((section(".minit"))) init(env_t *env) { mod.data_size = num_vendors; mod.data = vendor_list; env->ret = &mod; - log_printf("Готово22\n"); + log_printf("Готово %x\n", vendor_list); + mod_update_info(env); delete_thread( ); } \ No newline at end of file diff --git a/modules/ps2/main.c b/modules/ps2/main.c index 1eca59a..de7c0cc 100644 --- a/modules/ps2/main.c +++ b/modules/ps2/main.c @@ -161,5 +161,6 @@ void __attribute__((section(".minit"))) init(env_t *env) { .irq = 33, .irq_handler = &handler, .get_func = __get_func }); + mod_update_info(env); delete_thread( ); } \ No newline at end of file diff --git a/run.sh b/run.sh index 5081f45..d7e4319 100755 --- a/run.sh +++ b/run.sh @@ -1,5 +1,5 @@ #!/bin/sh -qemu-system-x86_64 -name "БМПОС" -cpu max -m 64M -smp 1 \ +qemu-system-x86_64 -name "БМПОС" -cpu max -m 128M -smp 1 \ -serial file:serial.log \ -drive file=bmosp.iso,if=none,id=sata_drive -device ahci \ -device virtio-blk-pci,drive=sata_drive \