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_end __builtin_va_end
|
||||||
#define va_arg __builtin_va_arg
|
#define va_arg __builtin_va_arg
|
||||||
#define PAGE_SIZE 4096
|
#define PAGE_SIZE 4096
|
||||||
|
#define SYS_PUTCHAR 1
|
||||||
|
#define SYS_GETCHAR 2
|
||||||
|
|
||||||
void *memset(void *buf, char c, size_t n);
|
void *memset(void *buf, char c, size_t n);
|
||||||
void *memcpy(void *dst, const void *src, 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 */);
|
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__((naked))
|
||||||
__attribute__((aligned(4)))
|
__attribute__((aligned(4)))
|
||||||
void kernel_entry(void) {
|
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) {
|
void handle_trap(struct trap_frame *f) {
|
||||||
uint32_t scause = READ_CSR(scause);
|
uint32_t scause = READ_CSR(scause);
|
||||||
uint32_t stval = READ_CSR(stval);
|
uint32_t stval = READ_CSR(stval);
|
||||||
uint32_t user_pc = READ_CSR(sepc);
|
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) {
|
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);
|
||||||
@@ -324,11 +355,8 @@ void kernel_main(void) {
|
|||||||
// for (;;) {
|
// for (;;) {
|
||||||
// __asm__ __volatile__("wfi");
|
// __asm__ __volatile__("wfi");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
memset(__bss, 0, (size_t) __bss_end - (size_t) __bss);
|
memset(__bss, 0, (size_t) __bss_end - (size_t) __bss);
|
||||||
|
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
|
|
||||||
WRITE_CSR(stvec, (uint32_t) kernel_entry);
|
WRITE_CSR(stvec, (uint32_t) kernel_entry);
|
||||||
|
|
||||||
idle_proc = create_process(NULL, 0);
|
idle_proc = create_process(NULL, 0);
|
||||||
@@ -345,8 +373,8 @@ void kernel_main(void) {
|
|||||||
|
|
||||||
// NEW
|
// NEW
|
||||||
create_process(_binary_shell_bin_start, (size_t) _binary_shell_bin_size);
|
create_process(_binary_shell_bin_start, (size_t) _binary_shell_bin_size);
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
|
|
||||||
PANIC("Switched to idle process");
|
PANIC("Switched to idle process");
|
||||||
|
|
||||||
// __asm__ __volatile__("unimp"); // calls a unimp which triggers kernel panic
|
// __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_UNUSED 0 // Unused processes control structure
|
||||||
#define PROC_RUNNABLE 1 // Runnable proccess
|
#define PROC_RUNNABLE 1 // Runnable proccess
|
||||||
#define SATP_SV32 (1u << 31)
|
#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_V (1 << 0) // "Valid" bit (entry is allowed)
|
||||||
#define PAGE_R (1 << 1) // Readable
|
#define PAGE_R (1 << 1) // Readable
|
||||||
#define PAGE_W (1 << 2) // Writable
|
#define PAGE_W (1 << 2) // Writable
|
||||||
#define PAGE_X (1 << 3) // Executable
|
#define PAGE_X (1 << 3) // Executable
|
||||||
#define PAGE_U (1 << 4) // User (accessible in user mode)
|
#define PAGE_U (1 << 4) // User (accessible in user mode)
|
||||||
#define USER_BASE 0x1000000
|
#define USER_BASE 0x1000000
|
||||||
#define SSTATUS_SPIE (1 << 5)
|
|
||||||
|
|
||||||
struct process {
|
struct process {
|
||||||
int pid; // ID of a process
|
int pid; // ID of a process
|
||||||
|
3
run.sh
3
run.sh
@@ -9,7 +9,8 @@ OBJCOPY=/usr/bin/llvm-objcopy
|
|||||||
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
|
# 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 --set-section-flags .bss=alloc,contents -O binary shell.elf shell.bin
|
||||||
$OBJCOPY -Ibinary -Oelf32-littleriscv shell.bin shell.bin.o
|
$OBJCOPY -Ibinary -Oelf32-littleriscv shell.bin shell.bin.o
|
||||||
|
|
||||||
|
38
shell.c
38
shell.c
@@ -1,17 +1,29 @@
|
|||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// *((volatile int *) 0x80200000) = 0x1234;
|
while (1) {
|
||||||
// printf(" ___ ___ ___ ___ ___ ___ ___ \\n");
|
prompt:
|
||||||
// printf(" /\\ \\ /\\__\\ /\\ \\ /\\ \\ /\\__\\ /\\ \\ /\\ \\ \\n");
|
printf("# > ");
|
||||||
// printf(" /::\\ \\ /::| | /::\\ \\ /::\\ \\ /:/ / /::\\ \\ /::\\ \\ \\n");
|
char cmdline[128];
|
||||||
// printf(" /:/\\:\\ \\ /:|:| | /:/\\:\\ \\ /:/\\:\\ \\ /:/ / /:/\\:\\ \\ /:/\\ \\ \\ \\n");
|
for (int i = 0;; i++) {
|
||||||
// printf(" /::\\~\\:\\ \\ /:/|:|__|__ /:/ \\:\\ \\ /::\\~\\:\\ \\ /:/ / /:/ \\:\\ \\ _\\:\\~\\ \\ \\ \\n");
|
char ch = getchar();
|
||||||
// printf(" /:/\\:\\ \\:\\__\\ /:/ |::::\\__\\ /:/__/ \\:\\__\\ /:/\\:\\ \\:\\__\\ /:/__/ /:/__/ \\:\\__\\ /\\ \\:\\ \\ \\__\\\\n");
|
putchar(ch);
|
||||||
// printf(" \\/__\\:\\/:/ / \\/__/~~/:/ / \\:\\ \\ /:/ / \\:\\~\\:\\ \\/__/ \\:\\ \\ \\:\\ \\ /:/ / \\:\\ \\:\\ \\/__/\\n");
|
if (i == sizeof(cmdline) - 1) {
|
||||||
// printf(" \\::/ / /:/ / \\:\\ /:/ / \\:\\ \\:\\__\\ \\:\\ \\ \\:\\ /:/ / \\:\\ \\:\\__\\ \\n");
|
printf("too much yapping bro :(\n");
|
||||||
// printf(" /:/ / /:/ / \\:\\/:/ / \\:\\ \\/__/ \\:\\ \\ \\:\\/:/ / \\:\\/:/ / \\n");
|
goto prompt;
|
||||||
// printf(" /:/ / /:/ / \\::/ / \\:\\__\\ \\:\\__\\ \\::/ / \\::/ / \\n");
|
} else if (ch == '\r') {
|
||||||
// printf(" \\/__/ \\/__/ \\/__/ \\/__/ \\/__/ \\/__/ \\/__/ \\n");
|
printf("\n");
|
||||||
for (;;);
|
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 "user.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
extern char __stack_top[];
|
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) {
|
__attribute__((noreturn)) void exit(void) {
|
||||||
for(;;);
|
for(;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
void putchar(char ch) {
|
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")))
|
__attribute__((section(".text.start")))
|
||||||
|
Reference in New Issue
Block a user