From cfffd14b4b81e3d6b6f7c1b0f45307660cab3aa5 Mon Sep 17 00:00:00 2001 From: Amoelle Date: Tue, 29 Jul 2025 21:48:16 +0300 Subject: [PATCH] wrote a shell but have an error will debug tomorrow --- common.h | 2 ++ kernel.c | 40 ++++++++++++++++++++++++++++++++++------ kernel.h | 3 ++- run.sh | 3 ++- shell.c | 38 +++++++++++++++++++++++++------------- user.c | 21 ++++++++++++++++++++- user.h | 1 + 7 files changed, 86 insertions(+), 22 deletions(-) diff --git a/common.h b/common.h index 0be6725..ce55b19 100644 --- a/common.h +++ b/common.h @@ -20,6 +20,8 @@ typedef uint32_t vaddr_t; #define va_end __builtin_va_end #define va_arg __builtin_va_arg #define PAGE_SIZE 4096 +#define SYS_PUTCHAR 1 +#define SYS_GETCHAR 2 void *memset(void *buf, char c, size_t n); void *memcpy(void *dst, const void *src, size_t n); diff --git a/kernel.c b/kernel.c index 8023e31..5adef72 100644 --- a/kernel.c +++ b/kernel.c @@ -67,6 +67,11 @@ void putchar(char ch) { sbi_call(ch, 0, 0, 0, 0, 0, 0, 1 /* Console Putchar */); } +long getchar(void) { + struct sbiret ret = sbi_call(0, 0, 0, 0, 0, 0, 0, 2); + return ret.error; +} + __attribute__((naked)) __attribute__((aligned(4))) void kernel_entry(void) { @@ -308,15 +313,41 @@ void proc_b_entry(void) { } } +void handle_syscall(struct trap_frame *f) { + switch (f->a3) { + case SYS_GETCHAR: + while (1) { + long ch = getchar(); + if (ch >= 0) { + f->a0 = ch; + break; + } + + yield(); + } + break; + case SYS_PUTCHAR: + putchar(f->a0); + break; + default: + PANIC("unexpected syscall a3=%x\n", f->a3); + } +} + 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); + if (scause == SCAUSE_ECALL) { + handle_syscall(f); + user_pc += 4; + } else { + PANIC("unexpected trap scause=%x, stval=%x, sepc=%x\n", scause, stval, user_pc); + } - PANIC("Unexpected trap: scause=%x, stval=%x, sepc=%x\n", scause, stval, user_pc); + WRITE_CSR(sepc, user_pc); } - void kernel_main(void) { // printf("\n\nHello %s\n", "friend :3"); // printf("60 + 9 = %d, %x\n", 60 + 9, 0x1234abcd); @@ -324,11 +355,8 @@ void kernel_main(void) { // for (;;) { // __asm__ __volatile__("wfi"); // } - memset(__bss, 0, (size_t) __bss_end - (size_t) __bss); - printf("\n\n"); - WRITE_CSR(stvec, (uint32_t) kernel_entry); idle_proc = create_process(NULL, 0); @@ -345,8 +373,8 @@ void kernel_main(void) { // NEW create_process(_binary_shell_bin_start, (size_t) _binary_shell_bin_size); - yield(); + PANIC("Switched to idle process"); // __asm__ __volatile__("unimp"); // calls a unimp which triggers kernel panic diff --git a/kernel.h b/kernel.h index 0422fa5..efe1f61 100644 --- a/kernel.h +++ b/kernel.h @@ -5,13 +5,14 @@ #define PROC_UNUSED 0 // Unused processes control structure #define PROC_RUNNABLE 1 // Runnable proccess #define SATP_SV32 (1u << 31) +#define SSTATUS_SPIE (1 << 5) +#define SCAUSE_ECALL 8 #define PAGE_V (1 << 0) // "Valid" bit (entry is allowed) #define PAGE_R (1 << 1) // Readable #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/run.sh b/run.sh index 18d5aee..c40a4b9 100755 --- a/run.sh +++ b/run.sh @@ -9,7 +9,8 @@ OBJCOPY=/usr/bin/llvm-objcopy 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 +# Build the shell +$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 diff --git a/shell.c b/shell.c index 5c15ebf..55f1564 100644 --- a/shell.c +++ b/shell.c @@ -1,17 +1,29 @@ #include "user.h" void main(void) { - // *((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 (;;); + while (1) { +prompt: + printf("# > "); + char cmdline[128]; + for (int i = 0;; i++) { + char ch = getchar(); + putchar(ch); + if (i == sizeof(cmdline) - 1) { + printf("too much yapping bro :(\n"); + goto prompt; + } else if (ch == '\r') { + printf("\n"); + cmdline[i] = '\0'; + break; + } else { + cmdline[i] = ch; + } + } + + if (strcmp(cmdline, "hello") == 0) { + printf("Hellow :3\n"); + } else { + printf("I don't know what is %s yet :(", cmdline); + } + } } diff --git a/user.c b/user.c index 793c07f..20ea0b5 100644 --- a/user.c +++ b/user.c @@ -1,13 +1,32 @@ #include "user.h" +#include "common.h" extern char __stack_top[]; +int syscall(int sysno, int arg0, int arg1, int arg2) { + register int a0 __asm__("a0") = arg0; + register int a1 __asm__("a1") = arg1; + register int a2 __asm__("a2") = arg2; + register int a3 __asm__("a3") = sysno; + + __asm__ __volatile__("ecall" + : "=r"(a0) + : "r"(a0), "r"(a1), "r"(a2), "r"(a3) + : "memory"); + + return a0; +} + __attribute__((noreturn)) void exit(void) { for(;;); } void putchar(char ch) { - // TODO + syscall(SYS_PUTCHAR, ch, 0, 0); +} + +int getchar(void) { + return syscall(SYS_GETCHAR, 0, 0, 0); } __attribute__((section(".text.start"))) diff --git a/user.h b/user.h index 637fa52..f2ddae9 100644 --- a/user.h +++ b/user.h @@ -3,3 +3,4 @@ __attribute__((noreturn)) void exit(void); void putchar(char ch); +int getchar(void);