wrote a shell but have an error will debug tomorrow
This commit is contained in:
2
common.h
2
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);
|
||||
|
40
kernel.c
40
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
|
||||
|
3
kernel.h
3
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
|
||||
|
1
run.sh
1
run.sh
@@ -9,6 +9,7 @@ OBJCOPY=/usr/bin/llvm-objcopy
|
||||
CC=clang
|
||||
CFLAGS="-std=c11 -O2 -g3 -Wall -Wextra --target=riscv32-unknown-elf -fno-stack-protector -ffreestanding -nostdlib"
|
||||
|
||||
# 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
|
||||
|
38
shell.c
38
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
21
user.c
21
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")))
|
||||
|
Reference in New Issue
Block a user