diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | mainboard/virt/conf/mainboard.conf | 2 | ||||
-rw-r--r-- | sys/Makefile | 2 | ||||
-rw-r--r-- | sys/include/mm/kalloc.h | 4 | ||||
-rw-r--r-- | sys/include/printf.h (renamed from sys/include/kernel_earlyprintf.h) | 3 | ||||
-rw-r--r-- | sys/kern/entry.S | 8 | ||||
-rw-r--r-- | sys/kern/init.c | 17 | ||||
-rw-r--r-- | sys/kern/kernel_earlyprintf.c | 11 | ||||
-rw-r--r-- | sys/kern/mm/kalloc.c | 30 | ||||
-rw-r--r-- | sys/kern/printf.c | 85 |
10 files changed, 142 insertions, 22 deletions
@@ -1,7 +1,7 @@ TARGET?=virt CROSS_COMPILE?=riscv64-unknown-elf- GDB_PORT?=1234 -CFLAGS=-nostdlib -ffreestanding -mcmodel=medany -nostdinc -I${.CURDIR}/include +CFLAGS=-nostdlib -ffreestanding -mcmodel=medany -I${.CURDIR}/include .export sys: ${SRC} lib/build/libc.a diff --git a/mainboard/virt/conf/mainboard.conf b/mainboard/virt/conf/mainboard.conf index 77e8e2a..1812b3b 100644 --- a/mainboard/virt/conf/mainboard.conf +++ b/mainboard/virt/conf/mainboard.conf @@ -1,4 +1,4 @@ LOAD_ADDR=0x80200000 PAGE_SIZE=4096 -NPROC=1 +NPROC=2 DEBUG=qemu-system-riscv64 -nographic -machine virt -smp ${NPROC} -m 128M -bios default -gdb tcp::${GDB_PORT} -kernel diff --git a/sys/Makefile b/sys/Makefile index 865a5a3..db8bf8e 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -10,7 +10,7 @@ TARGETDIR=../mainboard/${TARGET} SRC=\ kern/entry.S\ kern/init.c\ - kern/kernel_earlyprintf.c\ + kern/printf.c\ kern/mm/kalloc.c\ dev/sbi.c diff --git a/sys/include/mm/kalloc.h b/sys/include/mm/kalloc.h index e99d624..10adbda 100644 --- a/sys/include/mm/kalloc.h +++ b/sys/include/mm/kalloc.h @@ -7,5 +7,9 @@ void *kzalloc(void); void kfree(void *); +void kalloc_init(void); + +void walkfree(void); + #endif /* _KALLOC_H */ diff --git a/sys/include/kernel_earlyprintf.h b/sys/include/printf.h index 051d7e5..76debc3 100644 --- a/sys/include/kernel_earlyprintf.h +++ b/sys/include/printf.h @@ -1,6 +1,7 @@ #ifndef _KPRINTF_H #define _KPRINTF_H -int kernel_earlyputs(const char *); +int puts(const char *); +void printf(const char *, ...); #endif /* _KPRINTF_H */ diff --git a/sys/kern/entry.S b/sys/kern/entry.S index 5ad0490..fccd80f 100644 --- a/sys/kern/entry.S +++ b/sys/kern/entry.S @@ -11,9 +11,10 @@ _start: la gp, __global_pointer$ .option pop - la sp, __stack_start + addi t0, a0, 1 li t1, PAGE_SIZE - mul t1, t1, a0 + la sp, __stack_start + mul t1, t1, t0 add sp, sp, t1 li a2, 1 @@ -37,3 +38,6 @@ _spin: .section ".data" _boot_hart: .word 0 +.section ".rodata" +.globl HEAP_START +HEAP_START: .dword __heap_start diff --git a/sys/kern/init.c b/sys/kern/init.c index a49c304..18feaa3 100644 --- a/sys/kern/init.c +++ b/sys/kern/init.c @@ -1,11 +1,20 @@ #include <fdt.h> -#include <kernel_earlyprintf.h> +#include <printf.h> +#include <stdint.h> +#include <mm/kalloc.h> + +extern uint64_t HEAP_START; void init(unsigned long hartid, struct fdt_header *fdt) { - kernel_earlyputs("booting...\n"); + printf("booting from hart #%d\n", hartid); if (fdt_uint32(fdt->magic) == FDT_HEADER_MAGIC) - kernel_earlyputs("found flattened device tree!\n"); - + printf("found flattened device tree at %p!\n", (uint64_t)fdt); + + printf("setting up the heap at %p\n", HEAP_START); + kalloc_init(); + printf("done!\n"); + printf("printing free pages:\n"); + walkfree(); } diff --git a/sys/kern/kernel_earlyprintf.c b/sys/kern/kernel_earlyprintf.c deleted file mode 100644 index e6c85c4..0000000 --- a/sys/kern/kernel_earlyprintf.c +++ /dev/null @@ -1,11 +0,0 @@ -#include <kernel_earlyprintf.h> -#include <sbi.h> - -int -kernel_earlyputs(const char *str) -{ - do { - sbi_console_putchar(*str); - } while (*(str++) != '\0'); -} - diff --git a/sys/kern/mm/kalloc.c b/sys/kern/mm/kalloc.c index b17d432..f354648 100644 --- a/sys/kern/mm/kalloc.c +++ b/sys/kern/mm/kalloc.c @@ -1,7 +1,11 @@ #include <stddef.h> +#include <stdint.h> #include <string.h> +#include <printf.h> #include <mm/kalloc.h> +extern uint64_t HEAP_START; + typedef struct freenode { struct freenode *next; } freenode_t; @@ -31,10 +35,34 @@ kzalloc(void) void kfree(void *p) { - if (p == NULL || (unsigned long)p % PAGE_SIZE) + if (p == NULL) return; freenode_t *tmp = head; head = p; head->next = tmp; } + +void +kalloc_init(void) +{ + printf("1\n"); + freenode_t *p = (freenode_t*)HEAP_START; + for (;(unsigned long)p + PAGE_SIZE <= (HEAP_START + 0x100000); p += PAGE_SIZE) { + printf("freeing page at %p", p); + kfree(p); + } +} + +void +walkfree(void) +{ + freenode_t *node = head; + int nfree = 0; + while (node) { + printf("freenode at %p\n", node); + node = node->next; + nfree++; + } + printf("found and printed %d free pages!\n", nfree); +} diff --git a/sys/kern/printf.c b/sys/kern/printf.c new file mode 100644 index 0000000..dfd0657 --- /dev/null +++ b/sys/kern/printf.c @@ -0,0 +1,85 @@ +#include <printf.h> +#include <stdint.h> +#include <sbi.h> +#include <stdarg.h> + +static char digits[] = "0123456789abcdef"; + +int +puts(const char *str) +{ + do { + sbi_console_putchar(*str); + } while (*(str++) != '\0'); +} + +#define PUTCHAR(c) sbi_console_putchar(c) + +static void +printint(int xx, int base, int sign) +{ + char buf[16]; + int i; + unsigned int x; + + if (sign && (sign = xx < 0)) + x = -xx; + else + x = xx; + + i = 0; + do { + buf[i++] = digits[x % base]; + } while ((x /= base) != 0); + + if (sign) + buf[i++] = '-'; + while (--i >= 0) + PUTCHAR(buf[i]); + +} + +static void +printptr(uint64_t x) +{ + int i; + puts("0x"); + for (i = 0; i < (sizeof(uint64_t) * 2); i++, x <<= 4) + PUTCHAR(digits[x >> (sizeof(int64_t) * 8 - 4)]); +} + +void +printf(const char *fmt, ...) +{ + va_list ap; + int i, c; + char *s; + + va_start(ap, fmt); + + for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { + if (c != '%') { + PUTCHAR(c); + continue; + } + c = fmt[++i] & 0xff; + if (!c) + break; + + switch (c) { + case 'd': + case 'i': + printint(va_arg(ap, int), 10, 1); + break; + case 'x': + printint(va_arg(ap, int), 16, 1); + break; + case 'p': + printptr(va_arg(ap, uint64_t)); + break; + case '%': + PUTCHAR('%'); + break; + } + } +} |