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,
|
__attribute__((naked)) void switch_context(uint32_t *prev_sp,
|
||||||
uint32_t *next_sp) {
|
uint32_t *next_sp) {
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
@@ -242,11 +234,6 @@ struct process *create_process(uint32_t pc) {
|
|||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void delay(void) {
|
|
||||||
for (int i = 0; i < 69696969; i++)
|
|
||||||
__asm__ __volatile__("nop"); // do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
void yield(void) {
|
void yield(void) {
|
||||||
// Search for a runnable process
|
// Search for a runnable process
|
||||||
struct process *next = idle_proc;
|
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) {
|
void kernel_main(void) {
|
||||||
// printf("\n\nHello %s\n", "friend :3");
|
// printf("\n\nHello %s\n", "friend :3");
|
||||||
// printf("60 + 9 = %d, %x\n", 60 + 9, 0x1234abcd);
|
// printf("60 + 9 = %d, %x\n", 60 + 9, 0x1234abcd);
|
||||||
|
7
run.sh
7
run.sh
@@ -3,14 +3,19 @@ set -xue
|
|||||||
|
|
||||||
# QEMU path
|
# QEMU path
|
||||||
QEMU=qemu-system-riscv32
|
QEMU=qemu-system-riscv32
|
||||||
|
OBJCOPY=/usr/bin/llvm-objcopy
|
||||||
|
|
||||||
# Path to clang and compiler flags
|
# Path to clang and compiler flags
|
||||||
CC=clang
|
CC=clang
|
||||||
CFLAGS="-std=c11 -O2 -g3 -Wall -Wextra --target=riscv32-unknown-elf -fno-stack-protector -ffreestanding -nostdlib"
|
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
|
# Build the kernel
|
||||||
$CC $CFLAGS -Wl,-Tkernel.ld -Wl,-Map=kernel.map -o kernel.elf \
|
$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
|
# Start QEMU
|
||||||
$QEMU -machine virt -bios default -nographic -serial mon:stdio --no-reboot \
|
$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