diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-13 21:52:48 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-13 21:52:48 +0100 |
commit | 47e6cd42f0744f6c04b8347093f6549339a856c9 (patch) | |
tree | c91fc43178d136c2aa0f093087ba8cfb4e90bdae /src/kernel/core | |
parent | cf0b8a52287ee7c747b1d5a7d77abdef1fb46f94 (diff) | |
download | kogata-47e6cd42f0744f6c04b8347093f6549339a856c9.tar.gz kogata-47e6cd42f0744f6c04b8347093f6549339a856c9.zip |
Implement ELF loading ; arrange so that user processes run.
Diffstat (limited to 'src/kernel/core')
-rw-r--r-- | src/kernel/core/gdt.c | 21 | ||||
-rw-r--r-- | src/kernel/core/kmain.c | 19 | ||||
-rw-r--r-- | src/kernel/core/paging.c | 3 |
3 files changed, 29 insertions, 14 deletions
diff --git a/src/kernel/core/gdt.c b/src/kernel/core/gdt.c index 97e6661..ed7abe0 100644 --- a/src/kernel/core/gdt.c +++ b/src/kernel/core/gdt.c @@ -4,27 +4,25 @@ #define GDT_ENTRIES 6 // The contents of each entry is defined in gdt_init. /* One entry of the table */ -struct gdt_entry { +typedef struct { uint16_t limit_low; uint16_t base_low; uint8_t base_middle; uint8_t access; uint8_t granularity; uint8_t base_high; -} __attribute__((packed)); -typedef struct gdt_entry gdt_entry_t; +} __attribute__((packed)) gdt_entry_t; /* Structure defining the whole table : address and size (in bytes). */ -struct gdt_ptr { +typedef struct { uint16_t limit; uint32_t base; -} __attribute__((packed)); -typedef struct gdt_ptr gdt_ptr_t; +} __attribute__((packed)) gdt_ptr_t; /* The TSS is used for hardware multitasking. We don't use that, but we still need a TSS so that user mode process exceptions can be handled correctly by the kernel. */ -struct tss_entry { +typedef struct { uint32_t prev_tss; // The previous TSS - if we used hardware task switching this would form a linked list. uint32_t esp0; // The stack pointer to load when we change to kernel mode. uint32_t ss0; // The stack segment to load when we change to kernel mode. @@ -52,8 +50,7 @@ struct tss_entry { uint32_t ldt; // Unused... uint16_t trap; uint16_t iomap_base; -} __attribute__((packed)); -typedef struct tss_entry tss_entry_t; +} __attribute__((packed)) tss_entry_t; // ========================= // // Actual definitions @@ -86,13 +83,11 @@ void gdt_init() { gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); //User data segment 0x20 // Write TSS - memset(&tss_entry, 0, sizeof(tss_entry)); + memset(&tss_entry, 0, sizeof(tss_entry_t)); tss_entry.ss0 = 0x10; tss_entry.esp0 = 0; - - tss_entry.cs = 0x0b; - tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x13; + tss_entry.iomap_base = sizeof(tss_entry_t); uint32_t tss_base = (uint32_t)&tss_entry; uint32_t tss_limit = tss_base + sizeof(tss_entry_t); diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c index 34438aa..5572ac4 100644 --- a/src/kernel/core/kmain.c +++ b/src/kernel/core/kmain.c @@ -15,6 +15,8 @@ #include <vfs.h> #include <nullfs.h> +#include <process.h> +#include <elf.h> #include <slab_alloc.h> #include <hashtbl.h> @@ -333,6 +335,23 @@ void kernel_init_stage2(void* data) { test_cmdline(mbd, devfs); + fs_handle_t *init_bin = fs_open(devfs, "/mod/init.bin", FM_READ | FM_MMAP); + if (init_bin == 0) PANIC("No init.bin module provided!"); + if (!is_elf(init_bin)) PANIC("init.bin is not valid ELF32 binary"); + + process_t *init_p = new_process(0); + ASSERT(init_p != 0); + + bool add_devfs_ok = proc_add_fs(init_p, devfs, "dev"); + ASSERT(add_devfs_ok); + + proc_entry_t *e = elf_load(init_bin, init_p); + if (e == 0) PANIC("Could not load ELF file init.bin"); + + unref_file(init_bin); + + start_process(init_p, e); + //TODO : // - (OK) populate devfs with information regarding kernel command line & modules // - create user process with init module provided on command line diff --git a/src/kernel/core/paging.c b/src/kernel/core/paging.c index 74331c0..5a58c8c 100644 --- a/src/kernel/core/paging.c +++ b/src/kernel/core/paging.c @@ -221,7 +221,8 @@ bool pd_map_page(void* vaddr, uint32_t frame_id, bool rw) { } current_pd->page[pt] = pd->page[pt] = - (new_pt_frame << PTE_FRAME_SHIFT) | PTE_PRESENT | PTE_RW; + (new_pt_frame << PTE_FRAME_SHIFT) | PTE_PRESENT | PTE_RW + | ((size_t)vaddr < K_HIGHHALF_ADDR ? PTE_USER : 0); invlpg(¤t_pt[pt]); } current_pt[pt].page[page] = |