aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/core
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-02-13 21:52:48 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-02-13 21:52:48 +0100
commit47e6cd42f0744f6c04b8347093f6549339a856c9 (patch)
treec91fc43178d136c2aa0f093087ba8cfb4e90bdae /src/kernel/core
parentcf0b8a52287ee7c747b1d5a7d77abdef1fb46f94 (diff)
downloadkogata-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.c21
-rw-r--r--src/kernel/core/kmain.c19
-rw-r--r--src/kernel/core/paging.c3
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(&current_pt[pt]);
}
current_pt[pt].page[page] =