this repo has no description

initial commit

EmmaTheMartian 7ebd6cb9

+2
.gitignore
··· 1 + /build/ 2 +
+5
compile_flags.txt
··· 1 + -Wall 2 + -Wextra 3 + -Werror 4 + -ffreestanding 5 + -Isrcs/
+15
readme
··· 1 + nomad 2 + ===== 3 + 4 + build 5 + ----- 6 + 7 + Download a RISC-V 64-bit cross-compiler. 8 + Arch Linux: riscv64-elf-gcc 9 + 10 + $ sh scripts/build-kernel.sh 11 + 12 + To test it, I use QEMU. 13 + Arch Linux: qemu-system-riscv 14 + 15 + $ sh scripts/run-kernel-qemu.sh
+10
roadmap
··· 1 + 2 + - [ ] Bootloader 3 + - [ ] Basic kernel 4 + - [ ] Basic drivers 5 + - [ ] Shell 6 + - [ ] Userspace? 7 + 8 + - [ ] Run on bare metal 9 + - Orange Pi RV2? 10 + - Rock64?
+34
scripts/_config.sh
··· 1 + #!/usr/bin/env sh 2 + set -e 3 + 4 + NMD_TOOLCHAIN="riscv64-elf-" 5 + NMD_CC="gcc" 6 + NMD_AS="as" 7 + NMD_LD="ld" 8 + 9 + NMD_INCLUDE="-Isrcs/" 10 + 11 + NMD_KERNEL_CC_FLAGS="-Wall -Wextra -Werror -c -mcmodel=medany -ffreestanding $NMD_INCLUDE" 12 + NMD_KERNEL_AS_FLAGS="-c" 13 + NMD_KERNEL_LD_FLAGS="-nostdlib" 14 + 15 + function nmd_echo 16 + { 17 + echo "$ $1" 18 + $1 19 + } 20 + 21 + function nmd_cc() 22 + { 23 + nmd_echo "$NMD_TOOLCHAIN$NMD_CC $NMD_KERNEL_CC_FLAGS $NMD_ADD_KERNEL_CC_FLAGS $1 -o $2" 24 + } 25 + 26 + function nmd_as() 27 + { 28 + nmd_echo "$NMD_TOOLCHAIN$NMD_AS $NMD_KERNEL_AS_FLAGS $NMD_ADD_KERNEL_AS_FLAGS $1 -o $2" 29 + } 30 + 31 + function nmd_ld() 32 + { 33 + nmd_echo "$NMD_TOOLCHAIN$NMD_LD $NMD_KERNEL_LD_FLAGS $NMD_ADD_KERNEL_LD_FLAGS $1 -o $2" 34 + }
+24
scripts/build-kernel.sh
··· 1 + #!/usr/bin/env sh 2 + set -e 3 + 4 + . scripts/_config.sh 5 + 6 + mkdir -p build/kernel 7 + 8 + echo ": kernel.c" 9 + for f in `find srcs/kernel/ -name '*.c'` 10 + do 11 + ff=$(echo $f | tr '/' '_').o 12 + nmd_cc $f build/kernel/$ff 13 + done 14 + 15 + echo ": entry.S" 16 + nmd_as srcs/kernel/main/entry.S build/kernel/entry.o 17 + 18 + echo ": linking" 19 + NMD_ADD_KERNEL_LD_FLAGS="-T srcs/kernel/main/linker.ld" nmd_ld "build/kernel/*.o" build/kernel.elf 20 + 21 + echo ": cleaning" 22 + rm build/kernel/*.o 23 + 24 + echo ": done"
+4
scripts/run-kernel-qemu.sh
··· 1 + #!/usr/bin/env sh 2 + set -e 3 + 4 + qemu-system-riscv64 -machine virt -bios none -kernel build/kernel.elf -serial mon:stdio
+83
srcs/kernel/d/uart.c
··· 1 + #include <kernel/d/uart.h> 2 + 3 + void uart_init(void) 4 + { 5 + volatile u8 *uart = (u8 *)UART_ADDR; 6 + 7 + uart[3] = 3; /* set word length to 8 */ 8 + uart[2] = 1; /* enable FIFO */ 9 + uart[1] = 1; /* enable receiver buffer interrupts */ 10 + 11 + /* TODO: set baud rate here. QEMU on virt does this 12 + automatically, but for bare metal we'll need to 13 + do it ourselves. */ 14 + } 15 + 16 + u8 uart_getr(void) 17 + { 18 + return *(u8 *)UART_ADDR; 19 + } 20 + 21 + u8 uart_getc(void) 22 + { 23 + u8 c = uart_getr(); 24 + *(u8 *)UART_ADDR = 0; 25 + return c; 26 + } 27 + 28 + void uart_putc(u8 c) 29 + { 30 + *(u8 *)UART_ADDR = c; 31 + } 32 + 33 + void uart_puts(char *s) 34 + { 35 + while (*s != '\0') 36 + { 37 + uart_putc(*s); 38 + s++; 39 + } 40 + } 41 + 42 + void uart_putd(int d) 43 + { 44 + if (d < 0) 45 + { 46 + uart_putc('-'); 47 + d = -d; 48 + } 49 + char buf[32] = {0}; 50 + int i = 0; 51 + while (d) 52 + { 53 + if (i > (int)sizeof(buf) - 1) 54 + break; /* prevent overflow */ 55 + buf[i++] = '0' + (d%10); 56 + d /= 10; 57 + } 58 + while (i) 59 + { 60 + uart_putc(buf[--i]); 61 + } 62 + } 63 + 64 + void uart_putx(unsigned int x) 65 + { 66 + uart_puts("0x"); 67 + char buf[32] = {0}; 68 + int i = 0; 69 + while (x) 70 + { 71 + if (i > (int)sizeof(buf) - 1) 72 + break; /* prevent overflow */ 73 + if (x%16 >= 10) 74 + buf[i++] = 'A' + (x%16)-10; 75 + else 76 + buf[i++] = '0' + (x%16); 77 + x /= 16; 78 + } 79 + while (i) 80 + { 81 + uart_putc(buf[--i]); 82 + } 83 + }
+18
srcs/kernel/d/uart.h
··· 1 + #ifndef __nkern_uart__ 2 + #define __nkern_uart__ 3 + 4 + #include <kernel/nint.h> 5 + 6 + #ifndef UART_ADDR 7 + # define UART_ADDR (0x10000000) 8 + #endif 9 + 10 + void uart_init(void); 11 + u8 uart_getr(void); /* raw get; does not clear UART */ 12 + u8 uart_getc(void); /* get character; clears UART */ 13 + void uart_putc(u8 c); 14 + void uart_puts(char *s); 15 + void uart_putd(int d); 16 + void uart_putx(unsigned int x); 17 + 18 + #endif
+34
srcs/kernel/main/entry.S
··· 1 + .section .init 2 + 3 + .option norvc 4 + 5 + .type start, @function 6 + .global start 7 + start: 8 + .cfi_startproc 9 + 10 + .option push 11 + .option norelax 12 + la gp, global_pointer 13 + .option pop 14 + 15 + csrw satp, zero /* reset satp */ 16 + 17 + la sp, stack_top /* setup stack */ 18 + 19 + /* clear bss */ 20 + la t5, bss_start 21 + la t6, bss_end 22 + bss_clear: 23 + sd zero, (t5) 24 + addi t5, t5, 8 25 + bltu t5, t6, bss_clear 26 + 27 + la t0, kmain 28 + csrw mepc, t0 29 + 30 + tail kmain /* jump to kernel */ 31 + 32 + .cfi_endproc 33 + 34 + .end
+17
srcs/kernel/main/kmain.c
··· 1 + #include <kernel/d/uart.h> 2 + #include <kernel/panic.h> 3 + #include <kernel/sys.h> 4 + #include <kernel/nsh.h> 5 + 6 + void kmain(void) 7 + { 8 + uart_init(); 9 + 10 + uart_puts("Hello, World!\r\n"); 11 + uart_putd(-42); uart_puts("\r\n"); 12 + uart_putx(0xB00B); uart_puts("\r\n"); 13 + 14 + nsh(); 15 + 16 + poweroff(); 17 + }
+31
srcs/kernel/main/linker.ld
··· 1 + ENTRY(start); 2 + 3 + . = 0x80000000; 4 + 5 + SECTIONS 6 + { 7 + /* entry.S at the start of the binary */ 8 + .text : ALIGN(4K) 9 + { 10 + *(.init); 11 + *(.text); 12 + } 13 + .bss : ALIGN(4K) 14 + { 15 + PROVIDE(bss_start = .); 16 + *(.bss); 17 + . += 4096; 18 + PROVIDE(stack_top = .); 19 + . += 4096; 20 + PROVIDE(global_pointer = .); 21 + PROVIDE(bss_end = .); 22 + } 23 + .rodata : ALIGN(4K) 24 + { 25 + *(.rodata); 26 + } 27 + .data : ALIGN(4K) 28 + { 29 + *(.data); 30 + } 31 + }
+20
srcs/kernel/mem.c
··· 1 + #include <kernel/mem.h> 2 + #include <kernel/nint.h> 3 + 4 + void *memcpy(void *dest, void *src, size_t n); 5 + 6 + void *memmove(void *dest, void *src, size_t n); 7 + 8 + void *memset(void *s, int c, size_t n) 9 + { 10 + u8 *ps = s; 11 + while (n) 12 + { 13 + *ps = c; 14 + ps++; 15 + n--; 16 + } 17 + return s; 18 + } 19 + 20 + int memcmp(void *s1, void *s2, size_t n);
+12
srcs/kernel/mem.h
··· 1 + #ifndef __nkern_mem__ 2 + #define __nkern_mem__ 3 + 4 + #include <kernel/nint.h> 5 + #include <stddef.h> 6 + 7 + void *memcpy(void *dest, void *src, size_t n); 8 + void *memmove(void *dest, void *src, size_t n); 9 + void *memset(void *s, int c, size_t n); 10 + int memcmp(void *s1, void *s2, size_t n); 11 + 12 + #endif
+16
srcs/kernel/nint.h
··· 1 + #ifndef __nlibc_nint__ 2 + #define __nlibc_nint__ 3 + 4 + #include <stdint.h> 5 + 6 + typedef int8_t i8; 7 + typedef int16_t i16; 8 + typedef int32_t i32; 9 + typedef int64_t i64; 10 + 11 + typedef uint8_t u8; 12 + typedef uint16_t u16; 13 + typedef uint32_t u32; 14 + typedef uint64_t u64; 15 + 16 + #endif
+62
srcs/kernel/nsh.c
··· 1 + #include <kernel/nsh.h> 2 + #include <kernel/d/uart.h> 3 + #include <kernel/mem.h> 4 + 5 + #define PROMPT "/ " 6 + 7 + static void nsh_exec(char *cmd) 8 + { 9 + uart_puts("-> "); 10 + uart_puts(cmd); 11 + uart_puts("\r\n"); 12 + } 13 + 14 + static int nsh_read(char *buf, int buflen) 15 + { 16 + static int i = 0; 17 + 18 + uart_puts(PROMPT); 19 + u8 ch = 0; 20 + while (1) 21 + { 22 + ch = uart_getc(); 23 + switch (ch) 24 + { 25 + case 13: /* enter */ 26 + uart_puts("\r\n"); 27 + nsh_exec(buf); 28 + memset(buf, 0, buflen - 1); 29 + i = 0; 30 + return 1; 31 + case 3: /* ctrl-c */ 32 + uart_puts("\r\n"); 33 + memset(buf, 0, buflen - 1); 34 + i = 0; 35 + return 1; 36 + case 4: /* ctrl-d */ 37 + uart_puts("\r\n"); 38 + return 0; 39 + default: 40 + buf[i++] = ch; 41 + uart_putc(ch); 42 + break; 43 + } 44 + } 45 + 46 + return 1; 47 + } 48 + 49 + void nsh(void) 50 + { 51 + #define BUFLEN (1024) 52 + char buf[BUFLEN]; 53 + memset(buf, 0, BUFLEN - 1); 54 + 55 + while (1) 56 + { 57 + if (!nsh_read(&buf[0], BUFLEN)) 58 + { 59 + break; 60 + } 61 + } 62 + }
+6
srcs/kernel/nsh.h
··· 1 + #ifndef __nkern_nsh__ 2 + #define __nkern_nsh__ 3 + 4 + void nsh(void); 5 + 6 + #endif
+10
srcs/kernel/panic.c
··· 1 + #include <kernel/panic.h> 2 + #include <kernel/d/uart.h> 3 + 4 + void panic(const char *msg) 5 + { 6 + uart_puts("nomad kernel panic:\r\n\""); 7 + uart_puts((char *)msg); 8 + uart_puts("\"\r\n"); 9 + asm volatile ("wfi"); 10 + }
+6
srcs/kernel/panic.h
··· 1 + #ifndef __nkern_panic__ 2 + #define __nkern_panic__ 3 + 4 + void panic(const char *msg); 5 + 6 + #endif
+14
srcs/kernel/sys.c
··· 1 + #include <kernel/sys.h> 2 + #include <kernel/d/uart.h> 3 + 4 + void poweroff(void) 5 + { 6 + uart_puts("poweroff requested\r\n"); 7 + *(u32 *)SYSCON_ADDR = 0x5555; 8 + } 9 + 10 + void reboot(void) 11 + { 12 + uart_puts("reboot requested\r\n"); 13 + *(u32 *)SYSCON_ADDR = 0x7777; 14 + }
+11
srcs/kernel/sys.h
··· 1 + #ifndef __nkern_sys__ 2 + #define __nkern_sys__ 3 + 4 + #ifndef SYSCON_ADDR 5 + # define SYSCON_ADDR (0x100000) 6 + #endif 7 + 8 + void poweroff(void); 9 + void reboot(void); 10 + 11 + #endif