From 111d41d6106fa3609abf1660db7ec429ec4db555 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:39:49 +0200 Subject: [PATCH 01/16] Buddy bugfix --- kern/libkern/buddy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kern/libkern/buddy.c b/kern/libkern/buddy.c index 3b49bb0..36f1ff4 100644 --- a/kern/libkern/buddy.c +++ b/kern/libkern/buddy.c @@ -104,7 +104,7 @@ int buddy_free(void *ptr) { block_header_t *hdr = (block_header_t *)ptr - 1; int order = hdr->order; - assert_msg(order != MAX_ORDER, "The buddy freelist header seems to have been corrupted."); + assert_msg(order <= MAX_ORDER, "The buddy freelist header seems to have been corrupted."); uintptr_t addr = (uintptr_t)ptr; From 9d6c9a8bc5135da20a50cf326acf7939fd40ecfa Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:40:06 +0200 Subject: [PATCH 02/16] Initial RTC driver for google goldfish --- kern/rtc.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ kern/rtc.h | 14 ++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 kern/rtc.c create mode 100644 kern/rtc.h diff --git a/kern/rtc.c b/kern/rtc.c new file mode 100644 index 0000000..acc4c09 --- /dev/null +++ b/kern/rtc.c @@ -0,0 +1,51 @@ +#include + +#define VIRT_RTC_BASE 0x0101000UL +#define VIRT_RTC_SIZE 0x1000 + +#define RTC_TIME_LOW 0x00 +#define RTC_TIME_HIGH 0x04 +#define RTC_ALARM_LOW 0x08 +#define RTC_ALARM_HIGH 0x0c + +#define RTC_IRQ_ENABLED 0x10 +#define RTC_CLEAR_ALARM 0x14 +#define RTC_ALARM_STATUS 0x18 +#define RTC_CLEAR_INTERRUPT 0x1c + +static inline uint32_t mmio_read32(uintptr_t addr) { + return *(volatile uint32_t *)addr; +} + +static inline void mmio_write32(uintptr_t addr, uint32_t value) { + *(volatile uint32_t *)addr = value; +} + +uint64_t rtc_read_time(void) { + uint32_t low = mmio_read32(VIRT_RTC_BASE + RTC_TIME_LOW); + uint32_t high = mmio_read32(VIRT_RTC_BASE + RTC_TIME_HIGH); + return ((uint64_t)high << 32) | low; +} + +void rtc_alarm_set(uint64_t ns) { + mmio_write32(VIRT_RTC_BASE + RTC_ALARM_HIGH, ns >> 32); + mmio_write32(VIRT_RTC_BASE + RTC_ALARM_LOW, ns & 0xffffffff); +} + +uint64_t rtc_alarm_read(void) { + uint32_t low = mmio_read32(VIRT_RTC_BASE + RTC_ALARM_LOW); + uint32_t high = mmio_read32(VIRT_RTC_BASE + RTC_ALARM_HIGH); + return ((uint64_t)high << 32) | low; +} + +void rtc_alarm_enable(void) { + mmio_write32(VIRT_RTC_BASE + RTC_IRQ_ENABLED, 1); +} + +void rtc_alarm_disable(void) { + mmio_write32(VIRT_RTC_BASE + RTC_IRQ_ENABLED, 0); +} + +uint32_t rtc_alarm_status(void) { + return mmio_read32(VIRT_RTC_BASE + RTC_IRQ_ENABLED); +} diff --git a/kern/rtc.h b/kern/rtc.h new file mode 100644 index 0000000..656cf04 --- /dev/null +++ b/kern/rtc.h @@ -0,0 +1,14 @@ +#ifndef RTC_H +#define RTC_H + +#include + +uint64_t rtc_read_time(void); + +void rtc_alarm_set(uint64_t ns); +uint64_t rtc_alarm_read(void); +void rtc_alarm_enable(void); +void rtc_alarm_disable(void); +uint32_t rtc_alarm_status(void); + +#endif // RTC_H From 2fd62c52b47bf1ce07184f48da0e84bc934ef493 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:40:30 +0200 Subject: [PATCH 03/16] Replace __sync compiler intrinsics with 'modern' __atomic --- kern/start.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kern/start.c b/kern/start.c index 7d0e855..a8175c2 100644 --- a/kern/start.c +++ b/kern/start.c @@ -30,8 +30,7 @@ volatile int max_hart = 0; /* This is where entry.S drops us of. All cores land here */ void start() { // Do this first - __sync_fetch_and_add(&max_hart, 1); - __sync_synchronize(); + __atomic_fetch_add(&max_hart, 1, __ATOMIC_SEQ_CST); u64 id = read_mhartid(); From 6a2c1f4ea9c9b348a9f83d5175b1096cea427576 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:40:43 +0200 Subject: [PATCH 04/16] Include rtc in build --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index b316fc2..0a270a7 100644 --- a/Makefile +++ b/Makefile @@ -55,6 +55,7 @@ quickstart: KERNEL_OBJ := \ kern/entry.o \ kern/start.o \ + kern/rtc.o \ kern/libkern/freelist.o \ kern/libkern/string.o \ kern/libkern/proc.o \ From 6c3d50b6a5b8a319f44a13d4b2e85e6be9f07f0d Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:40:50 +0200 Subject: [PATCH 05/16] Allow unused for now --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 0a270a7..29aa115 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,7 @@ LDFLAGS += -m elf64lriscv CFLAGS = -Wall -Werror -O CFLAGS += -Wno-unused-result +CFLAGS += -Wno-unused-variable CFLAGS += -mcmodel=medany CFLAGS += -march=rv64gc -mabi=lp64 CFLAGS += -ffreestanding From 0dbb13fea09407c516e7a3a2f68b287d1316a7ab Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:41:09 +0200 Subject: [PATCH 06/16] Extend badrand with badrand_buf --- kern/libkern/badrand.c | 19 ++++++++++++++++++- kern/libkern/badrand.h | 5 +++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/kern/libkern/badrand.c b/kern/libkern/badrand.c index 48df698..f7c06f8 100644 --- a/kern/libkern/badrand.c +++ b/kern/libkern/badrand.c @@ -1,5 +1,6 @@ #include "badrand.h" #include +#include #define PRAND_BUILD_SEED \ ((uint64_t)(__TIME__[0]) * (uint64_t)(__TIME__[1]) * (uint64_t)(__TIME__[3]) * (uint64_t)(__TIME__[4]) * \ @@ -24,7 +25,23 @@ uint64_t badrand_range(uint64_t min, uint64_t max) { return min + (x % range); } -void sbadprand(uint64_t s) { +void badrand_buf(char *buf, size_t len) { + unsigned char *p = (unsigned char *)buf; + + while (len >= 8) { + uint64_t r = badrand(); + memcpy(p, &r, 8); + p += 8; + len -= 8; + } + + if (len > 0) { + uint64_t r = badrand(); + memcpy(p, &r, len); + } +} + +void sbadrand(uint64_t s) { if (s) { seed ^= (s * 0x9e3779b97f4a7c15ULL) + (seed << 6) + (seed >> 2); } else { diff --git a/kern/libkern/badrand.h b/kern/libkern/badrand.h index 8a0ab9c..6710b89 100644 --- a/kern/libkern/badrand.h +++ b/kern/libkern/badrand.h @@ -40,4 +40,9 @@ uint64_t badrand(); */ uint64_t badrand_range(uint64_t min, uint64_t max); +/** + * @brief Fills buffer with random data + */ +void badrand_buf(char *buf, size_t len); + #endif // BADRAND_H From 802ac9c012f4ebe06276cf11c8702caa831af1aa Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:42:45 +0200 Subject: [PATCH 07/16] Seed badrand with an rtc read xored with itself (its called BADrand for a reason) --- kern/start.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kern/start.c b/kern/start.c index a8175c2..7847e84 100644 --- a/kern/start.c +++ b/kern/start.c @@ -1,3 +1,4 @@ +#include "badrand.h" #include #include #include @@ -45,6 +46,7 @@ void start() { memory_sweep(heap_start, heap_end); buddy_init(heap_start, heap_end); spinlock_init(&sl); + sbadrand(rtc_read_time() ^ swap64(rtc_read_time())); for (int i = 0; i < banner_len; i++) uart_putc(banner[i]); __sync_synchronize(); hold = 0; From f4342ab221b52c5dadae39c7b76212ef432afc8b Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:48:03 +0200 Subject: [PATCH 08/16] ctype.h: include isprint --- kern/libkern/ctype.h | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 kern/libkern/ctype.h diff --git a/kern/libkern/ctype.h b/kern/libkern/ctype.h new file mode 100644 index 0000000..56ebbed --- /dev/null +++ b/kern/libkern/ctype.h @@ -0,0 +1,8 @@ +#ifndef CTYPE_H +#define CTYPE_H + +static inline int isprint(int c) { + return (unsigned)c - 0x20 < 0x5f; +} + +#endif // CTYPE_H From 1ed4b5788204ebbbde9b8b089b2991de7563a353 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:48:32 +0200 Subject: [PATCH 09/16] hexdump.[ch]: utility function for dumping memory regions as hex --- Makefile | 3 ++- kern/libkern/hexdump.c | 34 ++++++++++++++++++++++++++++++++++ kern/libkern/hexdump.h | 8 ++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 kern/libkern/hexdump.c create mode 100644 kern/libkern/hexdump.h diff --git a/Makefile b/Makefile index 29aa115..5622f00 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,8 @@ KERNEL_OBJ := \ kern/libkern/mini-printf.o \ kern/libkern/stdio.o \ kern/libkern/buddy.o \ - kern/libkern/badrand.o + kern/libkern/badrand.o \ + kern/libkern/hexdump.o kern/kernel.elf: $(KERNEL_OBJ) @echo LD $@ diff --git a/kern/libkern/hexdump.c b/kern/libkern/hexdump.c new file mode 100644 index 0000000..772095c --- /dev/null +++ b/kern/libkern/hexdump.c @@ -0,0 +1,34 @@ +#include +#include +#include + +void hexdump(const void *data, size_t size) { + const unsigned char *p = (const unsigned char *)data; + size_t i, j; + + for (i = 0; i < size; i += 16) { + // Print offset + kprintf("%08zx ", i); + + // Print hex bytes + for (j = 0; j < 16; j++) { + if (i + j < size) { + kprintf("%02X ", p[i + j]); + } else { + kprintf(" "); // padding for incomplete lines + } + if (j == 7) + kprintf(" "); // extra space in middle + } + + kprintf(" |"); + + // Print ASCII characters + for (j = 0; j < 16 && i + j < size; j++) { + unsigned char c = p[i + j]; + kprintf("%c", isprint(c) ? c : '.'); + } + + kprintf("|\n"); + } +} diff --git a/kern/libkern/hexdump.h b/kern/libkern/hexdump.h new file mode 100644 index 0000000..d01a907 --- /dev/null +++ b/kern/libkern/hexdump.h @@ -0,0 +1,8 @@ +#ifndef HEXDUMP_H +#define HEXDUMP_H + +#include + +void hexdump(const void *data, size_t size); + +#endif // HEXDUMP_H From 795cf84a07dfc21c403e6aaab2826ee799c275a4 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:51:37 +0200 Subject: [PATCH 10/16] Fix format specifier that doesnt exist in neptune --- kern/libkern/hexdump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kern/libkern/hexdump.c b/kern/libkern/hexdump.c index 772095c..6eaa377 100644 --- a/kern/libkern/hexdump.c +++ b/kern/libkern/hexdump.c @@ -8,7 +8,7 @@ void hexdump(const void *data, size_t size) { for (i = 0; i < size; i += 16) { // Print offset - kprintf("%08zx ", i); + kprintf("%08x ", i); // Print hex bytes for (j = 0; j < 16; j++) { From cc24fb66eba250b765e4d012cf4fdc8b00dc1fd4 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:52:20 +0200 Subject: [PATCH 11/16] Test hexdump in start.c --- kern/start.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kern/start.c b/kern/start.c index 7847e84..0e42fdd 100644 --- a/kern/start.c +++ b/kern/start.c @@ -1,4 +1,5 @@ -#include "badrand.h" +#include +#include #include #include #include @@ -79,6 +80,11 @@ void start() { buddy_free(mem); } + { + char buffer[128]; + badrand_buf(buffer, 128); + hexdump(buffer, 128); + } kprintf("To exit qemu, press CTRL+a followed by x\n"); spin_unlock(&sl); From f6e543b64dbea75facac955369a9dc2d733c29e7 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:53:03 +0200 Subject: [PATCH 12/16] Free the freelist allocation in start.c test, better logging messages --- kern/start.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kern/start.c b/kern/start.c index 0e42fdd..3c9f0ba 100644 --- a/kern/start.c +++ b/kern/start.c @@ -70,13 +70,13 @@ void start() { fl_init(&fl, (uintptr_t)mem, 4096, sizeof(int)); uint32_t *hello = fl_alloc(&fl); - *hello = UINT32_MAX; + fl_free(&fl, hello); int a = fl_available(&fl); assert_msg(fl_check(&fl) > 0, "FreeList checking failed, might be corrupt."); - kprintf("Available: %d\n", a); - kprintf("Size: %d\n", fl.size); + kprintf("Freelist available: %d\n", a); + kprintf("Freelist item size: %d\n", fl.size); buddy_free(mem); } From 8d8ad077ce89f235d37c7872ae869874707882b6 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:53:13 +0200 Subject: [PATCH 13/16] Include rtc... --- kern/start.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kern/start.c b/kern/start.c index 3c9f0ba..ac0bcd2 100644 --- a/kern/start.c +++ b/kern/start.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include From 2223a42488b3d941ed96549e7e914cb8d612f83b Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:53:33 +0200 Subject: [PATCH 14/16] Test rtc in main --- kern/start.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kern/start.c b/kern/start.c index ac0bcd2..87e0558 100644 --- a/kern/start.c +++ b/kern/start.c @@ -81,6 +81,18 @@ void start() { buddy_free(mem); } + { + uint64_t time = rtc_read_time(); + time = rtc_read_time(); + rtc_alarm_set(time + 3000000000); + uint64_t alrm = rtc_alarm_read(); + assert(alrm > time); + uint32_t astatus = rtc_alarm_status(); + assert(astatus == 0); + rtc_alarm_enable(); + astatus = rtc_alarm_status(); + assert(astatus == 1); + } { char buffer[128]; badrand_buf(buffer, 128); From 65d7cfe5846c8b36164927062b49e72e73d2fe80 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:53:40 +0200 Subject: [PATCH 15/16] Test badrand in start.c --- kern/start.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kern/start.c b/kern/start.c index 87e0558..9778dd9 100644 --- a/kern/start.c +++ b/kern/start.c @@ -93,6 +93,10 @@ void start() { astatus = rtc_alarm_status(); assert(astatus == 1); } + { + uint64_t rn = badrand(); + assert(rn != badrand()); + } { char buffer[128]; badrand_buf(buffer, 128); From cea6d7505f9494e7c10362bdc428a8b92178a762 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 1 Oct 2025 02:54:15 +0200 Subject: [PATCH 16/16] Include endian.h --- kern/start.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kern/start.c b/kern/start.c index 9778dd9..38f2922 100644 --- a/kern/start.c +++ b/kern/start.c @@ -1,3 +1,4 @@ +#include #include #include #include