Flat memory model, read_file() accepts statbuf.
This commit is contained in:
parent
5a05c48afc
commit
62c290f449
@ -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
14
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;
|
||||
}
|
||||
|
||||
5
fs/fs.h
5
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);
|
||||
|
||||
7
kernel.c
7
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') {
|
||||
|
||||
25
proc.c
25
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();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user