diff options
| author | Nathan Lee <me@nwlee.tech> | 2026-09-20 21:12:49 -0500 |
|---|---|---|
| committer | Nathan Lee <me@nwlee.tech> | 2026-09-20 21:12:49 -0500 |
| commit | 50e526d72f1fd9cb895d743a1353b54505b48025 (patch) | |
| tree | 3442b2bd7b3b6ba6db3d972f89cf575ce1201278 /kernel/x86 | |
| parent | 09be8ace254a7f8bb69542d09a6b2013636123a2 (diff) | |
Diffstat (limited to 'kernel/x86')
| -rw-r--r-- | kernel/x86/kernel.c | 30 | ||||
| -rw-r--r-- | kernel/x86/linker.ld | 87 | ||||
| -rw-r--r-- | kernel/x86/start.S | 10 | ||||
| -rw-r--r-- | kernel/x86/uart.S | 18 |
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 + |
