summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorNathan Lee <me@nwlee.tech>2026-09-20 21:12:49 -0500
committerNathan Lee <me@nwlee.tech>2026-09-20 21:12:49 -0500
commit50e526d72f1fd9cb895d743a1353b54505b48025 (patch)
tree3442b2bd7b3b6ba6db3d972f89cf575ce1201278 /kernel
parent09be8ace254a7f8bb69542d09a6b2013636123a2 (diff)
add x86 supportHEADmaster
Diffstat (limited to 'kernel')
-rw-r--r--kernel/common/log.c10
-rw-r--r--kernel/riscv/kernel.c13
-rw-r--r--kernel/x86/kernel.c30
-rw-r--r--kernel/x86/linker.ld87
-rw-r--r--kernel/x86/start.S10
-rw-r--r--kernel/x86/uart.S18
6 files changed, 166 insertions, 2 deletions
diff --git a/kernel/common/log.c b/kernel/common/log.c
index f65c165..5f470f1 100644
--- a/kernel/common/log.c
+++ b/kernel/common/log.c
@@ -1,15 +1,21 @@
#include <sys/stddef.h>
#include <sys/log.h>
+void stub(char c) {
+ (void)c;
+}
+
__attribute__((section(".ringbuf"), aligned(64)))
volatile char log_ring[RINGBUF_SIZE];
static int pos = 0;
+static console_callback_t console_callback = stub;
void put_char(char c) {
log_ring[pos++] = c;
if (pos >= RINGBUF_SIZE)
pos = 0;
+ console_callback(c);
}
void put_string(const char *s) {
@@ -17,6 +23,10 @@ void put_string(const char *s) {
put_char(*s++);
}
+void register_console_callback(console_callback_t callback) {
+ console_callback = callback;
+}
+
void put_uint(unsigned int value, unsigned int radix) {
char tmp[16];
const char digits[] = "0123456789abcdef";
diff --git a/kernel/riscv/kernel.c b/kernel/riscv/kernel.c
index 46de696..e38134c 100644
--- a/kernel/riscv/kernel.c
+++ b/kernel/riscv/kernel.c
@@ -1,5 +1,4 @@
#include <sys/log.h>
-#include <sys/log.h>
#include <sys/mem.h>
#include <sys/cpio.h>
#include <early/dtb.h>
@@ -70,7 +69,7 @@ struct kernel_info *discover_arch(void *fdt) {
}
void kernel_main(size_t hart, void *fdt) {
- printk("wkern version %s (Compiler %s, Linker %s)\n", VERSION, COMPILER_NAME, LINKER_NAME);
+ printk("wkern version %s (Compiler %s, Linker %s) on %s\n", VERSION, COMPILER_NAME, LINKER_NAME, ARCH_NAME);
if (hart != 0)
return;
@@ -79,6 +78,16 @@ void kernel_main(size_t hart, void *fdt) {
if (!kernel_info) {
return;
}
+
+
+ uint8_t *bitmap = kemalloc(kernel_info->mem_size / (8 * PAGE_SIZE));
+ uintptr_t mem_start = (uintptr_t)kernel_info->mem_start;
+ uintptr_t initrd_start = (uintptr_t)kernel_info->initrd_start;
+ uintptr_t initrd_end = initrd_start + kernel_info->initrd_size;
+ for (; initrd_start <= initrd_end; initrd_start += PAGE_SIZE) {
+ uintptr_t offset = (initrd_start - mem_start) / PAGE_SIZE;
+ bitmap[offset / 8] = (uint8_t)(1u << (offset % 8));
+ }
}
void kernel_trap() {
diff --git a/kernel/x86/kernel.c b/kernel/x86/kernel.c
new file mode 100644
index 0000000..296d966
--- /dev/null
+++ b/kernel/x86/kernel.c
@@ -0,0 +1,30 @@
+#include <sys/stddef.h>
+#include <early/uart.h>
+#include <sys/log.h>
+
+#define COM1_PORT 0x3F8
+
+void serial_init(void) {
+ outb(COM1_PORT + 1, 0x00); // Disable interrupts
+ outb(COM1_PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
+ outb(COM1_PORT + 0, 0x01); // Set divisor to 1 (lo byte) -> 115200 baud
+ outb(COM1_PORT + 1, 0x00); // (hi byte)
+ outb(COM1_PORT + 3, 0x03); // 8 bits, no parity, one stop bit
+ outb(COM1_PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
+ outb(COM1_PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
+}
+
+static int serial_tx_ready(void) {
+ return inb(COM1_PORT + 5) & 0x20;
+}
+
+void serial_putchar(char c) {
+ while (serial_tx_ready() == 0);
+ outb(COM1_PORT, c);
+}
+
+void kernel_main(void) {
+ serial_init();
+ register_console_callback(serial_putchar);
+ printk("wkern version %s (Compiler %s, Linker %s) on %s\n", VERSION, COMPILER_NAME, LINKER_NAME, ARCH_NAME);
+}
diff --git a/kernel/x86/linker.ld b/kernel/x86/linker.ld
new file mode 100644
index 0000000..067d4e4
--- /dev/null
+++ b/kernel/x86/linker.ld
@@ -0,0 +1,87 @@
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+
+MEMORY
+{
+ ROM (rx) : ORIGIN = 0x1000000, LENGTH = 1M
+ RAM (rwx) : ORIGIN = 0x1040000, LENGTH = 1M
+ LOGRAM (rw) : ORIGIN = 0x1080000, LENGTH = 1M
+}
+
+SECTIONS
+{
+ .header : {
+ KEEP(*(.header))
+ *(.header)
+ } > ROM
+
+ .text : {
+ KEEP(*(.text._start))
+ KEEP(*(.text.start))
+ *(.text)
+ *(.text.*)
+ } > ROM
+
+ .rodata : {
+ *(.rodata)
+ *(.rodata.*)
+ } > ROM
+
+ .init_array : {
+ __init_array_start = .;
+ KEEP(*(.init_array))
+ KEEP(*(.init_array.*))
+ __init_array_end = .;
+ } > ROM
+
+ .data : {
+ __data_start = .;
+ *(.data)
+ *(.data.*)
+ __data_end = .;
+ } > RAM AT> ROM
+ __data_load = LOADADDR(.data);
+
+ .bss : {
+ __bss_start = .;
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ __bss_end = .;
+ } > RAM
+
+ .stack (NOLOAD) : {
+ . = ALIGN(16);
+ __stack_bottom = .;
+ . += 8K;
+ __stack_top = .;
+ } > RAM
+
+ .ringbuf (NOLOAD) : ALIGN(64)
+ {
+ __ringbuf_start = .;
+ KEEP(*(.ringbuf))
+ . = ALIGN(64);
+ __ringbuf_end = .;
+ } > LOGRAM
+
+ .image_end (NOLOAD) : {
+ . = ALIGN(4);
+ __image_end = .;
+ } > ROM
+
+ /DISCARD/ : {
+ *(.eh_frame)
+ *(.eh_frame.*)
+ *(.eh_frame_hdr)
+ *(.comment)
+ *(.note.*)
+ *(.debug_*)
+ *(.stab*)
+ *(.llvm_*)
+ *(.rela.*)
+ }
+
+ __image_start = ORIGIN(ROM);
+ __image_size = __image_end - __image_start;
+}
diff --git a/kernel/x86/start.S b/kernel/x86/start.S
new file mode 100644
index 0000000..779657c
--- /dev/null
+++ b/kernel/x86/start.S
@@ -0,0 +1,10 @@
+.section .text._start
+.global _start
+
+_start:
+ call kernel_main
+1:
+ cli
+ hlt
+ jmp 1b
+
diff --git a/kernel/x86/uart.S b/kernel/x86/uart.S
new file mode 100644
index 0000000..416fad2
--- /dev/null
+++ b/kernel/x86/uart.S
@@ -0,0 +1,18 @@
+.section .text
+
+.global outb
+.global inb
+
+# void outb(uint16_t port, uint8_t val)
+outb:
+ mov %dl, %al
+ mov %cx, %dx
+ outb %al, %dx
+ ret
+
+# uint8_t inb(uint16_t port)
+inb:
+ mov %cx, %dx
+ inb %dx, %al
+ ret
+