more userspace stuff
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
#include "multiboot.h"
|
||||
#include "interrupts.h"
|
||||
#include "gdt.h"
|
||||
#include "scheduler.h"
|
||||
#include "common.h"
|
||||
#include "scheduler.h"
|
||||
#include "vfs.h"
|
||||
#include "elf.h"
|
||||
#include "gdt.h"
|
||||
|
||||
#include <lib/print.h>
|
||||
#include <lib/stream.h>
|
||||
@@ -26,6 +27,9 @@
|
||||
extern char __kernel_start;
|
||||
extern char __kernel_end;
|
||||
|
||||
extern uint32_t page_directory[1024];
|
||||
void* kernel_cr3 = page_directory;
|
||||
|
||||
void parse_multiboot_modules(uint32_t mbi_vaddr) {
|
||||
// find where grub put the boot module containing initrd
|
||||
multiboot_info* mbi = (multiboot_info*)mbi_vaddr;
|
||||
@@ -52,7 +56,8 @@ vfs_node_t* load_initrd() {
|
||||
return cpio_read_fs(initrd_module->mod_start);
|
||||
}
|
||||
|
||||
void load_program(const char* path) {
|
||||
void load_root_program(const char* path) {
|
||||
uint32_t kernel_cr3 = fetch_cr3();
|
||||
void* cr3 = create_task_pd();
|
||||
load_pd(cr3);
|
||||
flush_tlb();
|
||||
@@ -93,12 +98,12 @@ void load_program(const char* path) {
|
||||
|
||||
for (uint32_t v = page_start; v < page_end; v += PAGE_SIZE) {
|
||||
void* phys_frame = p_alloc_frame();
|
||||
map_page(v, (uint32_t)phys_frame, 0x07);
|
||||
map_page(v, (uint32_t)phys_frame, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER);
|
||||
}
|
||||
|
||||
uint32_t data_ptr = ph->p_offset;
|
||||
fseek(fd, data_ptr);
|
||||
read(fd, (void*)vstart, ph->p_memsz);
|
||||
read(fd, (void*)vstart, ph->p_filesz);
|
||||
|
||||
// 0 out bss
|
||||
if (ph->p_memsz > ph->p_filesz) {
|
||||
@@ -110,15 +115,24 @@ void load_program(const char* path) {
|
||||
ph_table_ptr += sizeof(elf_program_header_t);
|
||||
}
|
||||
|
||||
uint32_t esp = 0xBFFF0000;
|
||||
void* pesp = p_alloc_frame();
|
||||
map_page(esp - PAGE_SIZE, (uint32_t)pesp, 0x07);
|
||||
uint32_t stack_sz = PAGE_SIZE * 16;
|
||||
uint32_t stack_top = 0xBFFF0000;
|
||||
uint32_t stack_bottom = stack_top - stack_sz;
|
||||
for (uint32_t vaddr = stack_bottom; vaddr < stack_top; vaddr += PAGE_SIZE) {
|
||||
void* phys_frame = p_alloc_frame();
|
||||
map_page(vaddr, (uint32_t)phys_frame, PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER);
|
||||
}
|
||||
|
||||
create_task(e_hdr->e_entry, fetch_cr3(), 1);
|
||||
}
|
||||
uint32_t* u_esp = (uint32_t*)stack_top;
|
||||
*(--u_esp) = 0; // envp = NULL
|
||||
*(--u_esp) = 0; // argv = NULL
|
||||
*(--u_esp) = 0; // argc = 0
|
||||
|
||||
void start_origin() {
|
||||
load_program("/origin.elf");
|
||||
create_task(e_hdr->e_entry, (uint32_t)cr3, 1, (uint32_t)u_esp);
|
||||
load_pd((void*)kernel_cr3);
|
||||
flush_tlb();
|
||||
|
||||
kprintf("task created for origin program %s\n", path);
|
||||
}
|
||||
|
||||
void kmain(uint32_t magic, multiboot_info* mbi) {
|
||||
@@ -150,13 +164,14 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
|
||||
if (!initrd_root) {
|
||||
kprintf("failed to load initrd\n");
|
||||
}
|
||||
|
||||
mount(vfs_root, initrd_root);
|
||||
kprintf("initrd read, mounted @ /\n");
|
||||
|
||||
disable_interrupts();
|
||||
init_scheduler();
|
||||
enable_interrupts();
|
||||
|
||||
kprintf("loading user program\n");
|
||||
start_origin();
|
||||
kprintf("loading origin program\n");
|
||||
load_root_program("/origin.elf");
|
||||
yield();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user