diff --git a/kernel.c b/kernel.c index 96bbda5..8023e31 100644 --- a/kernel.c +++ b/kernel.c @@ -4,6 +4,7 @@ extern char __bss[], __bss_end[], __stack_top[]; extern char __free_ram[], __free_ram_end[]; extern char __kernel_base[]; +extern char _binary_shell_bin_start[], _binary_shell_bin_size[]; struct process procs[PROCS_MAX]; struct process *current_proc; @@ -190,7 +191,19 @@ __attribute__((naked)) void switch_context(uint32_t *prev_sp, ); } -struct process *create_process(uint32_t pc) { +__attribute__((naked)) void user_entry(void) { + __asm__ __volatile__( + "csrw sepc, %[sepc] \n" + "csrw sstatus, %[sstatus] \n" + "sret \n" + : + : [sepc] "r" (USER_BASE), + [sstatus] "r" (SSTATUS_SPIE) + ); +} + + +struct process *create_process(const void *image, size_t image_size) { // Find an unused proccess control structure struct process *proc = NULL; int i; @@ -218,7 +231,7 @@ struct process *create_process(uint32_t pc) { *--sp = 0; // s2 *--sp = 0; // s1 *--sp = 0; // s0 - *--sp = (uint32_t) pc; // ra + *--sp = (uint32_t) user_entry; // ra (changed) // Map kernel pages uint32_t *page_table = (uint32_t *) alloc_pages(1); @@ -226,6 +239,20 @@ struct process *create_process(uint32_t pc) { map_page(page_table, paddr, paddr, PAGE_R | PAGE_W | PAGE_X); } + // Map user pages + for (uint32_t off = 0; off < image_size; off += PAGE_SIZE) { + paddr_t page = alloc_pages(1); + + // Case where data to be copied is smaller than the page size + size_t remaining = image_size - off; + size_t copy_size = PAGE_SIZE <= remaining ? PAGE_SIZE : remaining; + + // Fill and map the page + memcpy((void *) page, image + off, copy_size); + map_page(page_table, USER_BASE + off, page, + PAGE_U | PAGE_R | PAGE_W | PAGE_X); + } + // Initialize fields proc->pid = i + 1; proc->state = PROC_RUNNABLE; @@ -304,7 +331,7 @@ void kernel_main(void) { WRITE_CSR(stvec, (uint32_t) kernel_entry); - idle_proc = create_process((uint32_t) NULL); + idle_proc = create_process(NULL, 0); idle_proc->pid = 0; // idle current_proc = idle_proc; @@ -313,8 +340,11 @@ void kernel_main(void) { // printf("alloc_pages test paddr0=%x\n", paddr0); // printf("alloc_pages test paddr1=%x\n", paddr1); - proc_a = create_process((uint32_t) proc_a_entry); - proc_b = create_process((uint32_t) proc_b_entry); + // proc_a = create_process((uint32_t) proc_a_entry); + // proc_b = create_process((uint32_t) proc_b_entry); + + // NEW + create_process(_binary_shell_bin_start, (size_t) _binary_shell_bin_size); yield(); PANIC("Switched to idle process"); diff --git a/kernel.h b/kernel.h index fe17181..0422fa5 100644 --- a/kernel.h +++ b/kernel.h @@ -10,6 +10,8 @@ #define PAGE_W (1 << 2) // Writable #define PAGE_X (1 << 3) // Executable #define PAGE_U (1 << 4) // User (accessible in user mode) +#define USER_BASE 0x1000000 +#define SSTATUS_SPIE (1 << 5) struct process { int pid; // ID of a process diff --git a/shell.c b/shell.c index 9e5e690..5c15ebf 100644 --- a/shell.c +++ b/shell.c @@ -1,5 +1,17 @@ #include "user.h" void main(void) { - for(;;); + // *((volatile int *) 0x80200000) = 0x1234; + // printf(" ___ ___ ___ ___ ___ ___ ___ \\n"); + // printf(" /\\ \\ /\\__\\ /\\ \\ /\\ \\ /\\__\\ /\\ \\ /\\ \\ \\n"); + // printf(" /::\\ \\ /::| | /::\\ \\ /::\\ \\ /:/ / /::\\ \\ /::\\ \\ \\n"); + // printf(" /:/\\:\\ \\ /:|:| | /:/\\:\\ \\ /:/\\:\\ \\ /:/ / /:/\\:\\ \\ /:/\\ \\ \\ \\n"); + // printf(" /::\\~\\:\\ \\ /:/|:|__|__ /:/ \\:\\ \\ /::\\~\\:\\ \\ /:/ / /:/ \\:\\ \\ _\\:\\~\\ \\ \\ \\n"); + // printf(" /:/\\:\\ \\:\\__\\ /:/ |::::\\__\\ /:/__/ \\:\\__\\ /:/\\:\\ \\:\\__\\ /:/__/ /:/__/ \\:\\__\\ /\\ \\:\\ \\ \\__\\\\n"); + // printf(" \\/__\\:\\/:/ / \\/__/~~/:/ / \\:\\ \\ /:/ / \\:\\~\\:\\ \\/__/ \\:\\ \\ \\:\\ \\ /:/ / \\:\\ \\:\\ \\/__/\\n"); + // printf(" \\::/ / /:/ / \\:\\ /:/ / \\:\\ \\:\\__\\ \\:\\ \\ \\:\\ /:/ / \\:\\ \\:\\__\\ \\n"); + // printf(" /:/ / /:/ / \\:\\/:/ / \\:\\ \\/__/ \\:\\ \\ \\:\\/:/ / \\:\\/:/ / \\n"); + // printf(" /:/ / /:/ / \\::/ / \\:\\__\\ \\:\\__\\ \\::/ / \\::/ / \\n"); + // printf(" \\/__/ \\/__/ \\/__/ \\/__/ \\/__/ \\/__/ \\/__/ \\n"); + for (;;); } diff --git a/user.ld b/user.ld index d4bca52..0d19165 100644 --- a/user.ld +++ b/user.ld @@ -1,7 +1,7 @@ ENTRY(start) SECTIONS { - . = 0x10000000; + . = 0x1000000; /* machine code */ .text :{