mirror of https://github.com/0Nera/BMOSP.git
Merge pull request #12 from 0Nera/feature
Более стабильная работа модулей
This commit is contained in:
commit
18ceec804b
2
TODO.md
2
TODO.md
|
@ -85,4 +85,4 @@
|
|||
- [ ] Настройка окружения
|
||||
- [ ] Сборка из исходного кода
|
||||
- [ ] Привет мир!
|
||||
- [ ] Написание драйвера
|
||||
- [ ] Написание драйвера
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <stdint.h>
|
||||
#include <sys.h>
|
||||
|
||||
#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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef SYS_H
|
||||
#define SYS_H
|
||||
|
||||
#include <arch.h>
|
||||
#include <stdint.h>
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_BUILD 162
|
||||
#define VERSION_BUILD 202
|
||||
|
|
|
@ -82,6 +82,8 @@ static void exception_handler(struct frame state) {
|
|||
stk = stk->rbp;
|
||||
}
|
||||
|
||||
mod_list_show( );
|
||||
|
||||
asm volatile("cli");
|
||||
asm volatile("hlt");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
23
kernel/mod.c
23
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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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( );
|
||||
}
|
|
@ -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( );
|
||||
}
|
||||
|
|
|
@ -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( );
|
||||
}
|
||||
|
|
|
@ -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( );
|
||||
}
|
||||
|
|
|
@ -144,5 +144,6 @@ void __attribute__((section(".minit"))) init(env_t *env) {
|
|||
|
||||
scan( );
|
||||
env->ret = &mod;
|
||||
mod_update_info(env);
|
||||
delete_thread( );
|
||||
}
|
|
@ -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( );
|
||||
}
|
|
@ -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( );
|
||||
}
|
Loading…
Reference in New Issue