From bf2841b014ff363cfd93ee49c1df55a5277d3d5c Mon Sep 17 00:00:00 2001 From: Martin Petr Date: Thu, 20 Nov 2025 16:26:59 +0100 Subject: [PATCH] Add serial driver --- scripts/run-kernel.sh | 2 +- src/os/src/kernel/drivers/etc/serial.ts | 27 ++++++++++++++++ src/os/src/kernel/index.ts | 31 ++++++++++++++++++- .../kernel/modules/drivers/drivers.kmod.ts | 11 +++++++ 4 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/os/src/kernel/drivers/etc/serial.ts create mode 100644 src/os/src/kernel/modules/drivers/drivers.kmod.ts diff --git a/scripts/run-kernel.sh b/scripts/run-kernel.sh index 7f45ffd..35d9c56 100755 --- a/scripts/run-kernel.sh +++ b/scripts/run-kernel.sh @@ -1,3 +1,3 @@ ./scripts/build.sh -qemu-system-i386 -kernel "build/out/kernel" \ No newline at end of file +qemu-system-i386 -serial stdio -kernel "build/out/kernel" \ No newline at end of file diff --git a/src/os/src/kernel/drivers/etc/serial.ts b/src/os/src/kernel/drivers/etc/serial.ts new file mode 100644 index 0000000..4ef562d --- /dev/null +++ b/src/os/src/kernel/drivers/etc/serial.ts @@ -0,0 +1,27 @@ +import { portin, portout } from "../../../lib/libts/port"; + +const SERIAL_PORT_COM1 = 0x3f8; + +export function kdriver_etc_serial_init() { + portout(SERIAL_PORT_COM1 + 1, 0x00); // Disable all interrupts + portout(SERIAL_PORT_COM1 + 3, 0x80); // Enable DLAB + portout(SERIAL_PORT_COM1 + 0, 0x03); // 38400 baud + portout(SERIAL_PORT_COM1 + 1, 0x00); + portout(SERIAL_PORT_COM1 + 3, 0x03); // 8 bits, no parity, one stop bit + portout(SERIAL_PORT_COM1 + 2, 0xc7); // Enable FIFO, clear them, with 14-byte threshold + portout(SERIAL_PORT_COM1 + 4, 0x0b); +} + +export function kdriver_etc_serial_isTransmitBufferEmpty(): boolean { + return (portin(SERIAL_PORT_COM1 + 5) & 0x20) !== 0; +} + +export function kdriver_etc_serial_transmit(byte: number): void { + while (!kdriver_etc_serial_isTransmitBufferEmpty()) {} + + portout(SERIAL_PORT_COM1, byte); +} + +export function kdriver_etc_serial_read(): number { + return portin(SERIAL_PORT_COM1); +} diff --git a/src/os/src/kernel/index.ts b/src/os/src/kernel/index.ts index fc7dd6a..918d4ee 100644 --- a/src/os/src/kernel/index.ts +++ b/src/os/src/kernel/index.ts @@ -1,10 +1,39 @@ +import { charc } from "../lib/libts/byte"; +import { padStart } from "../lib/libts/string"; +import { getDate } from "../lib/sys/date"; +import { + kdriver_etc_serial_read, + kdriver_etc_serial_transmit, +} from "./drivers/etc/serial"; +import { + kmod_drivers_init, + kmod_drivers_register, +} from "./modules/drivers/drivers.kmod"; import { kmod_graphics_vga_clear, kmod_graphics_vga_init, kmod_graphics_vga_pushLine, -} from "./modules/graphics/vga"; +} from "./modules/graphics/graphics.kmod"; export function kmain() { + kmod_drivers_init(); + + kmod_drivers_register(); + + kdriver_etc_serial_transmit(charc("H")); + kdriver_etc_serial_transmit(charc("e")); + kdriver_etc_serial_transmit(charc("l")); + kdriver_etc_serial_transmit(charc("l")); + kdriver_etc_serial_transmit(charc("o")); + kmod_graphics_vga_init(); kmod_graphics_vga_pushLine("[Kernel] Kernel initialized successfully."); + kmod_graphics_vga_pushLine("Current date: " + getDate().toDateString()); + + while (true) { + const d = kdriver_etc_serial_read(); + kmod_graphics_vga_pushLine( + "Serial input: 0x" + padStart(d.toString(16), 2, "0") + ); + } } diff --git a/src/os/src/kernel/modules/drivers/drivers.kmod.ts b/src/os/src/kernel/modules/drivers/drivers.kmod.ts new file mode 100644 index 0000000..4b18b0e --- /dev/null +++ b/src/os/src/kernel/modules/drivers/drivers.kmod.ts @@ -0,0 +1,11 @@ +import { kdriver_etc_serial_init } from "../../drivers/etc/serial"; + +const drivers = [kdriver_etc_serial_init]; + +export function kmod_drivers_init(): void {} + +export function kmod_drivers_register(): void { + for (let i = 0; i < drivers.length; i++) { + drivers[i]!(); + } +}