Flat memory model, read_file() accepts statbuf.

This commit is contained in:
Alexander Myltsev 2025-01-18 01:29:23 +04:00
parent 5a05c48afc
commit 62c290f449
5 changed files with 27 additions and 32 deletions

View File

@ -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 {

14
fs/fs.c
View File

@ -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;
}

View File

@ -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);

View File

@ -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') {

25
proc.c
View File

@ -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();
}