summaryrefslogtreecommitdiff
path: root/kernel/x86
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/x86
parent09be8ace254a7f8bb69542d09a6b2013636123a2 (diff)
add x86 supportHEADmaster
Diffstat (limited to 'kernel/x86')
-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
4 files changed, 145 insertions, 0 deletions
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
+