Flat memory model, read_file() accepts statbuf.
This commit is contained in:
parent
5a05c48afc
commit
62c290f449
@ -34,8 +34,8 @@ struct seg_desc_t seg_desc[6];
|
|||||||
void init_seg_desc() {
|
void init_seg_desc() {
|
||||||
seg_desc[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, 0);
|
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_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_UCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, DPL_USER);
|
||||||
seg_desc[SEG_UDATA] = SEG(STA_W, USER_BASE, 0xffffffff - USER_BASE, DPL_USER);
|
seg_desc[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gdt_desc_t {
|
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];
|
struct dirent *e = &dir.entries[i];
|
||||||
if (!strncmp(e->name, name, sizeof(e->name))) {
|
if (!strncmp(e->name, name, sizeof(e->name))) {
|
||||||
buf->size = e->size_bytes;
|
buf->size = e->size_bytes;
|
||||||
buf->reserved[0] = e->offset_sectors;
|
buf->start_sector = e->offset_sectors;
|
||||||
return 0;
|
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.
|
/* Find file by name and read it into buffer with size bufsize.
|
||||||
* At most (bufsize & -512) bytes will be read.
|
* At most (bufsize & -512) bytes will be read.
|
||||||
* Return number of bytes read or -1 on failure. */
|
* 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) {
|
||||||
struct stat statbuf;
|
uint32_t sector = fs_start + statbuf->start_sector;
|
||||||
if (stat(name, &statbuf) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
uint32_t sector = fs_start + statbuf.reserved[0];
|
|
||||||
uint32_t bytes_read = 0;
|
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) {
|
while (bufsize >= sector_size && file_sectors > 0) {
|
||||||
read_sectors_ATA_PIO(buf, sector, 1);
|
read_sectors_ATA_PIO(buf, sector, 1);
|
||||||
sector++;
|
sector++;
|
||||||
@ -39,5 +35,5 @@ int read_file(const char* name, void* buf, uint32_t bufsize) {
|
|||||||
buf += sector_size;
|
buf += sector_size;
|
||||||
bytes_read += 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 {
|
struct stat {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t reserved[3];
|
uint32_t start_sector;
|
||||||
|
uint32_t reserved1, reserved2;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Find file by name and fill information in buf.
|
/* 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.
|
/* Find file by name and read it into buffer with size bufsize.
|
||||||
* At most (bufsize & ~511) bytes will be read.
|
* At most (bufsize & ~511) bytes will be read.
|
||||||
* Return number of bytes read or -1 on failure. */
|
* 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();
|
load_idt();
|
||||||
sti();
|
sti();
|
||||||
|
|
||||||
char *buf = (char*)(16 << 20);
|
|
||||||
|
|
||||||
vga_clear_screen();
|
vga_clear_screen();
|
||||||
printk("YABLOKO\n");
|
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> ");
|
printk("\n> ");
|
||||||
while (1) {
|
while (1) {
|
||||||
if (kbd_buf_size > 0 && kbd_buf[kbd_buf_size-1] == '\n') {
|
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 task {
|
||||||
struct taskstate tss;
|
struct taskstate tss;
|
||||||
struct kstack stack;
|
struct kstack stack;
|
||||||
|
pde_t *pgdir;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vm {
|
struct vm {
|
||||||
void *kernel_thread;
|
void *kernel_thread;
|
||||||
void *user_thread;
|
|
||||||
struct task *user_task;
|
struct task *user_task;
|
||||||
} *vm;
|
} vm;
|
||||||
|
|
||||||
void trapret();
|
void trapret();
|
||||||
void swtch(void** oldstack, void* newstack);
|
void swtch(void** oldstack, void* newstack);
|
||||||
|
|
||||||
void run_elf(const char* name) {
|
void run_elf(const char* name) {
|
||||||
if (!vm) {
|
struct stat statbuf;
|
||||||
vm = kalloc();
|
if (stat(name, &statbuf) != 0) {
|
||||||
vm->user_task = kalloc();
|
printk(name);
|
||||||
switchuvm(&vm->user_task->tss, vm->user_task->stack.bottom);
|
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(name);
|
||||||
printk(": file not found\n");
|
printk(": file not found\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Elf32_Ehdr *hdr = (void*)USER_BASE;
|
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));
|
memset(u, 0, sizeof(*u));
|
||||||
u->context.eip = (uint32_t)trapret;
|
u->context.eip = (uint32_t)trapret;
|
||||||
|
|
||||||
@ -63,13 +68,13 @@ void run_elf(const char* name) {
|
|||||||
tf->useresp = USER_STACK_BASE;
|
tf->useresp = USER_STACK_BASE;
|
||||||
|
|
||||||
// initialization done, now switch to the process
|
// initialization done, now switch to the process
|
||||||
swtch(&vm->kernel_thread, &u->context);
|
swtch(&vm.kernel_thread, &u->context);
|
||||||
|
|
||||||
// process has finished
|
// process has finished
|
||||||
}
|
}
|
||||||
|
|
||||||
_Noreturn void killproc() {
|
_Noreturn void killproc() {
|
||||||
void* task_stack;
|
void* task_stack;
|
||||||
swtch(&task_stack, vm->kernel_thread);
|
swtch(&task_stack, vm.kernel_thread);
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user