1#![no_std]
12#![no_main]
13#![feature(abi_x86_interrupt)]
14#![feature(alloc_error_handler)]
15#![feature(negative_impls)]
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 crypto;
29pub mod debug;
30pub mod debug_cfg;
31
32pub mod async_io;
33pub mod dma;
34pub mod entropy;
35pub mod framebuffer;
36pub mod hal;
37pub mod hardware;
38pub mod ipc;
39pub mod kaslr;
40pub mod memory;
41pub mod namespace;
42pub mod process;
43pub mod shell;
44pub mod silo;
45pub mod sync;
46pub mod syscall;
47pub mod trace;
48pub mod vfs;
49
50pub use boot::dtb_boot::kmain;
52
53pub fn init_serial() {
58 if crate::debug_cfg::SERIAL_ENABLED {
59 arch::serial::init();
60 }
61}
62
63pub fn init_logger() {
65 boot::logger::init();
66}
67
68pub fn init_components(stage: component::InitStage) -> Result<(), component::ComponentInitError> {
73 component::init_all(stage)
74}
75
76use core::panic::PanicInfo;
77
78const PAGE_SIZE: u64 = 4096;
79const MAX_BOOT_MMAP_REGIONS_WORK: usize = strat9_abi::boot::MAX_BOOT_MEMORY_REGIONS;
80
81static mut MMAP_WORK: [boot::entry::MemoryRegion; MAX_BOOT_MMAP_REGIONS_WORK] =
83 [null_region(); MAX_BOOT_MMAP_REGIONS_WORK];
84
85static mut BOOT_ARGS: Option<&'static boot::entry::KernelArgs> = None;
88
89pub fn boot_args() -> Option<&'static boot::entry::KernelArgs> {
91 unsafe { BOOT_ARGS }
93}
94
95const fn null_region() -> boot::entry::MemoryRegion {
97 boot::entry::MemoryRegion {
98 base: 0,
99 size: 0,
100 kind: boot::entry::MemoryKind::Reserved,
101 }
102}
103
104#[inline]
106const fn align_down(value: u64, align: u64) -> u64 {
107 value & !(align - 1)
108}
109
110#[inline]
112const fn align_up(value: u64, align: u64) -> u64 {
113 (value + align - 1) & !(align - 1)
114}
115
116#[inline]
118const fn virt_or_phys_to_phys(addr: u64, hhdm: u64) -> u64 {
119 if hhdm != 0 && addr >= hhdm {
120 addr - hhdm
121 } else {
122 addr
123 }
124}
125
126fn reserve_range_in_map(
128 map: &mut [boot::entry::MemoryRegion],
129 len: &mut usize,
130 reserve_start: u64,
131 reserve_end: u64,
132) {
133 if reserve_start >= reserve_end {
134 return;
135 }
136
137 let mut i = 0usize;
138 while i < *len {
139 let region = map[i];
140 if !matches!(
141 region.kind,
142 boot::entry::MemoryKind::Free | boot::entry::MemoryKind::Reclaim
143 ) {
144 i += 1;
145 continue;
146 }
147
148 let region_start = region.base;
149 let region_end = region.base.saturating_add(region.size);
150 if reserve_end <= region_start || reserve_start >= region_end {
151 i += 1;
152 continue;
153 }
154
155 let overlap_start = core::cmp::max(region_start, reserve_start);
156 let overlap_end = core::cmp::min(region_end, reserve_end);
157
158 if overlap_start <= region_start && overlap_end >= region_end {
159 map[i].kind = boot::entry::MemoryKind::Reserved;
160 i += 1;
161 continue;
162 }
163
164 if overlap_start <= region_start {
165 map[i].base = overlap_end;
166 map[i].size = region_end.saturating_sub(overlap_end);
167 i += 1;
168 continue;
169 }
170
171 if overlap_end >= region_end {
172 map[i].size = overlap_start.saturating_sub(region_start);
173 i += 1;
174 continue;
175 }
176
177 let left = boot::entry::MemoryRegion {
178 base: region_start,
179 size: overlap_start.saturating_sub(region_start),
180 kind: region.kind,
181 };
182 let right = boot::entry::MemoryRegion {
183 base: overlap_end,
184 size: region_end.saturating_sub(overlap_end),
185 kind: region.kind,
186 };
187
188 if *len + 1 > map.len() {
189 map[i] = left;
190 i += 1;
191 continue;
192 }
193
194 for j in (i + 1..*len).rev() {
195 map[j + 1] = map[j];
196 }
197 map[i] = left;
198 map[i + 1] = right;
199 *len += 1;
200 i += 2;
201 }
202}
203
204#[inline]
205fn count_free_like_regions(map: &[boot::entry::MemoryRegion], len: usize) -> usize {
206 map[..len]
207 .iter()
208 .filter(|region| {
209 matches!(
210 region.kind,
211 boot::entry::MemoryKind::Free | boot::entry::MemoryKind::Reclaim
212 )
213 })
214 .count()
215}
216
217#[cfg(feature = "selftest")]
219fn region_kind_for_addr(
220 map: &[boot::entry::MemoryRegion],
221 len: usize,
222 addr: u64,
223) -> Option<boot::entry::MemoryKind> {
224 map.iter().take(len).find_map(|r| {
225 let start = r.base;
226 let end = r.base.saturating_add(r.size);
227 if addr >= start && addr < end {
228 Some(r.kind)
229 } else {
230 None
231 }
232 })
233}
234
235#[panic_handler]
237fn panic_handler(info: &PanicInfo) -> ! {
238 boot::panic::panic_handler(info)
239}
240
241fn register_initfs_module(module: &strat9_abi::boot::ModuleEntry) {
243 let view = boot::modules::InitfsModule::from_physical(module, memory::hhdm_offset())
244 .unwrap_or_else(|error| panic!("Invalid initfs module: {}", error));
245 let path = view.name;
246 let base_virt = view.virtual_base as *const u8;
247 let len = view.len;
248 #[cfg(feature = "selftest")]
249 {
250 let data = unsafe { core::slice::from_raw_parts(base_virt, len.min(4)) };
252 if data.len() == 4 {
253 serial_println!(
254 "[init] /initfs/{} source magic={:02x}{:02x}{:02x}{:02x} size={}",
255 path,
256 data[0],
257 data[1],
258 data[2],
259 data[3],
260 len
261 );
262 }
263 }
264
265 if let Err(e) = vfs::register_initfs_file(path, base_virt, len) {
267 panic!("Failed to register /initfs/{}: {:?}", path, e);
268 } else {
269 serial_println!("[init] Registered /initfs/{} ({} bytes)", path, len);
270 }
271}
272
273fn register_boot_modules(modules: &[strat9_abi::boot::ModuleEntry]) {
278 if modules.is_empty() {
279 serial_println!("[init] No modules provided by bootloader");
280 return;
281 }
282
283 serial_println!("[init] Bootloader provided {} modules:", modules.len());
284 for module in modules {
285 register_initfs_module(module);
286 }
287}
288
289#[cfg(feature = "selftest")]
291fn log_boot_module_magics(stage: &str) {
292 crate::serial_println!(
293 "[init] Module magic [{}]: (FAT32 module loader pending)",
294 stage
295 );
296}
297
298#[cfg(not(feature = "selftest"))]
300fn log_boot_module_magics(_stage: &str) {}
301
302pub unsafe fn kernel_main(args: *const boot::entry::KernelArgs) -> ! {
304 crate::e9_mark!(b'K');
306
307 if crate::debug_cfg::SERIAL_ENABLED {
310 {
312 let thr: u16 = 0x3F8;
313 let lsr: u16 = 0x3F8 + 5;
314 let msg = b"[km] kernel_main enter\r\n";
315 for &b in msg {
316 loop {
317 let s: u8;
318 core::arch::asm!("in al, dx", out("al") s, in("dx") lsr, options(nomem, nostack, preserves_flags));
319 if s & 0x20 != 0 {
320 break;
321 }
322 }
323 core::arch::asm!("out dx, al", in("dx") thr, in("al") b, options(nomem, nostack, preserves_flags));
324 }
325 }
326 }
327
328 debug_assert!(
332 !arch::interrupts_enabled(),
333 "interrupts must be disabled at boot entry"
334 );
335
336 if crate::debug_cfg::SERIAL_ENABLED {
338 let thr: u16 = 0x3F8;
339 let lsr: u16 = 0x3F8 + 5;
340 let msg = b"[km] after debug_assert\r\n";
341 for &b in msg {
342 loop {
343 let s: u8;
344 core::arch::asm!("in al, dx", out("al") s, in("dx") lsr, options(nomem, nostack, preserves_flags));
345 if s & 0x20 != 0 {
346 break;
347 }
348 }
349 core::arch::asm!("out dx, al", in("dx") thr, in("al") b, options(nomem, nostack, preserves_flags));
350 }
351 }
352
353 arch::x86_64::boot_timestamp::init();
357
358 if crate::debug_cfg::SERIAL_ENABLED {
360 let thr: u16 = 0x3F8;
361 let lsr: u16 = 0x3F8 + 5;
362 let msg = b"[km] after boot_timestamp\r\n";
363 for &b in msg {
364 loop {
365 let s: u8;
366 core::arch::asm!("in al, dx", out("al") s, in("dx") lsr, options(nomem, nostack, preserves_flags));
367 if s & 0x20 != 0 {
368 break;
369 }
370 }
371 core::arch::asm!("out dx, al", in("dx") thr, in("al") b, options(nomem, nostack, preserves_flags));
372 }
373 }
374
375 if crate::debug_cfg::SERIAL_ENABLED {
381 let thr: u16 = 0x3F8;
382 let lsr: u16 = 0x3F8 + 5;
383 let msg = b"[km] before init_serial\r\n";
384 for &b in msg {
385 loop {
386 let s: u8;
387 core::arch::asm!("in al, dx", out("al") s, in("dx") lsr, options(nomem, nostack, preserves_flags));
388 if s & 0x20 != 0 {
389 break;
390 }
391 }
392 core::arch::asm!("out dx, al", in("dx") thr, in("al") b, options(nomem, nostack, preserves_flags));
393 }
394 }
395
396 crate::e9_mark!(b'L');
401 arch::serial::set_boot_log_prefix_enabled(true);
402 crate::e9_mark!(b'M');
403
404 init_logger();
405 crate::e9_mark!(b'N');
406 e9_mark!(b'T');
417 arch::tss::init();
418 e9_mark!(b'G');
419 arch::gdt::init();
420 e9_mark!(b'I');
421 arch::x86_64::idt::init();
422 e9_mark!(b'i');
423 if crate::debug_cfg::SERIAL_ENABLED {
430 let thr: u16 = 0x3F8;
431 let lsr: u16 = 0x3F8 + 5;
432 let msg = b"[km] IDT initialized\r\n";
433 for &b in msg {
434 loop {
435 let s: u8;
436 core::arch::asm!("in al, dx", out("al") s, in("dx") lsr, options(nomem, nostack, preserves_flags));
437 if s & 0x20 != 0 {
438 break;
439 }
440 }
441 core::arch::asm!("out dx, al", in("dx") thr, in("al") b, options(nomem, nostack, preserves_flags));
442 }
443 }
444
445 debug_assert!(
446 !arch::interrupts_enabled(),
447 "interrupts must be disabled after IDT init"
448 );
449 e9_mark!(b'4');
450
451 e9_mark!(b'a');
453 crate::arch::x86_64::cpuid::init();
454 e9_mark!(b'b');
455
456 e9_mark!(b'c');
458 crate::arch::x86_64::init_cpu_extensions();
459 e9_mark!(b'd');
460
461 boot::logger::set_extensions_ready();
463
464 e9_mark!(b'e');
466 crate::entropy::seed_from_rdrand();
467 e9_mark!(b'f');
468
469 e9_mark!(b'g');
471 crate::kaslr::init();
472 e9_mark!(b'h');
473
474 e9_mark!(b'i');
476 crate::crypto::init();
477 e9_mark!(b'j');
478
479 e9_mark!(b'k');
482 boot::panic::install_default_panic_hooks();
483 e9_mark!(b'l');
484 boot::symbols::init();
485 e9_mark!(b'm');
486
487 e9_mark!(b'V');
518 if args.is_null() {
519 serial_println!("[CRIT] No KernelArgs provided. System will hang.");
520 loop {
521 arch::hlt();
522 }
523 }
524 e9_mark!(b'v');
525
526 let args = &*args;
527 e9_mark!(b'W');
528 serial_println!("[init] KernelArgs at {:p}", args);
529 e9_mark!(b'w');
530
531 unsafe { BOOT_ARGS = Some(args) };
534 e9_mark!(b'X');
535
536 let magic = unsafe { core::ptr::read_unaligned(core::ptr::addr_of!(args.magic)) };
538 let abi_version = unsafe { core::ptr::read_unaligned(core::ptr::addr_of!(args.abi_version)) };
539 e9_mark!(b'x');
540
541 if magic != strat9_abi::boot::STRAT9_BOOT_MAGIC {
542 serial_println!(
543 "[CRIT] Bad KernelArgs magic: 0x{:08x} (expected 0x{:08x})",
544 magic,
545 strat9_abi::boot::STRAT9_BOOT_MAGIC
546 );
547 loop {
548 arch::hlt();
549 }
550 }
551 if abi_version != strat9_abi::boot::STRAT9_BOOT_ABI_VERSION {
552 serial_println!(
553 "[CRIT] Unsupported boot ABI version: {} (kernel expects {})",
554 abi_version,
555 strat9_abi::boot::STRAT9_BOOT_ABI_VERSION
556 );
557 loop {
558 arch::hlt();
559 }
560 }
561 e9_mark!(b'Y');
562
563 e9_mark!(b'z');
568
569 let hhdm = args.hhdm_offset;
575 memory::set_hhdm_offset(hhdm);
576 #[cfg(target_arch = "x86_64")]
577 if args.env_get("loader.paging") == Some("wx-uc-v1") {
578 unsafe { memory::paging::retire_uefi_identity_code() };
581 }
582 serial_println!("[init] HHDM offset: 0x{:x}", hhdm);
583
584 let memory_map_base =
585 unsafe { core::ptr::read_unaligned(core::ptr::addr_of!(args.memory_map_base)) };
586 let memory_map_size =
587 unsafe { core::ptr::read_unaligned(core::ptr::addr_of!(args.memory_map_size)) };
588 serial_println!(
589 "[init] Memory map: 0x{:x} ({} bytes)",
590 memory_map_base,
591 memory_map_size
592 );
593
594 log_boot_module_magics("pre-mm");
595
596 crate::e9_println!("MM pre-regions");
600 serial_println!("[init] Memory manager...");
601 serial_println!(
602 "[init] Memory map: 0x{:x} ({} bytes)",
603 memory_map_base,
604 memory_map_size
605 );
606 let regions = unsafe { args.memory_regions() }
609 .unwrap_or_else(|error| panic!("Invalid boot memory map: {}", error));
610 if regions.is_empty() {
611 panic!("Boot memory map is empty");
612 }
613 let boot_modules = unsafe { args.modules() }
614 .unwrap_or_else(|error| panic!("Invalid boot module table: {}", error));
615 boot::modules::validate_modules(boot_modules, hhdm)
616 .unwrap_or_else(|error| panic!("Invalid boot modules: {}", error));
617 serial_println!("[init] Memory regions count: {}", regions.len());
618 if let Some(first) = regions.first() {
619 serial_println!(
620 "[init] First region: base={:#x} size={:#x} kind={:?}",
621 first.base,
622 first.size,
623 first.kind
624 );
625 }
626 {
628 let mut i = 0usize;
629 while i < regions.len().min(16) {
630 let r = ®ions[i];
631 let k = (r.kind.0 as u8) + b'0';
633 let base = r.base;
634 let size = r.size;
635 unsafe {
636 core::arch::asm!(
637 "out 0xe9, al",
638 in("al") b'R', options(nomem, nostack)
639 );
640 let mut shift = 0i32;
642 while shift < 40 {
643 let nib = ((base >> shift) & 0xF) as u8;
644 let c = if nib < 10 {
645 b'0' + nib
646 } else {
647 b'a' + nib - 10
648 };
649 core::arch::asm!("out 0xe9, al", in("al") c, options(nomem, nostack));
650 shift += 4;
651 }
652 core::arch::asm!("out 0xe9, al", in("al") b'/', options(nomem, nostack));
653 shift = 0;
654 while shift < 40 {
655 let nib = ((size >> shift) & 0xF) as u8;
656 let c = if nib < 10 {
657 b'0' + nib
658 } else {
659 b'a' + nib - 10
660 };
661 core::arch::asm!("out 0xe9, al", in("al") c, options(nomem, nostack));
662 shift += 4;
663 }
664 core::arch::asm!("out 0xe9, al", in("al") b'/', options(nomem, nostack));
665 core::arch::asm!("out 0xe9, al", in("al") k, options(nomem, nostack));
666 core::arch::asm!("out 0xe9, al", in("al") b'\n', options(nomem, nostack));
667 }
668 i += 1;
669 }
670 }
671 crate::e9_println!("MM regions");
672 let mmap_work = unsafe { &mut *core::ptr::addr_of_mut!(MMAP_WORK) };
674 crate::e9_println!("MM work array");
675 let mmap_work_len = regions.len();
676 crate::e9_println!("MM len calc");
677 mmap_work[..mmap_work_len].copy_from_slice(regions);
678 crate::e9_println!("MM copy done");
679
680 let protected_ranges = [None; memory::boot_alloc::MAX_PROTECTED_RANGES];
683 crate::e9_println!("MM prot ranges");
684 memory::boot_alloc::set_protected_ranges(&protected_ranges);
685 crate::e9_println!("MM set prot done");
686
687 crate::e9_println!("MM pre-init-boot-alloc");
692 memory::boot_alloc::init_boot_allocator(&mmap_work[..mmap_work_len]);
693 crate::e9_println!("MM post-init-boot-alloc before serial");
694 crate::e9_mark!(b'1');
695 serial_println!("[init] Boot allocator ready.");
696 crate::e9_mark!(b'2');
697 serial_println!("[init] Boot allocator ready.");
698 crate::e9_mark!(b'3');
699
700 let total_ram = mmap_work[..mmap_work_len]
701 .iter()
702 .filter(|region| {
703 matches!(
704 region.kind,
705 boot::entry::MemoryKind::Free | boot::entry::MemoryKind::Reclaim
706 )
707 })
708 .map(|region| region.base.saturating_add(region.size))
709 .max()
710 .unwrap_or(0);
711 crate::e9_mark!(b'4');
712 let free_like_regions = count_free_like_regions(&mmap_work[..mmap_work_len], mmap_work_len);
713 crate::e9_mark!(b'5');
714 let metadata_bytes = memory::frame::metadata_size_for(total_ram) as usize;
715 crate::e9_mark!(b'6');
716 let boot_stats = memory::boot_alloc::boot_allocator_stats();
717 crate::e9_mark!(b'7');
718 crate::e9_println!("M7 boot-stats-done");
719 serial_println!(
720 "[init] Frame metadata plan: total_ram={:#x} free_regions={} bytes={} boot_free={} largest_boot_region={}",
721 total_ram,
722 free_like_regions,
723 metadata_bytes,
724 boot_stats.total_free_bytes as usize,
725 boot_stats.largest_region_bytes as usize,
726 );
727 crate::e9_mark!(b'8');
728
729 {
730 crate::e9_mark!(b'9');
731 let mut boot_alloc = memory::boot_alloc::get_boot_allocator().lock();
732 crate::e9_mark!(b'A');
733 memory::frame::init_metadata_array(total_ram, &mut *boot_alloc);
734 crate::e9_mark!(b'B');
735 }
736 crate::e9_mark!(b'C');
737 serial_println!("[init] Frame metadata ready.");
738
739 crate::e9_mark!(b'D');
742
743 memory::buddy::init_buddy_allocator(&mmap_work[..mmap_work_len]);
744 crate::e9_mark!(b'E');
745
746 serial_println!("[init] Buddy allocator ready.");
747 crate::e9_mark!(b'F');
748
749 {
756 use crate::boot::dtb_boot::KERNEL_STACK_SIZE;
757 let stack_phys = memory::boot_alloc::alloc_bytes_accessible(
758 KERNEL_STACK_SIZE,
759 16, );
761 if let Some(phys) = stack_phys {
762 let stack_top = memory::phys_to_virt(phys.as_u64()) + KERNEL_STACK_SIZE as u64;
763 serial_println!(
764 "[init] Kernel stack allocated: {:#x} - {:#x} ({} KB)",
765 memory::phys_to_virt(phys.as_u64()),
766 stack_top,
767 KERNEL_STACK_SIZE / 1024
768 );
769
770 extern "C" {
773 fn switch_stack(new_rsp: u64, entry: extern "C" fn() -> !) -> !;
774 }
775 extern "C" fn stack_switch_entry() -> ! {
776 crate::serial_println!("[init] Stack switch: entered new stack, continuing...");
791 loop {
792 unsafe {
793 core::arch::asm!("hlt");
794 }
795 }
796 }
797
798 serial_println!("[init] Stack allocated (switch deferred to Phase 7)");
802 } else {
803 serial_println!(
804 "[init] WARNING: kernel stack alloc failed, staying on bootstrap stack"
805 );
806 }
807 }
808
809 boot::config::apply_kernel_config();
812
813 memory::vmalloc::init();
815 serial_println!("[init] Vmalloc arena ready.");
816
817 debug_assert!(
818 !arch::interrupts_enabled(),
819 "interrupts must be disabled after buddy allocator init"
820 );
821
822 boot_milestone!("Memory manager ready");
823 arch::speaker::beep_phase(2);
824 log_boot_module_magics("post-buddy");
825
826 if crate::memory::buddy::get_allocator().lock().is_none() {
829 serial_println!("[CRIT] Buddy allocator self-test FAILED: allocator not initialized");
830 serial_println!("[CRIT] System halted.");
831 loop {
832 arch::x86_64::hlt();
833 }
834 }
835
836 crate::e9_println!("B5 pre-paging");
840 serial_println!("[init] Paging...");
841 memory::paging::init(hhdm);
842 crate::e9_println!("B6 post-paging");
843
844 memory::paging::map_all_ram(&mmap_work[..mmap_work_len]);
847
848 if args.framebuffer_addr != 0 && args.framebuffer_stride != 0 && args.framebuffer_height != 0 {
852 let fb_phys = if args.framebuffer_addr >= hhdm {
853 args.framebuffer_addr - hhdm
854 } else {
855 args.framebuffer_addr
856 };
857 let fb_size =
858 (args.framebuffer_stride as u64).saturating_mul(args.framebuffer_height as u64);
859 memory::paging::ensure_identity_map_range(fb_phys, fb_size);
860 serial_println!(
861 "[init] Framebuffer mapped: phys=0x{:x} size={} bytes",
862 fb_phys,
863 fb_size
864 );
865 }
866 serial_println!("[init] Paging initialized.");
867 boot_milestone!("Paging initialized");
868 arch::speaker::beep_phase(3);
869
870 serial_println!("[init] Console...");
874 arch::vga::init(
875 args.framebuffer_addr,
876 args.framebuffer_width,
877 args.framebuffer_height,
878 args.framebuffer_stride,
879 args.framebuffer_bpp,
880 args.framebuffer_red_mask_size,
881 args.framebuffer_red_mask_shift,
882 args.framebuffer_green_mask_size,
883 args.framebuffer_green_mask_shift,
884 args.framebuffer_blue_mask_size,
885 args.framebuffer_blue_mask_shift,
886 );
887 arch::vgabuf::vgabuf_flush_to_framebuffer();
889 vga_println!("[OK] Paging initialized");
890 vga_println!("[OK] Serial port initialized");
891 vga_println!("[OK] Memory manager active");
892
893 serial_println!("[init] TSS+GDT already initialized.");
897
898 serial_println!("[init] SYSCALL/SYSRET...");
902 vga_println!("[..] Initializing SYSCALL/SYSRET...");
903 arch::syscall::init();
904 serial_println!("[init] SYSCALL/SYSRET initialized.");
905 vga_println!("[OK] SYSCALL/SYSRET configured");
906
907 serial_println!("[init] Components (bootstrap)...");
911 vga_println!("[..] Initializing bootstrap components...");
912 if let Err(e) = component::init_all(component::InitStage::Bootstrap) {
913 serial_println!("[WARN] Some bootstrap components failed: {:?}", e);
914 }
915 serial_println!("[init] Bootstrap components initialized.");
916 vga_println!("[OK] Bootstrap components ready");
917
918 log_boot_module_magics("post-paging");
922
923 serial_println!("[init] Kernel address space...");
927 vga_println!("[..] Initializing kernel address space...");
928 memory::address_space::init_kernel_address_space();
929 serial_println!("[init] Kernel address space initialized.");
930 debug_assert!(
931 !arch::interrupts_enabled(),
932 "interrupts must be disabled after kernel address space init"
933 );
934 vga_println!("[OK] Kernel address space initialized");
935 log_boot_module_magics("post-kas");
936
937 serial_println!("[init] VFS...");
941 vga_println!("[..] Initializing virtual file system...");
942
943 vfs::init();
944
945 serial_println!("[init] VFS initialized.");
946 vga_println!("[OK] VFS initialized");
947 register_boot_modules(boot_modules);
948
949 log_boot_module_magics("post-cow");
950
951 serial_println!("[init] Interrupt controller...");
955 vga_println!("[..] Initializing interrupt controller...");
956
957 memory::paging::ensure_identity_map(args.acpi_rsdp_base);
959
960 let rsdp_virt = memory::phys_to_virt(args.acpi_rsdp_base);
961 let apic_active = init_apic_subsystem(rsdp_virt);
962
963 if !apic_active {
964 serial_println!("[init] APIC unavailable, falling back to legacy PIC");
966 vga_println!("[..] Falling back to legacy PIC...");
967 arch::pic::init(arch::pic::PIC1_OFFSET, arch::pic::PIC2_OFFSET);
968 arch::pic::disable();
969 arch::pic::enable_irq(0); arch::pic::enable_irq(1); serial_println!("[init] Legacy PIC initialized.");
972 vga_println!("[OK] Legacy PIC initialized (IRQ0: timer, IRQ1: keyboard)");
973 } else {
974 serial_println!("[init] APIC subsystem initialized.");
975 vga_println!("[OK] APIC + I/O APIC + APIC timer active");
976 }
977
978 if apic_active {
980 arch::tlb::init();
981 serial_println!("[init] TLB shootdown system initialized.");
982 debug_assert!(
983 !arch::interrupts_enabled(),
984 "interrupts must be disabled after TLB init"
985 );
986 }
987
988 if apic_active {
992 let bsp_apic_id = arch::apic::lapic_id();
993 arch::percpu::init_boot_cpu(bsp_apic_id);
994 arch::percpu::init_gs_base(0);
995 serial_println!("[init] SMP: booting secondary cores...");
996 vga_println!("[..] SMP: starting APs...");
997
998 match arch::smp::init() {
999 Ok(count) => {
1000 serial_println!("[init] SMP: {} core(s) online", count);
1001 vga_println!("[OK] SMP: {} core(s) online", count);
1002 }
1003 Err(e) => {
1004 serial_println!("[init] SMP init failed: {}", e);
1005 vga_println!("[WARN] SMP init failed: {}", e);
1006 }
1007 }
1008 } else {
1009 arch::percpu::init_boot_cpu(0);
1010 }
1011 boot_milestone!("APIC + SMP ready");
1012 arch::speaker::beep_phase(4);
1013
1014 arch::keyboard::init();
1015 serial_println!("[init] PS/2 keyboard controller initialized.");
1016
1017 if apic_active {
1021 let mouse_ok = arch::mouse::init();
1022
1023 if mouse_ok {
1024 serial_println!("[init] PS/2 mouse initialized.");
1025 vga_println!("[OK] PS/2 mouse ready");
1026 } else {
1027 serial_println!("[init] PS/2 mouse not found (optional).");
1028 }
1029 }
1030
1031 crate::e9_println!("B7 pre-sched");
1035 serial_println!("[init] Initializing scheduler...");
1036 vga_println!("[..] Setting up multitasking...");
1037 crate::process::task::Task::debug_print_layout();
1039 process::init_scheduler();
1040 crate::e9_println!("B8 post-sched");
1041
1042 if crate::process::scheduler::GLOBAL_SCHED_STATE
1044 .lock()
1045 .is_none()
1046 {
1047 serial_println!("[CRIT] Scheduler init failed: GLOBAL_SCHED_STATE is None");
1048 serial_println!("[CRIT] System halted.");
1049 loop {
1050 arch::x86_64::hlt();
1051 }
1052 }
1053
1054 debug_assert!(
1055 !arch::interrupts_enabled(),
1056 "interrupts must be disabled after scheduler init"
1057 );
1058
1059 if apic_active {
1065 debug_assert!(
1066 !arch::interrupts_enabled(),
1067 "interrupts must be disabled before APIC timer start"
1068 );
1069 serial_println!("[init] Starting APIC timer on BSP...");
1070 arch::timer::start_apic_timer_cached();
1071 }
1072
1073 serial_println!("[init] Scheduler initialized.");
1074 serial_println!("[trace][bsp] after init_scheduler");
1075 boot_milestone!("Scheduler + timer ready");
1076 arch::speaker::beep_phase(5);
1077 vga_println!("[OK] Multitasking enabled");
1078
1079 crate::e9_println!("B9 pre-kthread");
1083 serial_println!("[trace][bsp] before kthread init_all");
1084 serial_println!("[init] Components (kthread)...");
1085 vga_println!("[..] Initializing kthread components...");
1086
1087 if let Err(e) = component::init_all(component::InitStage::Kthread) {
1088 serial_println!("[WARN] Some kthread components failed: {:?}", e);
1089 }
1090
1091 serial_println!("[trace][bsp] after kthread init_all");
1092 serial_println!("[init] Kthread components initialized.");
1093 vga_println!("[OK] Kthread components ready");
1094
1095 crate::e9_println!("BA pre-hardware");
1099 serial_println!("[init] Components (hardware)...");
1100 vga_println!("[..] Initializing hardware components...");
1101 if let Err(e) = component::init_all(component::InitStage::Hardware) {
1102 serial_println!("[WARN] Some hardware components failed: {:?}", e);
1103 }
1104 serial_println!("[init] Hardware components initialized.");
1105 vga_println!("[OK] Hardware components ready");
1106 boot_milestone!("Hardware drivers ready");
1107
1108 #[cfg(feature = "selftest")]
1109 {
1110 serial_println!("[init] Creating self-test tasks...");
1114 vga_println!("[..] Adding self-test tasks...");
1115 process::selftest::create_selftest_tasks();
1116 serial_println!("[init] Self-test tasks created.");
1117 vga_println!("[OK] Self-test tasks added");
1118 }
1119
1120 #[cfg(not(feature = "selftest"))]
1124 {
1125 let mut init_task_id: Option<crate::process::TaskId> = None;
1129
1130 crate::e9_println!("BB pre-process");
1131 serial_println!("[init] Components (process)...");
1132 vga_println!("[..] Initializing process components...");
1133 if let Err(e) = component::init_all(component::InitStage::Process) {
1134 serial_println!("[WARN] Some process components failed: {:?}", e);
1135 }
1136 serial_println!("[init] Process components initialized.");
1137 vga_println!("[OK] Process components ready");
1138
1139 crate::e9_println!("BD device-report");
1145 serial_println!("[init] Checking for devices...");
1146 vga_println!("[..] Checking for devices...");
1147
1148 if let Some(blk) = hardware::storage::virtio_block::get_device() {
1149 use hardware::storage::virtio_block::BlockDevice;
1150 serial_println!(
1151 "[INFO] VirtIO block device found. Capacity: {} sectors",
1152 blk.sector_count()
1153 );
1154 vga_println!("[OK] VirtIO block driver loaded");
1155 } else {
1156 serial_println!("[WARN] No VirtIO block device found");
1157 vga_println!("[WARN] No VirtIO block device found");
1158 }
1159
1160 if let Some(ahci) = hardware::storage::ahci::get_device() {
1161 serial_println!(
1162 "[INFO] AHCI SATA device found. Capacity: {} sectors ({} MiB)",
1163 ahci.sector_count(),
1164 (ahci.sector_count() * 512) / 1048576, );
1166 vga_println!("[OK] AHCI SATA driver loaded");
1167 } else {
1168 serial_println!("[INFO] No AHCI SATA device found");
1169 }
1170
1171 if let Some(nvme) = hardware::storage::nvme::get_first_controller() {
1172 let nvme = nvme.lock();
1173 if let Some(ns) = nvme.get_namespace(0) {
1174 serial_println!(
1175 "[INFO] NVMe device found. Namespace {} - {} blocks @ {} bytes ({} MiB)",
1176 ns.nsid,
1177 ns.size,
1178 ns.block_size,
1179 (ns.size * ns.block_size as u64) / 1048576, );
1181 vga_println!("[OK] NVMe driver loaded");
1182 }
1183 } else {
1184 serial_println!("[INFO] No NVMe device found");
1185 }
1186
1187 {
1189 let ifaces = hardware::nic::list_interfaces();
1190 if ifaces.is_empty() {
1191 serial_println!("[WARN] No network devices found");
1192 vga_println!("[WARN] No network devices found");
1193 } else {
1194 for name in &ifaces {
1195 if let Some(dev) = hardware::nic::get_device(name) {
1196 let mac = dev.mac_address();
1197 serial_println!(
1198 "[INFO] Network {} ({}) MAC {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x} link={}",
1199 name, dev.name(),
1200 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1201 if dev.link_up() { "up" } else { "down" },
1202 );
1203 vga_println!("[OK] Network {} ({}) loaded", name, dev.name());
1204 }
1205 }
1206 }
1207 }
1208
1209 serial_println!("[init] Storage verification skipped (boot path)");
1210 vga_println!("[..] Storage verification skipped at boot");
1211
1212 let mut init_loaded = false;
1214
1215 for init_path in ["/initfs/init", "/initfs/strate-init"] {
1216 if let Ok(fd) = vfs::open(init_path, vfs::OpenFlags::READ) {
1217 let data = vfs::read_all(fd);
1218 let _ = vfs::close(fd);
1219 let data = match data {
1220 Ok(data) => data,
1221 Err(error) => {
1222 serial_println!("[init] Failed to read {}: {:?}", init_path, error);
1223 continue;
1224 }
1225 };
1226 let init_caps = [crate::silo::create_silo_admin_capability()];
1227 match process::elf::load_and_run_elf_with_caps(&data, "init", &init_caps) {
1228 Ok(task_id) => {
1229 init_task_id = Some(task_id);
1230 init_loaded = true;
1231 serial_println!("[init] ELF '{}' loaded as task 'init'.", init_path);
1232 break;
1233 }
1234 Err(e) => {
1235 serial_println!("[init] Failed to load init ELF: {}", e);
1236 }
1237 }
1238 }
1239 }
1240
1241 if !init_loaded {
1244 for module in boot_modules {
1247 let raw = module.name_str();
1248 unsafe {
1249 core::arch::asm!("out 0xe9, al", in("al") b'N', options(nomem, nostack));
1250 for b in raw.as_bytes() {
1251 core::arch::asm!("out 0xe9, al", in("al") *b, options(nomem, nostack));
1252 }
1253 core::arch::asm!("out 0xe9, al", in("al") b'\n', options(nomem, nostack));
1254 }
1255 let name = raw;
1256 if name == "init" || name == "strate-init" {
1257 let view = boot::modules::InitfsModule::from_physical(module, hhdm)
1258 .unwrap_or_else(|error| panic!("Invalid init module: {}", error));
1259 let elf_data = unsafe {
1260 core::slice::from_raw_parts(view.virtual_base as *const u8, view.len)
1261 };
1262 unsafe {
1264 let magic_ok = elf_data.len() >= 4
1265 && elf_data[0] == 0x7F
1266 && elf_data[1] == b'E'
1267 && elf_data[2] == b'L'
1268 && elf_data[3] == b'F';
1269 core::arch::asm!("out 0xe9, al", in("al") b'!', options(nomem, nostack));
1270 core::arch::asm!("out 0xe9, al", in("al") if magic_ok { b'Y' } else { b'N' }, options(nomem, nostack));
1271 core::arch::asm!("out 0xe9, al", in("al") b'\n', options(nomem, nostack));
1272 }
1273 let init_caps = [crate::silo::create_silo_admin_capability()];
1274 match process::elf::load_and_run_elf_with_caps(elf_data, "init", &init_caps) {
1275 Ok(task_id) => {
1276 init_task_id = Some(task_id);
1277 crate::e9_mark!(b'I');
1278 serial_println!(
1279 "[init] ELF loaded as task 'init' (from module table)."
1280 );
1281 }
1282 Err(e) => {
1283 let code = e.as_bytes().first().copied().unwrap_or(b'?');
1285 unsafe {
1286 core::arch::asm!("out 0xe9, al", in("al") b'X', options(nomem, nostack));
1287 core::arch::asm!("out 0xe9, al", in("al") code, options(nomem, nostack));
1288 core::arch::asm!("out 0xe9, al", in("al") b'\n', options(nomem, nostack));
1289 }
1290 serial_println!("[init] Failed to load init ELF: {}", e);
1291 }
1292 }
1293 break;
1294 }
1295 }
1296 }
1297 if let (Some(task_id), Some(device)) =
1298 (init_task_id, hardware::storage::virtio_block::get_device())
1299 {
1300 if let Some(task) = crate::process::get_task_by_id(task_id) {
1301 let cap = crate::capability::get_capability_manager().create_capability(
1302 crate::capability::ResourceType::Volume,
1303 device as *const _ as usize,
1304 crate::capability::CapPermissions {
1305 read: true,
1306 write: true,
1307 execute: false,
1308 grant: true,
1309 revoke: true,
1310 },
1311 );
1312 unsafe { (&mut *task.process.capabilities.get()).insert(cap) };
1313 serial_println!("[init] Granted volume capability to init");
1314 }
1315 }
1316 crate::e9_mark!(b'W');
1317
1318 match process::Task::new_kernel_task_with_stack(
1319 shell::shell_main,
1320 "chevron-shell",
1321 process::TaskPriority::Normal,
1322 64 * 1024,
1323 ) {
1324 Ok(shell_task) => {
1325 process::add_task(shell_task);
1326 crate::e9_mark!(b'w');
1327 serial_println!("[init] Chevron shell ready.");
1328 }
1329 Err(e) => {
1330 serial_println!("[WARN] Failed to create shell task: {}", e);
1331 }
1332 }
1333 #[cfg(target_arch = "x86_64")]
1334 {
1335 match process::Task::new_kernel_task_with_stack(
1336 shell::mouse_task_main,
1337 "console-mouse",
1338 process::TaskPriority::Normal,
1339 64 * 1024,
1340 ) {
1341 Ok(task) => process::add_task(task),
1342 Err(err) => serial_println!("[WARN] Mouse task unavailable: {}", err),
1343 }
1344 match process::Task::new_kernel_task_with_stack(
1345 arch::x86_64::vgabuf::console_task_main,
1346 "console-render",
1347 process::TaskPriority::Normal,
1348 64 * 1024,
1349 ) {
1350 Ok(task) => process::add_task(task),
1351 Err(err) => serial_println!("[WARN] Console task unavailable: {}", err),
1352 }
1353 match process::Task::new_kernel_task_with_stack(
1354 arch::x86_64::serial::serial_task_main,
1355 "serial-output",
1356 process::TaskPriority::Low,
1357 32 * 1024,
1358 ) {
1359 Ok(task) => process::add_task(task),
1360 Err(err) => serial_println!("[WARN] Serial task unavailable: {}", err),
1361 }
1362 }
1363 crate::e9_mark!(b'Y');
1364 if let Ok(status_task) = process::Task::new_kernel_task_with_stack(
1365 arch::vga::status_line_task_main,
1366 "status-line",
1367 process::TaskPriority::Low,
1368 64 * 1024,
1369 ) {
1370 process::add_task(status_task);
1371 crate::e9_mark!(b'y');
1372 crate::debug_cfg::set_vga_debug_live(false);
1375 }
1376 }
1377 #[cfg(feature = "selftest")]
1378 {
1379 serial_println!("[init] Selftest mode: skipping process services and virtio drivers");
1380 }
1381
1382 crate::arch::keyboard_layout::set_french_layout();
1384 crate::e9_mark!(b'F');
1385
1386 if apic_active {
1390 arch::smp::open_ap_scheduler_gate();
1391 }
1392 crate::e9_mark!(b'G');
1393 crate::e9_println!("BC pre-schedule");
1394 crate::e9_mark!(b'H');
1395 boot_milestone!("Boot complete ! Now entering in scheduler");
1396 arch::speaker::beep_startup();
1397 serial_println!("[init] Boot complete. Starting preemptive scheduler...");
1398 vga_println!("[OK] Starting multitasking (preemptive)");
1399 arch::serial::set_boot_log_prefix_enabled(false);
1400
1401 serial_force_println!("[trace][bsp] schedule start (never returns)");
1407 process::schedule();
1408}
1409
1410fn init_apic_subsystem(rsdp_vaddr: u64) -> bool {
1415 use arch::{apic, ioapic, pic, timer};
1416 use timer::TIMER_HZ;
1417
1418 if !apic::is_present() {
1420 log::warn!("APIC: not present (CPUID)");
1421 return false;
1422 }
1423 serial_println!("[init] 6a. APIC present (CPUID)");
1424
1425 match acpi::init(rsdp_vaddr) {
1427 Ok(true) => {}
1428 Ok(false) => {
1429 log::warn!("APIC: no RSDP from bootloader");
1430 return false;
1431 }
1432 Err(e) => {
1433 log::warn!("APIC: ACPI init failed: {}", e);
1434 return false;
1435 }
1436 }
1437 serial_println!("[init] 6b. ACPI RSDP validated");
1438
1439 let madt_info = match acpi::madt::parse_madt() {
1441 Some(info) => info,
1442 None => {
1443 log::warn!("APIC: MADT not found");
1444 return false;
1445 }
1446 };
1447 serial_println!("[init] 6c. MADT parsed");
1448
1449 if let Some(mcfg) = acpi::mcfg::parse_mcfg() {
1450 serial_println!(
1451 "[init] 6c+. MCFG parsed ({} segment(s))",
1452 mcfg.entries.len()
1453 );
1454 for entry in mcfg.entries.iter() {
1455 log::info!(
1456 "ACPI: MCFG seg={} ecam={:#x} buses={}..{} ({} bus(es))",
1457 entry.segment_group,
1458 entry.base_address,
1459 entry.start_bus,
1460 entry.end_bus,
1461 entry.bus_count()
1462 );
1463 }
1464 } else {
1465 serial_println!("[init] 6c+. MCFG not found");
1466 }
1467
1468 if let Some(ivrs) = acpi::ivrs::Ivrs::get() {
1470 let dev_entry_count = unsafe {
1471 core::ptr::read_unaligned(core::ptr::addr_of!(ivrs.header().dev_entry_count))
1472 };
1473 serial_println!(
1474 "[init] 6c++. IVRS parsed (flags: draint={}, coherent={}, {} device entries)",
1475 ivrs.header().has_draint(),
1476 ivrs.header().is_coherent(),
1477 dev_entry_count,
1478 );
1479 ivrs.dump();
1480 } else {
1481 serial_println!("[init] 6c++. IVRS not found (no AMD IOMMU)");
1482 }
1483
1484 memory::paging::ensure_identity_map(madt_info.local_apic_address);
1487 apic::init(madt_info.local_apic_address);
1488 serial_println!("[init] 6d. Local APIC initialized");
1489
1490 if madt_info.io_apic_count == 0 {
1492 log::warn!("APIC: no I/O APIC in MADT");
1493 return false;
1494 }
1495 let Some(io_apic_entry) = madt_info.io_apics[0] else {
1496 log::warn!("APIC: MADT I/O APIC entry[0] missing");
1497 return false;
1498 };
1499 memory::paging::ensure_identity_map(io_apic_entry.address as u64);
1501 ioapic::init(io_apic_entry.address, io_apic_entry.gsi_base);
1502 serial_println!("[init] 6e. I/O APIC initialized");
1503
1504 pic::init(pic::PIC1_OFFSET, pic::PIC2_OFFSET);
1510 pic::disable_permanently();
1511 pic::enable_irq(1);
1512 pic::enable_irq(2);
1513 pic::enable_irq(12);
1514 serial_println!("[init] 6f. Legacy PIC remapped; PS/2 IRQ1/IRQ12 left enabled");
1515
1516 let lapic_id = apic::lapic_id();
1519 ioapic::route_legacy_irq(0, lapic_id, 0x20, &madt_info.overrides);
1520 ioapic::mask_legacy_irq(1, &madt_info.overrides);
1521 ioapic::mask_legacy_irq(12, &madt_info.overrides);
1522
1523 ioapic::store_madt_overrides(&madt_info.overrides);
1525
1526 serial_println!("[init] 6g. IRQ0->vec 0x20 via IOAPIC; IRQ1/IRQ12 via PIC");
1527
1528 serial_println!("[init] 6h. Calibrating APIC timer using PIT channel 2...");
1530 serial_println!(
1531 "[timer] ================================ TIMER INIT ================================"
1532 );
1533
1534 let ticks_per_10ms = timer::calibrate_apic_timer();
1535
1536 if ticks_per_10ms == 0 {
1537 log::error!("APIC: timer calibration FAILED");
1538 log::warn!("Falling back to legacy PIT timer at 100Hz");
1539
1540 serial_println!("[timer] APIC calibration failed, initializing PIT fallback...");
1543 timer::init_pit(TIMER_HZ as u32);
1544 serial_println!(
1545 "[timer] PIT initialized at {}Hz ({} ms/tick)",
1546 TIMER_HZ,
1547 1_000 / TIMER_HZ
1548 );
1549 serial_println!("[init] 6h. PIT timer initialized (fallback)");
1550
1551 serial_println!("[timer] ============================= TIMER INIT COMPLETE ============================");
1552 serial_println!("[timer] Mode: PIT (legacy fallback)");
1553 serial_println!("[timer] Frequency: {}Hz", TIMER_HZ);
1554 serial_println!("[timer] Interval: {} ms per tick", 1_000 / TIMER_HZ);
1555 serial_println!(
1556 "[timer] =========================================================================="
1557 );
1558
1559 } else {
1562 serial_println!("[init] 6h. APIC timer calibrated successfully");
1563
1564 timer::stop_pit();
1570 ioapic::mask_legacy_irq(0, &madt_info.overrides);
1571 serial_println!("[init] 6i+. Legacy PIT stopped and masked in IOAPIC");
1572
1573 serial_println!("[timer] ============================= TIMER INIT COMPLETE ============================");
1574 serial_println!("[timer] Mode: APIC (native)");
1575 serial_println!("[timer] Frequency: {}Hz", TIMER_HZ);
1576 serial_println!("[timer] Interval: {} ms per tick", 1_000 / TIMER_HZ);
1577 serial_println!("[timer] Ticks per 10ms: {}", ticks_per_10ms);
1578 serial_println!(
1579 "[timer] =========================================================================="
1580 );
1581 }
1582
1583 true
1584}
1585
1586#[cfg(not(target_arch = "x86_64"))]
1589pub mod boot_limine_shim {
1590 pub fn kernel_elf_bytes() -> Option<&'static [u8]> {
1591 None
1592 }
1593 pub fn test_syscalls_module() -> Option<(u64, u64)> {
1594 None
1595 }
1596
1597 pub fn test_mem_module() -> Option<(u64, u64)> {
1598 None
1599 }
1600
1601 pub fn test_mem_stressed_module() -> Option<(u64, u64)> {
1602 None
1603 }
1604
1605 pub fn test_mem_region_module() -> Option<(u64, u64)> {
1606 None
1607 }
1608
1609 pub fn test_mem_region_proc_module() -> Option<(u64, u64)> {
1610 None
1611 }
1612
1613 pub fn test_exec_module() -> Option<(u64, u64)> {
1614 None
1615 }
1616
1617 pub fn test_exec_helper_module() -> Option<(u64, u64)> {
1618 None
1619 }
1620
1621 pub fn fs_ext4_module() -> Option<(u64, u64)> {
1622 None
1623 }
1624
1625 pub fn strate_fs_ramfs_module() -> Option<(u64, u64)> {
1626 None
1627 }
1628
1629 pub fn init_module() -> Option<(u64, u64)> {
1630 None
1631 }
1632
1633 pub fn console_admin_module() -> Option<(u64, u64)> {
1634 None
1635 }
1636
1637 pub fn strate_net_module() -> Option<(u64, u64)> {
1638 None
1639 }
1640
1641 pub fn strate_bus_module() -> Option<(u64, u64)> {
1642 None
1643 }
1644
1645 pub fn dhcp_client_module() -> Option<(u64, u64)> {
1646 None
1647 }
1648
1649 pub fn ping_module() -> Option<(u64, u64)> {
1650 None
1651 }
1652
1653 pub fn telnetd_module() -> Option<(u64, u64)> {
1654 None
1655 }
1656
1657 pub fn udp_tool_module() -> Option<(u64, u64)> {
1658 None
1659 }
1660
1661 pub fn strate_wasm_module() -> Option<(u64, u64)> {
1662 None
1663 }
1664
1665 pub fn hello_wasm_module() -> Option<(u64, u64)> {
1666 None
1667 }
1668
1669 pub fn wasm_test_toml_module() -> Option<(u64, u64)> {
1670 None
1671 }
1672
1673 pub fn strate_webrtc_module() -> Option<(u64, u64)> {
1674 None
1675 }
1676
1677 pub fn web_admin_module() -> Option<(u64, u64)> {
1678 None
1679 }
1680}
1681
1682pub mod x86_crate_shim {
1685 #[cfg(target_arch = "x86_64")]
1686 pub use ::x86_64::*;
1687 #[cfg(target_arch = "x86_64")]
1688 pub use ::x86_64::{instructions, registers, structures};
1689
1690 #[cfg(not(target_arch = "x86_64"))]
1691 pub use crate::arch::x86_64::*;
1692}