1#![no_std]
12#![no_main]
13#![feature(abi_x86_interrupt)]
14#![feature(allocator_api)]
15#![feature(alloc_error_handler)]
16
17extern crate alloc;
18
19pub mod ostd;
21
22pub mod acpi;
23pub mod arch;
24pub mod audit;
25pub mod boot;
26pub mod capability;
27pub mod components;
28pub mod hardware;
29pub mod ipc;
30pub mod memory;
31pub mod namespace;
32pub mod process;
33pub mod shell;
34pub mod silo;
35pub mod sync;
36pub mod syscall;
37pub mod trace;
38pub mod vfs;
39
40pub use boot::limine::kmain;
42
43pub fn init_serial() {
48 arch::x86_64::serial::init();
49}
50
51pub fn init_logger() {
53 boot::logger::init();
54}
55
56pub fn init_components(stage: component::InitStage) -> Result<(), component::ComponentInitError> {
61 component::init_all(stage)
62}
63
64use core::panic::PanicInfo;
65
66const PAGE_SIZE: u64 = 4096;
67const MAX_BOOT_MMAP_REGIONS_WORK: usize = 1024;
68
69const fn null_region() -> boot::entry::MemoryRegion {
71 boot::entry::MemoryRegion {
72 base: 0,
73 size: 0,
74 kind: boot::entry::MemoryKind::Reserved,
75 }
76}
77
78#[inline]
80const fn align_down(value: u64, align: u64) -> u64 {
81 value & !(align - 1)
82}
83
84#[inline]
86const fn align_up(value: u64, align: u64) -> u64 {
87 (value + align - 1) & !(align - 1)
88}
89
90#[inline]
92const fn virt_or_phys_to_phys(addr: u64, hhdm: u64) -> u64 {
93 if hhdm != 0 && addr >= hhdm {
94 addr - hhdm
95 } else {
96 addr
97 }
98}
99
100fn reserve_range_in_map(
102 map: &mut [boot::entry::MemoryRegion],
103 len: &mut usize,
104 reserve_start: u64,
105 reserve_end: u64,
106) {
107 if reserve_start >= reserve_end {
108 return;
109 }
110
111 let mut i = 0usize;
112 while i < *len {
113 let region = map[i];
114 if !matches!(
115 region.kind,
116 boot::entry::MemoryKind::Free | boot::entry::MemoryKind::Reclaim
117 ) {
118 i += 1;
119 continue;
120 }
121
122 let region_start = region.base;
123 let region_end = region.base.saturating_add(region.size);
124 if reserve_end <= region_start || reserve_start >= region_end {
125 i += 1;
126 continue;
127 }
128
129 let overlap_start = core::cmp::max(region_start, reserve_start);
130 let overlap_end = core::cmp::min(region_end, reserve_end);
131
132 if overlap_start <= region_start && overlap_end >= region_end {
133 map[i].kind = boot::entry::MemoryKind::Reserved;
134 i += 1;
135 continue;
136 }
137
138 if overlap_start <= region_start {
139 map[i].base = overlap_end;
140 map[i].size = region_end.saturating_sub(overlap_end);
141 i += 1;
142 continue;
143 }
144
145 if overlap_end >= region_end {
146 map[i].size = overlap_start.saturating_sub(region_start);
147 i += 1;
148 continue;
149 }
150
151 let left = boot::entry::MemoryRegion {
152 base: region_start,
153 size: overlap_start.saturating_sub(region_start),
154 kind: region.kind,
155 };
156 let right = boot::entry::MemoryRegion {
157 base: overlap_end,
158 size: region_end.saturating_sub(overlap_end),
159 kind: region.kind,
160 };
161
162 if *len + 1 > map.len() {
163 map[i] = left;
164 i += 1;
165 continue;
166 }
167
168 for j in (i + 1..*len).rev() {
169 map[j + 1] = map[j];
170 }
171 map[i] = left;
172 map[i + 1] = right;
173 *len += 1;
174 i += 2;
175 }
176}
177
178#[cfg(feature = "selftest")]
180fn region_kind_for_addr(
181 map: &[boot::entry::MemoryRegion],
182 len: usize,
183 addr: u64,
184) -> Option<boot::entry::MemoryKind> {
185 map.iter().take(len).find_map(|r| {
186 let start = r.base;
187 let end = r.base.saturating_add(r.size);
188 if addr >= start && addr < end {
189 Some(r.kind)
190 } else {
191 None
192 }
193 })
194}
195
196#[panic_handler]
198fn panic_handler(info: &PanicInfo) -> ! {
199 boot::panic::panic_handler(info)
200}
201
202fn register_initfs_module(path: &str, module: Option<(u64, u64)>) {
204 let Some((base, size)) = module else {
205 return;
206 };
207 if base == 0 || size == 0 {
208 return;
209 }
210
211 let base_virt = memory::phys_to_virt(base) as *const u8;
212 let len = size as usize;
213 #[cfg(feature = "selftest")]
214 {
215 let data = unsafe { core::slice::from_raw_parts(base_virt, len.min(4)) };
217 if data.len() == 4 {
218 serial_println!(
219 "[init] /initfs/{} source magic={:02x}{:02x}{:02x}{:02x} size={}",
220 path,
221 data[0],
222 data[1],
223 data[2],
224 data[3],
225 size
226 );
227 }
228 }
229
230 if let Err(e) = vfs::register_initfs_file(path, base_virt, len) {
232 serial_println!("[init] Failed to register /initfs/{}: {:?}", path, e);
233 } else {
234 serial_println!("[init] Registered /initfs/{} ({} bytes)", path, size);
235 }
236}
237
238fn register_boot_initfs_modules(initfs_base: u64, initfs_size: u64) {
240 let boot_test_pid = if initfs_base != 0 && initfs_size != 0 {
241 Some((initfs_base, initfs_size))
242 } else {
243 None
244 };
245 let initfs_modules = [
246 ("test_pid", boot_test_pid),
247 ("test_syscalls", crate::boot::limine::test_syscalls_module()),
248 ("test_mem", crate::boot::limine::test_mem_module()),
249 (
250 "test_mem_stressed",
251 crate::boot::limine::test_mem_stressed_module(),
252 ),
253 ("fs-ext4", crate::boot::limine::fs_ext4_module()),
254 (
255 "strate-fs-ramfs",
256 crate::boot::limine::strate_fs_ramfs_module(),
257 ),
258 ("init", crate::boot::limine::init_module()),
259 ("console-admin", crate::boot::limine::console_admin_module()),
260 ("strate-net", crate::boot::limine::strate_net_module()),
261 ("strate-bus", crate::boot::limine::strate_bus_module()),
262 ("bin/dhcp-client", crate::boot::limine::dhcp_client_module()),
263 ("bin/ping", crate::boot::limine::ping_module()),
264 ("bin/telnetd", crate::boot::limine::telnetd_module()),
265 ("bin/udp-tool", crate::boot::limine::udp_tool_module()),
266 ("strate-wasm", crate::boot::limine::strate_wasm_module()),
267 ("strate-webrtc", crate::boot::limine::strate_webrtc_module()),
268 ("bin/hello.wasm", crate::boot::limine::hello_wasm_module()),
269 (
270 "wasm-test.toml",
271 crate::boot::limine::wasm_test_toml_module(),
272 ),
273 ];
274 for (path, module) in initfs_modules {
275 register_initfs_module(path, module);
276 }
277}
278
279#[inline]
281fn boot_module_slice(base: u64, size: u64) -> &'static [u8] {
282 let base_virt = memory::phys_to_virt(base);
283 unsafe { core::slice::from_raw_parts(base_virt as *const u8, size as usize) }
284}
285
286#[cfg(feature = "selftest")]
288fn log_boot_module_magics(stage: &str) {
289 let modules = [
290 ("init", crate::boot::limine::init_module()),
291 ("console-admin", crate::boot::limine::console_admin_module()),
292 ("strate-net", crate::boot::limine::strate_net_module()),
293 ("strate-bus", crate::boot::limine::strate_bus_module()),
294 ("bin/dhcp-client", crate::boot::limine::dhcp_client_module()),
295 ("bin/ping", crate::boot::limine::ping_module()),
296 ("bin/telnetd", crate::boot::limine::telnetd_module()),
297 ("bin/udp-tool", crate::boot::limine::udp_tool_module()),
298 ("strate-wasm", crate::boot::limine::strate_wasm_module()),
299 ("strate-webrtc", crate::boot::limine::strate_webrtc_module()),
300 ("bin/hello.wasm", crate::boot::limine::hello_wasm_module()),
301 (
302 "wasm-test.toml",
303 crate::boot::limine::wasm_test_toml_module(),
304 ),
305 ];
306 for (name, module) in modules {
307 let Some((base, size)) = module else {
308 continue;
309 };
310 if size < 4 {
311 continue;
312 }
313 let ptr = memory::phys_to_virt(base) as *const u8;
314 let m0 = unsafe { core::ptr::read_volatile(ptr) };
315 let m1 = unsafe { core::ptr::read_volatile(ptr.add(1)) };
316 let m2 = unsafe { core::ptr::read_volatile(ptr.add(2)) };
317 let m3 = unsafe { core::ptr::read_volatile(ptr.add(3)) };
318 serial_println!(
319 "[init] Module magic [{}]: {} phys=0x{:x} magic={:02x}{:02x}{:02x}{:02x} size={}",
320 stage,
321 name,
322 base,
323 m0,
324 m1,
325 m2,
326 m3,
327 size
328 );
329 }
330}
331
332#[cfg(not(feature = "selftest"))]
334fn log_boot_module_magics(_stage: &str) {}
335
336pub unsafe fn kernel_main(args: *const boot::entry::KernelArgs) -> ! {
338 debug_assert!(
342 !arch::x86_64::interrupts_enabled(),
343 "interrupts must be disabled at boot entry"
344 );
345
346 init_serial();
350 init_logger();
351
352 serial_println!("[init] IDT (early)...");
358 arch::x86_64::idt::init();
359 serial_println!("[init] IDT initialized.");
360
361 debug_assert!(
362 !arch::x86_64::interrupts_enabled(),
363 "interrupts must be disabled after IDT init"
364 );
365
366 crate::arch::x86_64::cpuid::init();
368
369 crate::arch::x86_64::init_cpu_extensions();
371
372 boot::panic::install_default_panic_hooks();
375
376 serial_println!();
378 serial_println!();
379 serial_println!(r" __ __ ________ ");
380 serial_println!(r" _______/ |_____________ _/ |_/ __ \ ____ ______ ");
381 serial_println!(r" / ___/\ __\_ __ \__ \\ __\____ / ______ / _ \/ ___/ ");
382 serial_println!(r" \___ \ | | | | \// __ \| | / / /_____/ ( <_> )___ \ ");
383 serial_println!(r"/____ > |__| |__| (____ /__| /____/ \____/____ > ");
384 serial_println!(r" \/ \/ \/ ");
385 serial_println!();
386
387 serial_println!("");
388 serial_println!("=======================================================================================================");
389 serial_println!(" strat9-OS kernel v0.1.0 (Bedrock)");
390 serial_println!(" Copyright (c) 2025-26 Guillaume Gielly - GPLv3 License");
391 serial_println!("");
392 serial_println!(" This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, without");
395 serial_println!(
396 " even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
397 );
398 serial_println!(" See the GNU General Public License for more details.");
399 serial_println!("=======================================================================================================");
400 serial_println!();
401
402 if args.is_null() {
404 serial_println!("[CRIT] No KernelArgs provided. System will hang.");
405 loop {
406 arch::x86_64::hlt();
407 }
408 }
409
410 let args = &*args;
411 serial_println!("[init] KernelArgs at {:p}", args);
412
413 if args.magic != strat9_abi::boot::STRAT9_BOOT_MAGIC {
414 serial_println!(
415 "[CRIT] Bad KernelArgs magic: 0x{:08x} (expected 0x{:08x})",
416 args.magic,
417 strat9_abi::boot::STRAT9_BOOT_MAGIC
418 );
419 loop {
420 arch::x86_64::hlt();
421 }
422 }
423 if args.abi_version != strat9_abi::boot::STRAT9_BOOT_ABI_VERSION {
424 serial_println!(
425 "[CRIT] Unsupported boot ABI version: {} (kernel expects {})",
426 args.abi_version,
427 strat9_abi::boot::STRAT9_BOOT_ABI_VERSION
428 );
429 loop {
430 arch::x86_64::hlt();
431 }
432 }
433
434 let hhdm = args.hhdm_offset;
440 memory::set_hhdm_offset(hhdm);
441 serial_println!("[init] HHDM offset: 0x{:x}", hhdm);
442
443 serial_println!(
444 "[init] Memory map: 0x{:x} ({} bytes)",
445 args.memory_map_base,
446 args.memory_map_size
447 );
448
449 log_boot_module_magics("pre-mm");
450
451 serial_println!("[init] Memory manager...");
455 let mmap_ptr = args.memory_map_base as *const boot::entry::MemoryRegion;
456 let mmap_len =
457 args.memory_map_size as usize / core::mem::size_of::<boot::entry::MemoryRegion>();
458 let mmap = core::slice::from_raw_parts(mmap_ptr, mmap_len);
459 let mut mmap_work = [null_region(); MAX_BOOT_MMAP_REGIONS_WORK];
460 let mut mmap_work_len = core::cmp::min(mmap.len(), mmap_work.len());
461 for (dst, src) in mmap_work.iter_mut().zip(mmap.iter()).take(mmap_work_len) {
462 *dst = *src;
463 }
464
465 let reserve_modules = [
466 (
467 "test_pid",
468 if args.initfs_base != 0 && args.initfs_size != 0 {
469 Some((args.initfs_base, args.initfs_size))
470 } else {
471 None
472 },
473 ),
474 ("test_syscalls", crate::boot::limine::test_syscalls_module()),
475 ("test_mem", crate::boot::limine::test_mem_module()),
476 (
477 "test_mem_stressed",
478 crate::boot::limine::test_mem_stressed_module(),
479 ),
480 ("fs-ext4", crate::boot::limine::fs_ext4_module()),
481 (
482 "strate-fs-ramfs",
483 crate::boot::limine::strate_fs_ramfs_module(),
484 ),
485 ("init", crate::boot::limine::init_module()),
486 ("console-admin", crate::boot::limine::console_admin_module()),
487 ("strate-net", crate::boot::limine::strate_net_module()),
488 ("strate-bus", crate::boot::limine::strate_bus_module()),
489 ("bin/dhcp-client", crate::boot::limine::dhcp_client_module()),
490 ("bin/ping", crate::boot::limine::ping_module()),
491 ("bin/telnetd", crate::boot::limine::telnetd_module()),
492 ("bin/udp-tool", crate::boot::limine::udp_tool_module()),
493 ("strate-wasm", crate::boot::limine::strate_wasm_module()),
494 ("bin/hello.wasm", crate::boot::limine::hello_wasm_module()),
495 (
496 "wasm-test.toml",
497 crate::boot::limine::wasm_test_toml_module(),
498 ),
499 ];
500
501 for (_name, module) in reserve_modules {
502 let Some((base, size)) = module else {
503 continue;
504 };
505 if size == 0 {
506 continue;
507 }
508 let phys = virt_or_phys_to_phys(base, hhdm);
509 let reserve_start = align_down(phys, PAGE_SIZE);
510 let reserve_end = align_up(phys.saturating_add(size), PAGE_SIZE);
511 reserve_range_in_map(
512 &mut mmap_work,
513 &mut mmap_work_len,
514 reserve_start,
515 reserve_end,
516 );
517 #[cfg(feature = "selftest")]
518 {
519 serial_println!(
520 "[init] Reserved module pages: {} phys=0x{:x}..0x{:x}",
521 _name,
522 reserve_start,
523 reserve_end
524 );
525 let kind = region_kind_for_addr(&mmap_work, mmap_work_len, reserve_start);
526 serial_println!(
527 "[init] Module map kind: {} @0x{:x} => {:?}",
528 _name,
529 reserve_start,
530 kind
531 );
532 }
533 }
534
535 memory::boot_alloc::init_boot_allocator(&mmap_work[..mmap_work_len]);
538 serial_println!("[init] Boot allocator ready.");
539
540 let total_ram = mmap_work[..mmap_work_len]
541 .iter()
542 .filter(|region| {
543 matches!(
544 region.kind,
545 boot::entry::MemoryKind::Free | boot::entry::MemoryKind::Reclaim
546 )
547 })
548 .map(|region| region.base.saturating_add(region.size))
549 .max()
550 .unwrap_or(0);
551
552 {
553 let mut boot_alloc = memory::boot_alloc::get_boot_allocator().lock();
554 memory::frame::init_metadata_array(total_ram, &mut *boot_alloc);
555 }
556 serial_println!("[init] Frame metadata ready.");
557
558 memory::buddy::init_buddy_allocator(&mmap_work[..mmap_work_len]);
559
560 serial_println!("[init] Buddy allocator ready.");
561
562 debug_assert!(
563 !arch::x86_64::interrupts_enabled(),
564 "interrupts must be disabled after buddy allocator init"
565 );
566
567 log_boot_module_magics("post-buddy");
568
569 serial_println!("[init] Paging...");
573 memory::paging::init(hhdm);
574
575 memory::paging::map_all_ram(&mmap_work[..mmap_work_len]);
578
579 if args.framebuffer_addr != 0 && args.framebuffer_stride != 0 && args.framebuffer_height != 0 {
583 let fb_phys = if args.framebuffer_addr >= hhdm {
584 args.framebuffer_addr - hhdm
585 } else {
586 args.framebuffer_addr
587 };
588 let fb_size =
589 (args.framebuffer_stride as u64).saturating_mul(args.framebuffer_height as u64);
590 memory::paging::ensure_identity_map_range(fb_phys, fb_size);
591 serial_println!(
592 "[init] Framebuffer mapped: phys=0x{:x} size={} bytes",
593 fb_phys,
594 fb_size
595 );
596 }
597 serial_println!("[init] Paging initialized.");
598
599 serial_println!("[init] Console...");
603 arch::x86_64::vga::init(
604 args.framebuffer_addr,
605 args.framebuffer_width,
606 args.framebuffer_height,
607 args.framebuffer_stride,
608 args.framebuffer_bpp,
609 args.framebuffer_red_mask_size,
610 args.framebuffer_red_mask_shift,
611 args.framebuffer_green_mask_size,
612 args.framebuffer_green_mask_shift,
613 args.framebuffer_blue_mask_size,
614 args.framebuffer_blue_mask_shift,
615 );
616 vga_println!("[OK] Paging initialized");
617 vga_println!("[OK] Serial port initialized");
618 vga_println!("[OK] Memory manager active");
619
620 serial_println!("[init] TSS...");
624 vga_println!("[..] Initializing TSS...");
625 arch::x86_64::tss::init();
626 serial_println!("[init] TSS initialized.");
627 vga_println!("[OK] TSS initialized");
628
629 serial_println!("[init] GDT...");
633 vga_println!("[..] Initializing GDT...");
634 arch::x86_64::gdt::init();
635 serial_println!("[init] GDT initialized.");
636 vga_println!("[OK] GDT loaded (with TSS)");
637
638 serial_println!("[init] SYSCALL/SYSRET...");
642 vga_println!("[..] Initializing SYSCALL/SYSRET...");
643 arch::x86_64::syscall::init();
644 serial_println!("[init] SYSCALL/SYSRET initialized.");
645 vga_println!("[OK] SYSCALL/SYSRET configured");
646
647 serial_println!("[init] Components (bootstrap)...");
651 vga_println!("[..] Initializing bootstrap components...");
652 if let Err(e) = component::init_all(component::InitStage::Bootstrap) {
653 serial_println!("[WARN] Some bootstrap components failed: {:?}", e);
654 }
655 serial_println!("[init] Bootstrap components initialized.");
656 vga_println!("[OK] Bootstrap components ready");
657
658 log_boot_module_magics("post-paging");
667
668 serial_println!("[init] Kernel address space...");
672 vga_println!("[..] Initializing kernel address space...");
673 memory::address_space::init_kernel_address_space();
674 serial_println!("[init] Kernel address space initialized.");
675 debug_assert!(
676 !arch::x86_64::interrupts_enabled(),
677 "interrupts must be disabled after kernel address space init"
678 );
679 vga_println!("[OK] Kernel address space initialized");
680 log_boot_module_magics("post-kas");
681
682 serial_println!("[init] VFS...");
686 vga_println!("[..] Initializing virtual file system...");
687
688 vfs::init();
689
690 serial_println!("[init] VFS initialized.");
691 vga_println!("[OK] VFS initialized");
692 register_boot_initfs_modules(args.initfs_base, args.initfs_size);
693
694 log_boot_module_magics("post-cow");
695
696 serial_println!("[init] Interrupt controller...");
700 vga_println!("[..] Initializing interrupt controller...");
701
702 memory::paging::ensure_identity_map(args.acpi_rsdp_base);
704
705 let rsdp_virt = memory::phys_to_virt(args.acpi_rsdp_base);
706 let apic_active = init_apic_subsystem(rsdp_virt);
707
708 if !apic_active {
709 serial_println!("[init] APIC unavailable, falling back to legacy PIC");
711 vga_println!("[..] Falling back to legacy PIC...");
712 arch::x86_64::pic::init(
713 arch::x86_64::pic::PIC1_OFFSET,
714 arch::x86_64::pic::PIC2_OFFSET,
715 );
716 arch::x86_64::pic::disable();
717 arch::x86_64::pic::enable_irq(0); arch::x86_64::pic::enable_irq(1); serial_println!("[init] Legacy PIC initialized.");
720 vga_println!("[OK] Legacy PIC initialized (IRQ0: timer, IRQ1: keyboard)");
721 } else {
722 serial_println!("[init] APIC subsystem initialized.");
723 vga_println!("[OK] APIC + I/O APIC + APIC timer active");
724 }
725
726 if apic_active {
728 arch::x86_64::tlb::init();
729 serial_println!("[init] TLB shootdown system initialized.");
730 debug_assert!(
731 !arch::x86_64::interrupts_enabled(),
732 "interrupts must be disabled after TLB init"
733 );
734 }
735
736 if apic_active {
740 let bsp_apic_id = arch::x86_64::apic::lapic_id();
741 arch::x86_64::percpu::init_boot_cpu(bsp_apic_id);
742 arch::x86_64::percpu::init_gs_base(0);
743 serial_println!("[init] SMP: booting secondary cores...");
744 vga_println!("[..] SMP: starting APs...");
745
746 match arch::x86_64::smp::init() {
747 Ok(count) => {
748 serial_println!("[init] SMP: {} core(s) online", count);
749 vga_println!("[OK] SMP: {} core(s) online", count);
750 }
751 Err(e) => {
752 serial_println!("[init] SMP init failed: {}", e);
753 vga_println!("[WARN] SMP init failed: {}", e);
754 }
755 }
756 } else {
757 arch::x86_64::percpu::init_boot_cpu(0);
758 }
759
760 if apic_active {
764 let mouse_ok = arch::x86_64::mouse::init();
765
766 if mouse_ok {
767 serial_println!("[init] PS/2 mouse initialized.");
768 vga_println!("[OK] PS/2 mouse ready");
769 } else {
770 serial_println!("[init] PS/2 mouse not found (optional).");
771 }
772 }
773
774 serial_println!("[init] Initializing scheduler...");
778 vga_println!("[..] Setting up multitasking...");
779 crate::process::task::Task::debug_print_layout();
781 process::init_scheduler();
782
783 debug_assert!(
784 !arch::x86_64::interrupts_enabled(),
785 "interrupts must be disabled after scheduler init"
786 );
787
788 if apic_active {
794 debug_assert!(
795 !arch::x86_64::interrupts_enabled(),
796 "interrupts must be disabled before APIC timer start"
797 );
798 serial_println!("[init] Starting APIC timer on BSP...");
799 arch::x86_64::timer::start_apic_timer_cached();
800 }
801
802 serial_println!("[init] Scheduler initialized.");
803 serial_println!("[trace][bsp] after init_scheduler");
804 vga_println!("[OK] Multitasking enabled");
805
806 serial_println!("[trace][bsp] before kthread init_all");
810 serial_println!("[init] Components (kthread)...");
811 vga_println!("[..] Initializing kthread components...");
812
813 if let Err(e) = component::init_all(component::InitStage::Kthread) {
814 serial_println!("[WARN] Some kthread components failed: {:?}", e);
815 }
816
817 serial_println!("[trace][bsp] after kthread init_all");
818 serial_println!("[init] Kthread components initialized.");
819 vga_println!("[OK] Kthread components ready");
820
821 #[cfg(feature = "selftest")]
822 {
823 serial_println!("[init] Creating self-test tasks...");
827 vga_println!("[..] Adding self-test tasks...");
828 process::selftest::create_selftest_tasks();
829 serial_println!("[init] Self-test tasks created.");
830 vga_println!("[OK] Self-test tasks added");
831 }
832
833 #[cfg(not(feature = "selftest"))]
837 {
838 let mut init_task_id: Option<crate::process::TaskId> = None;
842
843 serial_println!("[init] Components (process)...");
844 vga_println!("[..] Initializing process components...");
845 if let Err(e) = component::init_all(component::InitStage::Process) {
846 serial_println!("[WARN] Some process components failed: {:?}", e);
847 }
848 serial_println!("[init] Process components initialized.");
849 vga_println!("[OK] Process components ready");
850
851 serial_println!("[init] Loading hardware drivers...");
859 vga_println!("[..] Initializing hardware drivers...");
860 hardware::init();
861
862 serial_println!("[init] Initializing timers...");
863 vga_println!("[..] Initializing HPET and RTC...");
864 hardware::timer::init();
865 serial_println!("[init] Timers initialized.");
866 vga_println!("[OK] HPET/RTC initialized");
867
868 serial_println!("[init] Initializing USB...");
869 vga_println!("[..] Looking for USB controllers...");
870 hardware::usb::init();
871 serial_println!("[init] USB initialized.");
872 vga_println!("[OK] USB xHCI/EHCI/UHCI initialized");
873
874 serial_println!("[init] Initializing VirtIO block...");
875 vga_println!("[..] Looking for VirtIO block device...");
876 hardware::storage::virtio_block::init();
877 serial_println!("[init] VirtIO block initialized.");
878 vga_println!("[OK] VirtIO block driver initialized");
879
880 serial_println!("[init] Initializing AHCI...");
881 vga_println!("[..] Looking for AHCI SATA controller...");
882 hardware::storage::ahci::init();
883 serial_println!("[init] AHCI probe done.");
884 vga_println!("[OK] AHCI probe done");
885
886 serial_println!("[init] Initializing ATA/IDE...");
887 vga_println!("[..] Looking for ATA/IDE devices...");
888 hardware::storage::ata_legacy::init();
889 serial_println!("[init] ATA/IDE probe done.");
890 vga_println!("[OK] ATA/IDE probe done");
891
892 serial_println!("[init] Initializing NVMe...");
893 vga_println!("[..] Looking for NVMe controllers...");
894 hardware::storage::nvme::init();
895 serial_println!("[init] NVMe probe done.");
896 vga_println!("[OK] NVMe probe done");
897
898 serial_println!("[init] Initializing VirtIO net...");
899 vga_println!("[..] Looking for VirtIO net device...");
900 hardware::nic::virtio_net::init();
901 serial_println!("[init] VirtIO net initialized.");
902 vga_println!("[OK] VirtIO net driver initialized");
903
904 serial_println!("[init] Initializing VirtIO RNG...");
905 vga_println!("[..] Looking for VirtIO RNG device...");
906 crate::hardware::virtio::rng::init();
907 serial_println!("[init] VirtIO RNG initialized.");
908 vga_println!("[OK] VirtIO RNG driver initialized");
909
910 serial_println!("[init] Initializing VirtIO Console...");
911 vga_println!("[..] Looking for VirtIO Console device...");
912 crate::hardware::virtio::console::init();
913 serial_println!("[init] VirtIO Console initialized.");
914 vga_println!("[OK] VirtIO Console driver initialized");
915
916 serial_println!("[init] Checking for devices...");
919 vga_println!("[..] Checking for devices...");
920
921 if let Some(blk) = hardware::storage::virtio_block::get_device() {
922 use hardware::storage::virtio_block::BlockDevice;
923 serial_println!(
924 "[INFO] VirtIO block device found. Capacity: {} sectors",
925 blk.sector_count()
926 );
927 vga_println!("[OK] VirtIO block driver loaded");
928 } else {
929 serial_println!("[WARN] No VirtIO block device found");
930 vga_println!("[WARN] No VirtIO block device found");
931 }
932
933 if let Some(ahci) = hardware::storage::ahci::get_device() {
934 serial_println!(
935 "[INFO] AHCI SATA device found. Capacity: {} sectors ({} MiB)",
936 ahci.sector_count(),
937 (ahci.sector_count() * 512) / 1048576, );
939 vga_println!("[OK] AHCI SATA driver loaded");
940 } else {
941 serial_println!("[INFO] No AHCI SATA device found");
942 }
943
944 if let Some(nvme) = hardware::storage::nvme::get_first_controller() {
945 if let Some(ns) = nvme.get_namespace(0) {
946 serial_println!(
947 "[INFO] NVMe device found. Namespace {} - {} blocks @ {} bytes ({} MiB)",
948 ns.nsid,
949 ns.size,
950 ns.block_size,
951 (ns.size * ns.block_size as u64) / 1048576, );
953 vga_println!("[OK] NVMe driver loaded");
954 }
955 } else {
956 serial_println!("[INFO] No NVMe device found");
957 }
958
959 {
961 let ifaces = hardware::nic::list_interfaces();
962 if ifaces.is_empty() {
963 serial_println!("[WARN] No network devices found");
964 vga_println!("[WARN] No network devices found");
965 } else {
966 for name in &ifaces {
967 if let Some(dev) = hardware::nic::get_device(name) {
968 let mac = dev.mac_address();
969 serial_println!(
970 "[INFO] Network {} ({}) MAC {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x} link={}",
971 name, dev.name(),
972 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
973 if dev.link_up() { "up" } else { "down" },
974 );
975 vga_println!("[OK] Network {} ({}) loaded", name, dev.name());
976 }
977 }
978 }
979 }
980
981 serial_println!("[init] Storage verification skipped (boot path)");
982 vga_println!("[..] Storage verification skipped at boot");
983
984 let mut init_loaded = false;
988
989 if let Some((base, size)) = crate::boot::limine::init_module() {
990 let elf_data = boot_module_slice(base, size);
991 match process::elf::load_and_run_elf(elf_data, "init") {
992 Ok(task_id) => {
993 init_task_id = Some(task_id);
994 init_loaded = true;
995 serial_println!("[init] ELF '/initfs/init' loaded as task 'init'.");
996 }
997 Err(e) => {
998 serial_println!("[init] Failed to load init ELF: {}; trying fallback.", e);
999 }
1000 }
1001 }
1002
1003 if !init_loaded && args.initfs_base != 0 && args.initfs_size != 0 {
1004 let elf_data = boot_module_slice(args.initfs_base, args.initfs_size);
1005 match process::elf::load_and_run_elf(elf_data, "init") {
1006 Ok(task_id) => {
1007 init_task_id = Some(task_id);
1008 serial_println!(
1009 "[init] ELF '/initfs/test_pid' loaded as task 'init' (fallback)."
1010 );
1011 }
1012 Err(e) => {
1013 serial_println!("[init] Failed to load test_pid ELF: {}", e);
1014 }
1015 }
1016 }
1017 if let Some((base, size)) = crate::boot::limine::strate_fs_ramfs_module() {
1018 let ram_data = boot_module_slice(base, size);
1019 match process::elf::load_elf_task_with_caps(ram_data, "strate-fs-ramfs", &[]) {
1020 Ok(task) => {
1021 let task_id = task.id;
1022 crate::serial_force_println!(
1023 "[trace][boot] before register_boot_strate_task tid={} label=ramfs-default",
1024 task_id.as_u64()
1025 );
1026 let reg_res = crate::silo::register_boot_strate_task(task_id, "ramfs-default");
1027 crate::serial_force_println!(
1028 "[trace][boot] marker: returned from register_boot_strate_task"
1029 );
1030 if let Err(e) = reg_res {
1031 crate::serial_force_println!(
1032 "[trace][boot] register_boot_strate_task failed tid={} err={:?}",
1033 task_id.as_u64(),
1034 e
1035 );
1036 } else {
1037 crate::serial_force_println!(
1038 "[trace][boot] register_boot_strate_task ok tid={}",
1039 task_id.as_u64()
1040 );
1041 }
1042 crate::serial_force_println!(
1043 "[trace][boot] before add_task tid={} name=strate-fs-ramfs",
1044 task_id.as_u64()
1045 );
1046 process::add_task(task);
1047 crate::serial_force_println!(
1048 "[trace][boot] after add_task tid={} name=strate-fs-ramfs",
1049 task_id.as_u64()
1050 );
1051 serial_println!("[init] Component 'strate-fs-ramfs' loaded.");
1052 }
1053 Err(e) => serial_println!("[init] Failed to load strate-fs-ramfs component: {}", e),
1054 }
1055 }
1056 if let Some((base, size)) = crate::boot::limine::fs_ext4_module() {
1057 let ext4_data = boot_module_slice(base, size);
1058 match process::elf::load_elf_task_with_caps(ext4_data, "strate-fs-ext4", &[]) {
1059 Ok(task) => {
1060 let task_id = task.id;
1061 crate::serial_force_println!(
1062 "[trace][boot] before register_boot_strate_task tid={} label=ext4-default",
1063 task_id.as_u64()
1064 );
1065 if let Err(e) = crate::silo::register_boot_strate_task(task_id, "ext4-default")
1066 {
1067 crate::serial_force_println!(
1068 "[trace][boot] register_boot_strate_task failed tid={} err={:?}",
1069 task_id.as_u64(),
1070 e
1071 );
1072 } else {
1073 crate::serial_force_println!(
1074 "[trace][boot] register_boot_strate_task ok tid={}",
1075 task_id.as_u64()
1076 );
1077 }
1078 crate::serial_force_println!(
1079 "[trace][boot] before add_task tid={} name=strate-fs-ext4",
1080 task_id.as_u64()
1081 );
1082 process::add_task(task);
1083 crate::serial_force_println!(
1084 "[trace][boot] after add_task tid={} name=strate-fs-ext4",
1085 task_id.as_u64()
1086 );
1087 serial_println!("[init] Component 'strate-fs-ext4' loaded.");
1088 }
1089 Err(e) => serial_println!("[init] Failed to load strate-fs-ext4 component: {}", e),
1090 }
1091 }
1092 if let (Some(task_id), Some(device)) =
1093 (init_task_id, hardware::storage::virtio_block::get_device())
1094 {
1095 if let Some(task) = crate::process::get_task_by_id(task_id) {
1096 let cap = crate::capability::get_capability_manager().create_capability(
1097 crate::capability::ResourceType::Volume,
1098 device as *const _ as usize,
1099 crate::capability::CapPermissions {
1100 read: true,
1101 write: true,
1102 execute: false,
1103 grant: true,
1104 revoke: true,
1105 },
1106 );
1107 unsafe { (&mut *task.process.capabilities.get()).insert(cap) };
1108 serial_println!("[init] Granted volume capability to init");
1109 }
1110 }
1111
1112 match process::Task::new_kernel_task_with_stack(
1113 shell::shell_main,
1114 "chevron-shell",
1115 process::TaskPriority::Normal,
1116 64 * 1024,
1117 ) {
1118 Ok(shell_task) => {
1119 process::add_task(shell_task);
1120 serial_println!("[init] Chevron shell ready.");
1121 }
1122 Err(e) => {
1123 serial_println!("[WARN] Failed to create shell task: {}", e);
1124 }
1125 }
1126 if let Ok(status_task) = process::Task::new_kernel_task_with_stack(
1127 arch::x86_64::vga::status_line_task_main,
1128 "status-line",
1129 process::TaskPriority::Low,
1130 64 * 1024,
1131 ) {
1132 process::add_task(status_task);
1133 }
1134 }
1135 #[cfg(feature = "selftest")]
1136 {
1137 serial_println!("[init] Selftest mode: skipping process services and virtio drivers");
1138 }
1139
1140 crate::arch::x86_64::keyboard_layout::set_french_layout();
1142
1143 if apic_active {
1147 arch::x86_64::smp::open_ap_scheduler_gate();
1148 }
1149 serial_println!("[init] Boot complete. Starting preemptive scheduler...");
1150 vga_println!("[OK] Starting multitasking (preemptive)");
1151
1152 process::schedule();
1158}
1159
1160fn init_apic_subsystem(rsdp_vaddr: u64) -> bool {
1165 use arch::x86_64::{apic, ioapic, pic, timer};
1166 use timer::TIMER_HZ;
1167
1168 if !apic::is_present() {
1170 log::warn!("APIC: not present (CPUID)");
1171 return false;
1172 }
1173 serial_println!("[init] 6a. APIC present (CPUID)");
1174
1175 match acpi::init(rsdp_vaddr) {
1177 Ok(true) => {}
1178 Ok(false) => {
1179 log::warn!("APIC: no RSDP from bootloader");
1180 return false;
1181 }
1182 Err(e) => {
1183 log::warn!("APIC: ACPI init failed: {}", e);
1184 return false;
1185 }
1186 }
1187 serial_println!("[init] 6b. ACPI RSDP validated");
1188
1189 let madt_info = match acpi::madt::parse_madt() {
1191 Some(info) => info,
1192 None => {
1193 log::warn!("APIC: MADT not found");
1194 return false;
1195 }
1196 };
1197 serial_println!("[init] 6c. MADT parsed");
1198
1199 if let Some(mcfg) = acpi::mcfg::parse_mcfg() {
1200 serial_println!(
1201 "[init] 6c+. MCFG parsed ({} segment(s))",
1202 mcfg.entries.len()
1203 );
1204 for entry in mcfg.entries.iter() {
1205 log::info!(
1206 "ACPI: MCFG seg={} ecam={:#x} buses={}..{} ({} bus(es))",
1207 entry.segment_group,
1208 entry.base_address,
1209 entry.start_bus,
1210 entry.end_bus,
1211 entry.bus_count()
1212 );
1213 }
1214 } else {
1215 serial_println!("[init] 6c+. MCFG not found");
1216 }
1217
1218 memory::paging::ensure_identity_map(madt_info.local_apic_address as u64);
1221 apic::init(madt_info.local_apic_address);
1222 serial_println!("[init] 6d. Local APIC initialized");
1223
1224 if madt_info.io_apic_count == 0 {
1226 log::warn!("APIC: no I/O APIC in MADT");
1227 return false;
1228 }
1229 let Some(io_apic_entry) = madt_info.io_apics[0] else {
1230 log::warn!("APIC: MADT I/O APIC entry[0] missing");
1231 return false;
1232 };
1233 memory::paging::ensure_identity_map(io_apic_entry.address as u64);
1235 ioapic::init(io_apic_entry.address, io_apic_entry.gsi_base);
1236 serial_println!("[init] 6e. I/O APIC initialized");
1237
1238 pic::init(pic::PIC1_OFFSET, pic::PIC2_OFFSET);
1241 pic::disable_permanently();
1242 serial_println!("[init] 6f. Legacy PIC remapped and disabled");
1243
1244 let lapic_id = apic::lapic_id();
1246 ioapic::route_legacy_irq(0, lapic_id, 0x20, &madt_info.overrides);
1247 ioapic::route_legacy_irq(1, lapic_id, 0x21, &madt_info.overrides);
1248 ioapic::route_legacy_irq(12, lapic_id, 0x2C, &madt_info.overrides);
1249 serial_println!("[init] 6g. IRQ0->vec 0x20, IRQ1->vec 0x21, IRQ12->vec 0x2C routed");
1250
1251 serial_println!("[init] 6h. Calibrating APIC timer using PIT channel 2...");
1253 serial_println!(
1254 "[timer] ================================ TIMER INIT ================================"
1255 );
1256
1257 let ticks_per_10ms = timer::calibrate_apic_timer();
1258
1259 if ticks_per_10ms == 0 {
1260 log::error!("APIC: timer calibration FAILED");
1261 log::warn!("Falling back to legacy PIT timer at 100Hz");
1262
1263 serial_println!("[timer] APIC calibration failed, initializing PIT fallback...");
1266 timer::init_pit(TIMER_HZ as u32);
1267 serial_println!(
1268 "[timer] PIT initialized at {}Hz ({} ms/tick)",
1269 TIMER_HZ,
1270 1_000 / TIMER_HZ
1271 );
1272 serial_println!("[init] 6h. PIT timer initialized (fallback)");
1273
1274 serial_println!("[timer] ============================= TIMER INIT COMPLETE ============================");
1275 serial_println!("[timer] Mode: PIT (legacy fallback)");
1276 serial_println!("[timer] Frequency: {}Hz", TIMER_HZ);
1277 serial_println!("[timer] Interval: {} ms per tick", 1_000 / TIMER_HZ);
1278 serial_println!(
1279 "[timer] =========================================================================="
1280 );
1281
1282 } else {
1285 serial_println!("[init] 6h. APIC timer calibrated successfully");
1286
1287 timer::stop_pit();
1293 ioapic::mask_legacy_irq(0, &madt_info.overrides);
1294 serial_println!("[init] 6i+. Legacy PIT stopped and masked in IOAPIC");
1295
1296 serial_println!("[timer] ============================= TIMER INIT COMPLETE ============================");
1297 serial_println!("[timer] Mode: APIC (native)");
1298 serial_println!("[timer] Frequency: {}Hz", TIMER_HZ);
1299 serial_println!("[timer] Interval: {} ms per tick", 1_000 / TIMER_HZ);
1300 serial_println!("[timer] Ticks per 10ms: {}", ticks_per_10ms);
1301 serial_println!(
1302 "[timer] =========================================================================="
1303 );
1304 }
1305
1306 true
1307}