commit 650c79ed1d1a5f16ff3ad46e4a32c1a75d608124 from: Murilo Ijanc date: Tue Jan 27 23:33:19 2026 UTC add serial and vga text output, print ALIVE on boot commit - c40788ab652e5648301786507982a694873230ff commit + 650c79ed1d1a5f16ff3ad46e4a32c1a75d608124 blob - 5f4ec049e82ced20821de85894efe224255e3790 blob + 1825aaae6f72bcd7762657fa9c98ad36c8adfb53 --- .cargo/config.toml +++ .cargo/config.toml @@ -1,2 +1,5 @@ [build] target = ["x86_64-unknown-none"] + +[target.x86_64-unknown-none] +rustflags = ["-C", "relocation-model=static"] blob - ea8c4bf7f35f6f77f75d92ad8ce8349f6e81ddba blob + f90dc2df8c995332109a36872b9e98cb433a197f --- .gitignore +++ .gitignore @@ -1 +1,4 @@ /target +/limine +/iso_root +*.iso blob - 76ef8853b9a6018a258a4674fd89a4c487ce98e7 blob + 21ac2ff11eee9b58a875b5347ecf8dd1d0a14a22 --- Makefile +++ Makefile @@ -1,19 +1,48 @@ -.PHONY: all check build build-release test fmt clippy lint doc clean install run +.PHONY: all build build-release run clean fmt clippy lint iso +KERNEL := target/x86_64-unknown-none/debug/omk +ISO := omk.iso +ISO_DIR := iso_root + all: run -check: - cargo check - build: cargo build build-release: - cargo build + cargo build --release -test: - cargo test +limine: + git clone https://github.com/limine-bootloader/limine.git \ + --branch=v8.x-binary --depth=1 + $(MAKE) -C limine +iso: build limine + rm -rf $(ISO_DIR) + mkdir -p $(ISO_DIR)/boot/limine $(ISO_DIR)/EFI/BOOT + cp $(KERNEL) $(ISO_DIR)/boot/kernel.elf + cp limine.conf $(ISO_DIR)/boot/limine/ + cp limine/limine-bios.sys $(ISO_DIR)/boot/limine/ + cp limine/limine-bios-cd.bin $(ISO_DIR)/boot/limine/ + cp limine/limine-uefi-cd.bin $(ISO_DIR)/boot/limine/ + cp limine/BOOTX64.EFI $(ISO_DIR)/EFI/BOOT/ + cp limine/BOOTIA32.EFI $(ISO_DIR)/EFI/BOOT/ + xorriso -as mkisofs -R \ + -b boot/limine/limine-bios-cd.bin \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + --efi-boot boot/limine/limine-uefi-cd.bin \ + -efi-boot-part --efi-boot-image --no-emul-boot \ + --protective-msdos-label \ + $(ISO_DIR) -o $(ISO) + ./limine/limine bios-install $(ISO) + +run: iso + qemu-system-x86_64 \ + -cdrom $(ISO) \ + -serial stdio \ + -no-reboot \ + -no-shutdown + fmt: cargo fmt @@ -24,14 +53,6 @@ lint: cargo fmt --check cargo clippy --all-features -- -D warnings -doc: - cargo doc - clean: cargo clean - -install: - cargo install --path . - -run: - cargo run + rm -rf $(ISO_DIR) $(ISO) blob - 1de38b2ec75bb3384096a12bc235782494d890f0 blob + 6399dd32f11fba63858dfb26ff9c73cbc3e9ae36 --- build.rs +++ build.rs @@ -17,6 +17,8 @@ fn main() { let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + println!("cargo:rustc-link-arg=--no-dynamic-linker"); + println!("cargo:rustc-link-arg=-static"); println!("cargo:rustc-link-arg=-Tlinker-{arch}.ld"); println!("cargo:rerun-if-changed=linker-{arch}.ld"); } blob - /dev/null blob + 3d1b299785984668ffa781ce54b781c5411277e0 (mode 644) --- /dev/null +++ limine.conf @@ -0,0 +1,6 @@ +timeout: 0 +serial: yes + +/Olivia MicroKernel (OMK) + protocol: limine + path: boot():/boot/kernel.elf blob - 79fda87a4d008e173cc879d522d7a9ce45cda1a1 blob + fb74be1776407495f4175388b8c3302e8a839e4e --- src/main.rs +++ src/main.rs @@ -18,6 +18,8 @@ #![no_std] #![no_main] +use core::arch::asm; + use limine::{BaseRevision, RequestsStartMarker, RequestsEndMarker}; #[used] @@ -30,6 +32,12 @@ pub static BASE_REVISION: BaseRevision = BaseRevision: #[unsafe(no_mangle)] pub unsafe extern "C" fn kmain() -> ! { + serial_init(); + serial_print("OMK: Olivia MicroKernel\n"); + serial_print("ALIVE\n"); + + vga_write("ALIVE", 0x0F); + loop {} } @@ -38,6 +46,61 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} } +const COM1: u16 = 0x3F8; + +unsafe fn outb(port: u16, val: u8) { + unsafe { + asm!("out dx, al", in("dx") port, in("al") val); + } +} + +unsafe fn inb(port: u16) -> u8 { + let val: u8; + unsafe { + asm!("in al, dx", out("al") val, in("dx") port); + } + val +} + +fn serial_init() { + unsafe { + outb(COM1 + 1, 0x00); + outb(COM1 + 3, 0x80); + outb(COM1 + 0, 0x03); + outb(COM1 + 1, 0x00); + outb(COM1 + 3, 0x03); + outb(COM1 + 2, 0xC7); + outb(COM1 + 4, 0x0B); + } +} + +fn serial_putc(c: u8) { + while unsafe { inb(COM1 + 5) } & 0x20 == 0 {} + unsafe { + outb(COM1, c); + } +} + +fn serial_print(s: &str) { + for b in s.bytes() { + if b == b'\n' { + serial_putc(b'\r'); + } + serial_putc(b); + } +} + +fn vga_write(s: &str, color: u8) { + let vga = 0xb8000 as *mut u16; + for (i, b) in s.bytes().enumerate() { + unsafe { + vga.add(i).write_volatile( + (color as u16) << 8 | b as u16 + ); + } + } +} + #[used] #[unsafe(link_section = ".requests_end")] pub static REQUEST_END: RequestsEndMarker = RequestsEndMarker::new();