From ce79dd7873468b012834d57a9ec44aea0352fe30 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 10:40:19 +0200 Subject: [PATCH 01/13] Add limine conf --- tmp/boot/limine/limine.conf | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tmp/boot/limine/limine.conf diff --git a/tmp/boot/limine/limine.conf b/tmp/boot/limine/limine.conf new file mode 100644 index 000000000..71aeeda32 --- /dev/null +++ b/tmp/boot/limine/limine.conf @@ -0,0 +1,7 @@ +timeout: 0 +interface_resolution: 640x480 + +/MOROS + protocol: limine + resolution: 640x480x32 + kernel_path: boot():/kernel.elf From f6eb3e3ba7849c4881bc7cae5d9f2cd0d560427f Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 10:41:10 +0200 Subject: [PATCH 02/13] Add limine setup --- Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile b/Makefile index f48154970..a4ce3c8b9 100644 --- a/Makefile +++ b/Makefile @@ -115,6 +115,14 @@ test: -m $(memory) -cpu core2duo -display none -serial stdio \ -device isa-debug-exit,iobase=0xF4,iosize=0x04 +# Require llvm lld mtools +limine-setup: + cd tmp + wget https://github.com/Limine-Bootloader/Limine/releases/download/v11.3.1/limine-11.3.1.tar.gz + cd limine-* + ./configure --enable-bios --enable-bios-cd + make + website: cd www && sh build.sh From 58100b149ef546a79b64ba2477dd3484c62fc146 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 10:43:56 +0200 Subject: [PATCH 03/13] Add limine bios files --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a4ce3c8b9..46ebd7d43 100644 --- a/Makefile +++ b/Makefile @@ -119,9 +119,12 @@ test: limine-setup: cd tmp wget https://github.com/Limine-Bootloader/Limine/releases/download/v11.3.1/limine-11.3.1.tar.gz - cd limine-* + cd limine-11.3.1 ./configure --enable-bios --enable-bios-cd make + cd .. + cp limine-11.3.1/bin/limine-bios-cd.bin boot/limine/ + cp limine-11.3.1/bin/limine-bios.sys boot/limine/ website: cd www && sh build.sh From 96b5edcf37c34b693bcffae37d72b9c7d53bfc78 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 10:45:02 +0200 Subject: [PATCH 04/13] Add limine image building to makefile --- Makefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Makefile b/Makefile index 46ebd7d43..d898fb4ce 100644 --- a/Makefile +++ b/Makefile @@ -126,6 +126,18 @@ limine-setup: cp limine-11.3.1/bin/limine-bios-cd.bin boot/limine/ cp limine-11.3.1/bin/limine-bios.sys boot/limine/ +limine-image: RUSTFLAGS = -C link-arg=-Ttmp/boot/linker.ld -C link-arg=-z -C link-arg=norelro +limine-image: + cargo build --release --features limine + cp target/x86_64-moros/release/moros tmp/boot/kernel.elf + find tmp/boot + cat tmp/boot/limine/limine.conf + xorriso -as mkisofs \ + -b limine/limine-bios-cd.bin \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + --protective-msdos-label \ + tmp/boot -o boot.img + website: cd www && sh build.sh From 8b119fa8143d96d52da3db62837095c7d72f53e4 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 10:45:19 +0200 Subject: [PATCH 05/13] Add limine crate --- Cargo.lock | 7 +++++++ Cargo.toml | 2 ++ 2 files changed, 9 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index ba66d4f9b..4a3929776 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -297,6 +297,12 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +[[package]] +name = "limine" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90b240f611eba0b43bf3e97478d87f12322c6c0f540bdad885c3e8c4a0d57333" + [[package]] name = "linked_list_allocator" version = "0.10.6" @@ -370,6 +376,7 @@ dependencies = [ "geodate", "lazy_static", "libm", + "limine", "linked_list_allocator", "littlewing", "miniz_oxide", diff --git a/Cargo.toml b/Cargo.toml index a5df4fa6f..69a02a623 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ default = ["video"] video = [] serial = [] userspace = [] +limine = [] [dependencies] acpi = "5.0.0" @@ -25,6 +26,7 @@ chumsky = { version = "0.12.0", default-features = false } geodate = { version = "0.5.0", default-features = false } lazy_static = { version = "1.5.0", features = ["spin_no_std"] } libm = "0.2.16" +limine = "0.6.3" linked_list_allocator = "0.10.6" littlewing = { version = "0.8.0", default-features = false } miniz_oxide = "0.9.1" From 61f99c76f2fc6e9bb941c2bdcecce807f13a2dad Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 10:46:27 +0200 Subject: [PATCH 06/13] Add limine start --- src/main.rs | 101 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 21 deletions(-) diff --git a/src/main.rs b/src/main.rs index b793b1d06..6f4c35dc0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,6 @@ extern crate alloc; -use bootloader::{entry_point, BootInfo}; use core::panic::PanicInfo; use alloc::string::ToString; use moros::api::console::Style; @@ -11,12 +10,76 @@ use moros::{ error, warning, hlt_loop, eprint, eprintln, print, println, sys, usr }; -entry_point!(main); +#[cfg(not(feature = "limine"))] +mod bootloader_boot { + use super::*; + use bootloader::{entry_point, BootInfo}; -fn main(boot_info: &'static BootInfo) -> ! { - let memory_map = moros::extract_memory_map(boot_info); - let offset = boot_info.physical_memory_offset; - moros::init(&memory_map, offset); + entry_point!(main); + + fn main(boot_info: &'static BootInfo) -> ! { + let memory_map = moros::extract_memory_map(boot_info); + let offset = boot_info.physical_memory_offset; + moros::init(&memory_map, offset); + exec(); + } +} + +#[cfg(feature = "limine")] +mod limine_boot { + use super::*; + + use moros::sys::mem::MemoryMap; + use moros::sys::mem::MemoryRegion; + use moros::sys::mem::MemoryRegionType; + use limine::request::{MemmapRequest, HhdmRequest, FramebufferRequest}; + use limine::{BaseRevision, RequestsStartMarker, RequestsEndMarker}; + use limine::memmap; + + #[used] + #[link_section = ".limine_reqs"] + static BASE_REVISION: BaseRevision = BaseRevision::new(); + + #[used] + #[link_section = ".limine_req_start"] + static REQUESTS_START: RequestsStartMarker = RequestsStartMarker::new(); + + #[used] + #[link_section = ".limine_reqs"] + static MEMMAP_REQUEST: MemmapRequest = MemmapRequest::new(); + + #[used] + #[link_section = ".limine_reqs"] + static HHDM_REQUEST: HhdmRequest = HhdmRequest::new(); + + #[used] + #[link_section = ".limine_reqs"] + static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new(); + + #[used] + #[link_section = ".limine_req_end"] + static REQUESTS_END: RequestsEndMarker = RequestsEndMarker::new(); + + #[no_mangle] + extern "C" fn _start() -> ! { + let hhdm = HHDM_REQUEST.response().unwrap(); + let memmap = MEMMAP_REQUEST.response().unwrap(); + + let mut memory_map = MemoryMap::new(); + for entry in memmap.entries() { + let kind = match entry.type_ { + memmap::MEMMAP_USABLE => MemoryRegionType::Usable, + _ => MemoryRegionType::Reserved, + }; + memory_map.add(MemoryRegion::new(entry.base, entry.length, kind)); + } + + moros::init(&memory_map, hhdm.offset); + exec(); + } +} + +pub fn exec() -> ! { print!("\x1b[?25h"); // Enable cursor loop { if let Some(cmd) = option_env!("MOROS_CMD") { @@ -25,22 +88,18 @@ fn main(boot_info: &'static BootInfo) -> ! { usr::shell::exec(cmd).ok(); sys::acpi::shutdown(); } else { - user_boot(); - } - } -} - -fn user_boot() { - let script = "/ini/boot.sh"; - if sys::fs::File::open(script).is_some() { - usr::shell::main(&["shell", script]).ok(); - } else { - if sys::fs::is_mounted() { - error!("Could not find '{}'", script); - } else { - warning!("MFS not found, run 'install' to setup the system"); + let script = "/ini/boot.sh"; + if sys::fs::File::open(script).is_some() { + usr::shell::main(&["shell", script]).ok(); + } else { + if sys::fs::is_mounted() { + error!("Could not find '{}'", script); + } else { + warning!("MFS not found, run 'install' to setup the system"); + } + usr::shell::main(&["shell"]).ok(); + } } - usr::shell::main(&["shell"]).ok(); } } From e19d2edb18e065c55bc2b061f850f39cc5b81c0f Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 10:47:04 +0200 Subject: [PATCH 07/13] Set VGA text mode during init --- src/sys/vga/mod.rs | 7 +------ src/sys/vga/screen.rs | 11 +++++++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/sys/vga/mod.rs b/src/sys/vga/mod.rs index 5b425afb1..dc0bd2590 100644 --- a/src/sys/vga/mod.rs +++ b/src/sys/vga/mod.rs @@ -132,10 +132,5 @@ pub fn init() { set_attr_ctrl_reg(0xE, 0x3E); set_attr_ctrl_reg(0xF, 0x3F); - //Palette::default().write(); - - disable_blinking(); - disable_underline(); - - WRITER.lock().clear_screen(); + screen::set_80x25_mode(); } diff --git a/src/sys/vga/screen.rs b/src/sys/vga/screen.rs index de53b04a2..5c34e4c29 100644 --- a/src/sys/vga/screen.rs +++ b/src/sys/vga/screen.rs @@ -78,7 +78,7 @@ fn set_mode(mode: ModeName) { ModeName::T80x25 => T_80_25, ModeName::G320x200x256 => G_320_200_256, ModeName::G640x480x16 => G_640_480_16, - }.to_vec(); + }; interrupts::without_interrupts(|| { let mut misc_write: Port = Port::new(MISC_WRITE_REG); @@ -149,13 +149,16 @@ fn is_80x25_mode() -> bool { } } -fn set_80x25_mode() { +pub fn set_80x25_mode() { + let restorable = MODE.lock().is_some(); clear_screen(); set_mode(ModeName::T80x25); disable_blinking(); disable_underline(); - palette::restore_palette(); - font::restore_font(); + if restorable { + palette::restore_palette(); + font::restore_font(); + } } fn set_320x200_mode() { From 76edbc58735d4200f5326eb2b662bbafb174c91a Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 10:47:36 +0200 Subject: [PATCH 08/13] Add limine qemu to makefile --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d898fb4ce..acfcc43a4 100644 --- a/Makefile +++ b/Makefile @@ -72,7 +72,7 @@ image: $(img) dd conv=notrunc if=$(bin) of=$(img) qemu-opts = -name "MOROS $$MOROS_VERSION" \ - -m $(memory) -smp $(smp) -drive file=$(img),format=raw \ + -m $(memory) -smp $(smp) \ -audiodev $(audio),id=a0 -machine pcspk-audiodev=a0 \ -audio driver=$(audio),model=$(snd) \ -netdev user,id=e0,hostfwd=tcp::8080-:80 -device $(nic),netdev=e0 @@ -108,7 +108,7 @@ endif # > gdb target/x86_64-moros/debug/moros -ex "target remote :1234" qemu: - qemu-system-x86_64 $(qemu-opts) + qemu-system-x86_64 $(qemu-opts) -hda $(img) test: cargo test --release --lib --no-default-features --features serial -- \ @@ -138,6 +138,9 @@ limine-image: --protective-msdos-label \ tmp/boot -o boot.img +limine-qemu: + qemu-system-x86_64 -cdrom boot.img $(qemu-opts) + website: cd www && sh build.sh From 8eed6d5b4d044c32c262dc2954c9a0b678b84300 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 10:47:50 +0200 Subject: [PATCH 09/13] Add debug to init --- src/lib.rs | 1 + src/main.rs | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 4617c4e37..54f774a46 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,7 @@ pub fn init(memory_map: &MemoryMap, offset: u64) { sys::pic::init(); // Enable interrupts sys::serial::init(); sys::keyboard::init(); + return; // FIXME sys::clk::init(); let v = option_env!("MOROS_VERSION").unwrap_or(env!("CARGO_PKG_VERSION")); diff --git a/src/main.rs b/src/main.rs index 6f4c35dc0..18be35eeb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,6 +62,16 @@ mod limine_boot { #[no_mangle] extern "C" fn _start() -> ! { + if let Some(res) = FRAMEBUFFER_REQUEST.response() { + if let Some(fb) = res.framebuffers().first() { + let ptr = fb.address() as *mut u32; + let n = 10 * fb.width as usize; + for i in 0..n { + unsafe { *ptr.add(i) = 0x00FF00FF; } // Draw pink pixel + } + } + } + let hhdm = HHDM_REQUEST.response().unwrap(); let memmap = MEMMAP_REQUEST.response().unwrap(); @@ -75,6 +85,18 @@ mod limine_boot { } moros::init(&memory_map, hhdm.offset); + + if let Some(res) = FRAMEBUFFER_REQUEST.response() { + if let Some(fb) = res.framebuffers().first() { + let ptr = fb.address() as *mut u32; + let n = 10 * fb.width as usize; + for i in n..(2 * n) { + unsafe { *ptr.add(i) = 0x0000FFFF; } // Draw cyan pixel + } + } + } + + hlt_loop(); exec(); } } From 06f4893de5023fb5bbc067a53ef3871aa0f5014c Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 10:58:17 +0200 Subject: [PATCH 10/13] Fix tests --- src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 54f774a46..33ae1963c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,7 +31,10 @@ pub fn init(memory_map: &MemoryMap, offset: u64) { sys::pic::init(); // Enable interrupts sys::serial::init(); sys::keyboard::init(); + + #[cfg(feature = "limine")] return; // FIXME + sys::clk::init(); let v = option_env!("MOROS_VERSION").unwrap_or(env!("CARGO_PKG_VERSION")); From 458830e7dc2b87791956bee4b17d51fac56553a1 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 11:03:22 +0200 Subject: [PATCH 11/13] Add missing linker --- tmp/boot/linker.ld | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tmp/boot/linker.ld diff --git a/tmp/boot/linker.ld b/tmp/boot/linker.ld new file mode 100644 index 000000000..e917e4635 --- /dev/null +++ b/tmp/boot/linker.ld @@ -0,0 +1,24 @@ +KERNEL_OFFSET = 0xFFFFFFFF80000000; + +SECTIONS { + . = KERNEL_OFFSET; + + .text : { *(.text .text.*) } + . = ALIGN(4096); + + .rodata : { *(.rodata .rodata.*) } + . = ALIGN(4096); + + .data : { + *(.data .data.*) + KEEP(*(.limine_req_start)) + KEEP(*(.limine_reqs)) + KEEP(*(.limine_req_end)) + } + . = ALIGN(4096); + + .bss : { *(.bss .bss.*) *(COMMON) } + . = ALIGN(4096); + + /DISCARD/ : { *(.eh_frame*) *(.note*) *(.comment*) } +} From 64e4769bfeb4ff797720fb30a96b622e750d5d3d Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 11:20:28 +0200 Subject: [PATCH 12/13] Use cargo-opts in makefile --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index acfcc43a4..47201d14a 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ user-nasm: sh -c "printf '\x7FBIN' | cat - dsk/bin/{}.tmp > dsk/bin/{}" rm dsk/bin/*.tmp -user-cargo-opts = --no-default-features --features userspace --release +user-cargo-opts = --release --no-default-features --features userspace # FIXME: Userspace alloc panic when the default `lld` linker is used because it # sets the entry point 0x200000 which is used by the kernel, so we use `ld` to @@ -59,10 +59,11 @@ img = disk.img $(img): qemu-img create $(img) 32M -cargo-opts = --no-default-features --features $(output) --bin moros +cargo-opts = --bin moros ifeq ($(mode),release) cargo-opts += --release endif +cargo-opts += --no-default-features --features $(output) # Rebuild MOROS if the features list changed image: $(img) @@ -128,7 +129,7 @@ limine-setup: limine-image: RUSTFLAGS = -C link-arg=-Ttmp/boot/linker.ld -C link-arg=-z -C link-arg=norelro limine-image: - cargo build --release --features limine + cargo build $(cargo-opts),limine cp target/x86_64-moros/release/moros tmp/boot/kernel.elf find tmp/boot cat tmp/boot/limine/limine.conf From f4b14c43f17c9a658c1c949990eb913c89bb1395 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 18 Apr 2026 14:43:57 +0200 Subject: [PATCH 13/13] Add multiboot2 support --- Cargo.lock | 79 ++++++++++++++++++++++++++++++++----- Cargo.toml | 2 + Makefile | 6 ++- src/main.rs | 73 ++++++++++++++++++++++++++++++++-- tmp/boot/limine/limine.conf | 11 ++++-- tmp/boot/linker.ld | 24 ----------- 6 files changed, 154 insertions(+), 41 deletions(-) delete mode 100644 tmp/boot/linker.ld diff --git a/Cargo.lock b/Cargo.lock index 4a3929776..ad331dfe5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,9 +69,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "bitvec" @@ -380,6 +380,7 @@ dependencies = [ "linked_list_allocator", "littlewing", "miniz_oxide", + "multiboot2", "nom", "num-bigint", "num-traits", @@ -399,6 +400,30 @@ dependencies = [ "x86_64", ] +[[package]] +name = "multiboot2" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89797c447846ff7c39eebf22b1c6ce1c6d8721d0dced9771fc142d10cc2a4e97" +dependencies = [ + "bitflags 2.11.1", + "log", + "multiboot2-common", + "ptr_meta", + "thiserror", + "uefi-raw", +] + +[[package]] +name = "multiboot2-common" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6892f2795001adb0f6e4c124de90b68f9edc4bf52b8d81b14dac45cb361f1cca" +dependencies = [ + "ptr_meta", + "thiserror", +] + [[package]] name = "no-std-compat" version = "0.4.1" @@ -514,6 +539,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "ptr_meta" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "quote" version = "1.0.37" @@ -577,7 +622,7 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.11.1", ] [[package]] @@ -707,18 +752,18 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "thiserror" -version = "2.0.4" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f49a1853cf82743e3b7950f77e0f4d622ca36cf4317cba00c767838bac8d490" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.4" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8381894bb3efe0c4acac3ded651301ceee58a15d47c2e34885ed1908ad667061" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -772,11 +817,27 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94d293f51425981fdb1b766beae254dbb711a17e8c4b549dc69b9b7ee0d478d5" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.11.1", "rustversion", "x86", ] +[[package]] +name = "uefi-raw" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aff2f4f2b556a36a201d335a1e0a57754967a96857b1f47a52d5a23825cac84" +dependencies = [ + "bitflags 2.11.1", + "uguid", +] + +[[package]] +name = "uguid" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8352f8c05e47892e7eaf13b34abd76a7f4aeaf817b716e88789381927f199c" + [[package]] name = "unicode-ident" version = "1.0.12" @@ -855,7 +916,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f042214de98141e9c8706e8192b73f56494087cc55ebec28ce10f26c5c364ae" dependencies = [ "bit_field", - "bitflags 2.4.1", + "bitflags 2.11.1", "rustversion", "volatile", ] diff --git a/Cargo.toml b/Cargo.toml index 69a02a623..f2dfc262a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ video = [] serial = [] userspace = [] limine = [] +multiboot = [] [dependencies] acpi = "5.0.0" @@ -30,6 +31,7 @@ limine = "0.6.3" linked_list_allocator = "0.10.6" littlewing = { version = "0.8.0", default-features = false } miniz_oxide = "0.9.1" +multiboot2 = "0.24.1" nom = { version = "8.0.0", default-features = false, features = ["alloc"] } num-bigint = { version = "0.4.6", default-features = false } num-traits = { version = "0.2.19", default-features = false } diff --git a/Makefile b/Makefile index 47201d14a..f67817c58 100644 --- a/Makefile +++ b/Makefile @@ -127,9 +127,11 @@ limine-setup: cp limine-11.3.1/bin/limine-bios-cd.bin boot/limine/ cp limine-11.3.1/bin/limine-bios.sys boot/limine/ -limine-image: RUSTFLAGS = -C link-arg=-Ttmp/boot/linker.ld -C link-arg=-z -C link-arg=norelro +limine-proto = limine# limine, multiboot + +limine-image: RUSTFLAGS = -C link-arg=-Ttmp/boot/$(limine-proto).ld -C link-arg=-z -C link-arg=norelro limine-image: - cargo build $(cargo-opts),limine + cargo build $(cargo-opts),$(limine-proto) cp target/x86_64-moros/release/moros tmp/boot/kernel.elf find tmp/boot cat tmp/boot/limine/limine.conf diff --git a/src/main.rs b/src/main.rs index 18be35eeb..30885b087 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,8 +10,8 @@ use moros::{ error, warning, hlt_loop, eprint, eprintln, print, println, sys, usr }; -#[cfg(not(feature = "limine"))] -mod bootloader_boot { +#[cfg(not(any(feature = "limine", feature = "multiboot")))] +mod bootloader_main { use super::*; use bootloader::{entry_point, BootInfo}; @@ -26,7 +26,7 @@ mod bootloader_boot { } #[cfg(feature = "limine")] -mod limine_boot { +mod limine_main { use super::*; use moros::sys::mem::MemoryMap; @@ -101,6 +101,73 @@ mod limine_boot { } } +#[cfg(feature = "multiboot")] +mod multiboot_main { + use super::*; + + use moros::sys::mem::MemoryMap; + use moros::sys::mem::MemoryRegion; + use moros::sys::mem::MemoryRegionType; + use multiboot2::{BootInformation, BootInformationHeader}; + + #[used] + #[link_section = ".multiboot"] + static MULTIBOOT_HEADER: [u32; 6] = [ + 0xE85250D6, // magic + 0, // architecture: i386 + 24, // header length (6 * 4 bytes) + 0u32.wrapping_sub(0xE85250D6u32.wrapping_add(24)), // checksum + 0, // end tag type + 8, // end tag size + ]; + + core::arch::global_asm!( + ".section .text", + ".global _start", + "_start:", + "mov edi, ebx", + "mov esi, eax", + "call main", + "hlt", + ); + + #[no_mangle] + pub extern "C" fn main(mb2_info: u32, mb2_magic: u32) -> ! { + let vga = 0xB8000 as *mut u8; + let msg = b"MOROS loading..."; + for (i, &byte) in msg.iter().enumerate() { + unsafe { + *vga.add(i * 2) = byte; + *vga.add(i * 2 + 1) = 0x0F; + } + } + + if mb2_magic == multiboot2::MAGIC { + let boot_info = unsafe { + BootInformation::load(mb2_info as *const BootInformationHeader).unwrap() + }; + if let Some(memory_map_tag) = boot_info.memory_map_tag() { + // FIXME: This is never reached + use multiboot2::MemoryAreaType as Mem; + let mut memory_map = MemoryMap::new(); + for region in memory_map_tag.memory_areas() { + let addr = region.start_address(); + let size = region.size(); + let kind = match region.typ().into() { + Mem::Available => MemoryRegionType::Usable, + _ => MemoryRegionType::Reserved, + }; + memory_map.add(MemoryRegion::new(addr, size, kind)); + }; + let offset = 0; + moros::init(&memory_map, offset); + } + } + + exec(); + } +} + pub fn exec() -> ! { print!("\x1b[?25h"); // Enable cursor loop { diff --git a/tmp/boot/limine/limine.conf b/tmp/boot/limine/limine.conf index 71aeeda32..c6840700e 100644 --- a/tmp/boot/limine/limine.conf +++ b/tmp/boot/limine/limine.conf @@ -1,7 +1,12 @@ -timeout: 0 -interface_resolution: 640x480 +timeout: 10 +graphics: no -/MOROS +/MOROS (Limine) protocol: limine resolution: 640x480x32 kernel_path: boot():/kernel.elf + +/MOROS (Multiboot2) + protocol: multiboot2 + textmode: yes + kernel_path: boot():/kernel.elf diff --git a/tmp/boot/linker.ld b/tmp/boot/linker.ld deleted file mode 100644 index e917e4635..000000000 --- a/tmp/boot/linker.ld +++ /dev/null @@ -1,24 +0,0 @@ -KERNEL_OFFSET = 0xFFFFFFFF80000000; - -SECTIONS { - . = KERNEL_OFFSET; - - .text : { *(.text .text.*) } - . = ALIGN(4096); - - .rodata : { *(.rodata .rodata.*) } - . = ALIGN(4096); - - .data : { - *(.data .data.*) - KEEP(*(.limine_req_start)) - KEEP(*(.limine_reqs)) - KEEP(*(.limine_req_end)) - } - . = ALIGN(4096); - - .bss : { *(.bss .bss.*) *(COMMON) } - . = ALIGN(4096); - - /DISCARD/ : { *(.eh_frame*) *(.note*) *(.comment*) } -}