From 62c290f4496080209e1ec7f3dc483b9f9009f696 Mon Sep 17 00:00:00 2001 From: Alexander Myltsev Date: Sat, 18 Jan 2025 01:29:23 +0400 Subject: [PATCH] Flat memory model, read_file() accepts statbuf. --- cpu/gdt.c | 8 ++++---- fs/fs.c | 14 +++++--------- fs/fs.h | 5 +++-- kernel.c | 7 ------- proc.c | 25 +++++++++++++++---------- 5 files changed, 27 insertions(+), 32 deletions(-) diff --git a/cpu/gdt.c b/cpu/gdt.c index 0b046c9..f005541 100644 --- a/cpu/gdt.c +++ b/cpu/gdt.c @@ -32,10 +32,10 @@ struct seg_desc_t { struct seg_desc_t seg_desc[6]; void init_seg_desc() { - seg_desc[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, 0); - seg_desc[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); - seg_desc[SEG_UCODE] = SEG(STA_X|STA_R, USER_BASE, 0xffffffff - USER_BASE, DPL_USER); - seg_desc[SEG_UDATA] = SEG(STA_W, USER_BASE, 0xffffffff - USER_BASE, DPL_USER); + seg_desc[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, 0); + seg_desc[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); + seg_desc[SEG_UCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, DPL_USER); + seg_desc[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER); } struct gdt_desc_t { diff --git a/fs/fs.c b/fs/fs.c index 6c7e6b6..7299058 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -13,7 +13,7 @@ int stat(const char* name, struct stat *buf) { struct dirent *e = &dir.entries[i]; if (!strncmp(e->name, name, sizeof(e->name))) { buf->size = e->size_bytes; - buf->reserved[0] = e->offset_sectors; + buf->start_sector = e->offset_sectors; return 0; } } @@ -23,14 +23,10 @@ int stat(const char* name, struct stat *buf) { /* Find file by name and read it into buffer with size bufsize. * At most (bufsize & -512) bytes will be read. * Return number of bytes read or -1 on failure. */ -int read_file(const char* name, void* buf, uint32_t bufsize) { - struct stat statbuf; - if (stat(name, &statbuf) != 0) { - return -1; - } - uint32_t sector = fs_start + statbuf.reserved[0]; +int read_file(const struct stat *statbuf, void* buf, uint32_t bufsize) { + uint32_t sector = fs_start + statbuf->start_sector; uint32_t bytes_read = 0; - uint32_t file_sectors = (statbuf.size + sector_size - 1) / sector_size; + uint32_t file_sectors = (statbuf->size + sector_size - 1) / sector_size; while (bufsize >= sector_size && file_sectors > 0) { read_sectors_ATA_PIO(buf, sector, 1); sector++; @@ -39,5 +35,5 @@ int read_file(const char* name, void* buf, uint32_t bufsize) { buf += sector_size; bytes_read += sector_size; } - return bytes_read < statbuf.size ? bytes_read : statbuf.size; + return bytes_read < statbuf->size ? bytes_read : statbuf->size; } diff --git a/fs/fs.h b/fs/fs.h index 67f01a2..a67d569 100644 --- a/fs/fs.h +++ b/fs/fs.h @@ -38,7 +38,8 @@ struct dir { struct stat { uint32_t size; - uint32_t reserved[3]; + uint32_t start_sector; + uint32_t reserved1, reserved2; }; /* Find file by name and fill information in buf. @@ -48,4 +49,4 @@ int stat(const char* name, struct stat *buf); /* Find file by name and read it into buffer with size bufsize. * At most (bufsize & ~511) bytes will be read. * Return number of bytes read or -1 on failure. */ -int read_file(const char* name, void* buf, uint32_t bufsize); +int read_file(const struct stat *statbuf, void* buf, uint32_t bufsize); diff --git a/kernel.c b/kernel.c index 98695fb..5b309e5 100644 --- a/kernel.c +++ b/kernel.c @@ -26,16 +26,9 @@ void kmain() { load_idt(); sti(); - char *buf = (char*)(16 << 20); - vga_clear_screen(); printk("YABLOKO\n"); - if (read_file("kernel.bin", buf, 4096 + sector_size) > 0) { - printk(buf + 4096); - } else { - printk("failed to read file\n"); - } printk("\n> "); while (1) { if (kbd_buf_size > 0 && kbd_buf[kbd_buf_size-1] == '\n') { diff --git a/proc.c b/proc.c index 3b462d6..e6d81af 100644 --- a/proc.c +++ b/proc.c @@ -23,31 +23,36 @@ struct kstack { struct task { struct taskstate tss; struct kstack stack; + pde_t *pgdir; }; struct vm { void *kernel_thread; - void *user_thread; struct task *user_task; -} *vm; +} vm; void trapret(); void swtch(void** oldstack, void* newstack); void run_elf(const char* name) { - if (!vm) { - vm = kalloc(); - vm->user_task = kalloc(); - switchuvm(&vm->user_task->tss, vm->user_task->stack.bottom); + struct stat statbuf; + if (stat(name, &statbuf) != 0) { + printk(name); + printk(": file not found\n"); + return; } - if (read_file(name, (void*)USER_BASE, 100 << 20) <= 0) { + if (!vm.user_task) { + vm.user_task = kalloc(); + switchuvm(&vm.user_task->tss, vm.user_task->stack.bottom); + } + if (read_file(&statbuf, (void*)USER_BASE, 100 << 20) <= 0) { printk(name); printk(": file not found\n"); return; } Elf32_Ehdr *hdr = (void*)USER_BASE; - struct kstack *u = &vm->user_task->stack; + struct kstack *u = &vm.user_task->stack; memset(u, 0, sizeof(*u)); u->context.eip = (uint32_t)trapret; @@ -63,13 +68,13 @@ void run_elf(const char* name) { tf->useresp = USER_STACK_BASE; // initialization done, now switch to the process - swtch(&vm->kernel_thread, &u->context); + swtch(&vm.kernel_thread, &u->context); // process has finished } _Noreturn void killproc() { void* task_stack; - swtch(&task_stack, vm->kernel_thread); + swtch(&task_stack, vm.kernel_thread); __builtin_unreachable(); }