diff --git a/kernel.c b/kernel.c index 0811c32..96bbda5 100644 --- a/kernel.c +++ b/kernel.c @@ -148,14 +148,6 @@ void kernel_entry(void) { ); } -void handle_trap(struct trap_frame *f) { - uint32_t scause = READ_CSR(scause); - uint32_t stval = READ_CSR(stval); - uint32_t user_pc = READ_CSR(sepc); - - PANIC("Unexpected trap: scause=%x, stval=%x, sepc=%x\n", scause, stval, user_pc); -} - __attribute__((naked)) void switch_context(uint32_t *prev_sp, uint32_t *next_sp) { __asm__ __volatile__( @@ -242,11 +234,6 @@ struct process *create_process(uint32_t pc) { return proc; } -void delay(void) { - for (int i = 0; i < 69696969; i++) - __asm__ __volatile__("nop"); // do nothing -} - void yield(void) { // Search for a runnable process struct process *next = idle_proc; @@ -294,6 +281,15 @@ void proc_b_entry(void) { } } +void handle_trap(struct trap_frame *f) { + uint32_t scause = READ_CSR(scause); + uint32_t stval = READ_CSR(stval); + uint32_t user_pc = READ_CSR(sepc); + + PANIC("Unexpected trap: scause=%x, stval=%x, sepc=%x\n", scause, stval, user_pc); +} + + void kernel_main(void) { // printf("\n\nHello %s\n", "friend :3"); // printf("60 + 9 = %d, %x\n", 60 + 9, 0x1234abcd); diff --git a/run.sh b/run.sh index e312578..18d5aee 100755 --- a/run.sh +++ b/run.sh @@ -3,14 +3,19 @@ set -xue # QEMU path QEMU=qemu-system-riscv32 +OBJCOPY=/usr/bin/llvm-objcopy # Path to clang and compiler flags CC=clang CFLAGS="-std=c11 -O2 -g3 -Wall -Wextra --target=riscv32-unknown-elf -fno-stack-protector -ffreestanding -nostdlib" +$CC $CFLAGS -Wl,-Tuser.ld -Wl,-Map=shell.map -o shell.elf shell.c user.c common.c +$OBJCOPY --set-section-flags .bss=alloc,contents -O binary shell.elf shell.bin +$OBJCOPY -Ibinary -Oelf32-littleriscv shell.bin shell.bin.o + # Build the kernel $CC $CFLAGS -Wl,-Tkernel.ld -Wl,-Map=kernel.map -o kernel.elf \ - kernel.c common.c + kernel.c common.c shell.bin.o # Start QEMU $QEMU -machine virt -bios default -nographic -serial mon:stdio --no-reboot \ diff --git a/shell.c b/shell.c new file mode 100644 index 0000000..9e5e690 --- /dev/null +++ b/shell.c @@ -0,0 +1,5 @@ +#include "user.h" + +void main(void) { + for(;;); +} diff --git a/user.c b/user.c new file mode 100644 index 0000000..793c07f --- /dev/null +++ b/user.c @@ -0,0 +1,22 @@ +#include "user.h" + +extern char __stack_top[]; + +__attribute__((noreturn)) void exit(void) { + for(;;); +} + +void putchar(char ch) { + // TODO +} + +__attribute__((section(".text.start"))) +__attribute__((naked)) +void start(void) { + __asm__ __volatile__( + "mv sp, %[stack_top]\n" + "call main\n" + "call exit\n" + :: [stack_top] "r" (__stack_top) + ); +} diff --git a/user.h b/user.h new file mode 100644 index 0000000..637fa52 --- /dev/null +++ b/user.h @@ -0,0 +1,5 @@ +#pragma once +#include "common.h" + +__attribute__((noreturn)) void exit(void); +void putchar(char ch); diff --git a/user.ld b/user.ld new file mode 100644 index 0000000..d4bca52 --- /dev/null +++ b/user.ld @@ -0,0 +1,32 @@ +ENTRY(start) + +SECTIONS { + . = 0x10000000; + + /* machine code */ + .text :{ + KEEP(*(.text.start)); + *(.text .text.*); + } + + /* read only data */ + .rodata : ALIGN(4) { + *(.rodata .rodata.*); + } + + /* data with initial values */ + .data : ALIGN(4) { + *(.data .data.*); + } + + /* data that should be zero-filled at the start */ + .bss : ALIGN(4) { + *(.bss .bss.* .sbss .sbss.*); + + . = ALIGN(16); + . += 64 * 1024; /* 64KB */ + __stack_top = .; + + ASSERT(. < 0x18000000, "executable is too large"); + } +}