first user application
This commit is contained in:
22
kernel.c
22
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);
|
||||
|
7
run.sh
7
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 \
|
||||
|
22
user.c
Normal file
22
user.c
Normal file
@@ -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)
|
||||
);
|
||||
}
|
5
user.h
Normal file
5
user.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include "common.h"
|
||||
|
||||
__attribute__((noreturn)) void exit(void);
|
||||
void putchar(char ch);
|
32
user.ld
Normal file
32
user.ld
Normal file
@@ -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");
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user