1use limine::{modules::InternalModule, request::*, BaseRevision};
7
8use crate::serial_println;
9
10#[used]
12#[link_section = ".requests"]
13static BASE_REVISION: BaseRevision = BaseRevision::new();
14
15#[used]
17#[link_section = ".requests"]
18static MEMORY_MAP: MemoryMapRequest = MemoryMapRequest::new();
19
20#[used]
22#[link_section = ".requests"]
23static FRAMEBUFFER: FramebufferRequest = FramebufferRequest::new();
24
25#[used]
27#[link_section = ".requests"]
28static EXECUTABLE_ADDRESS: ExecutableAddressRequest = ExecutableAddressRequest::new();
29
30#[used]
32#[link_section = ".requests"]
33static EXEC_CMDLINE: ExecutableCmdlineRequest = ExecutableCmdlineRequest::new();
34
35#[used]
37#[link_section = ".requests"]
38static EXECUTABLE_FILE: ExecutableFileRequest = ExecutableFileRequest::new();
39
40#[used]
42#[link_section = ".requests"]
43static RSDP: RsdpRequest = RsdpRequest::new();
44
45#[used]
47#[link_section = ".requests"]
48static HHDM: HhdmRequest = HhdmRequest::new();
49
50#[used]
52#[link_section = ".requests"]
53static STACK_SIZE: StackSizeRequest = StackSizeRequest::new().with_size(0x80000); static TEST_PID_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/test_pid");
57
58static TEST_SYSCALLS_MODULE: InternalModule =
60 InternalModule::new().with_path(c"/initfs/test_syscalls");
61
62static TEST_MEM_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/test_mem");
64
65static TEST_MEM_STRESSED_MODULE: InternalModule =
67 InternalModule::new().with_path(c"/initfs/test_mem_stressed");
68
69static TEST_MEM_REGION_MODULE: InternalModule =
71 InternalModule::new().with_path(c"/initfs/test_mem_region");
72
73static TEST_MEM_REGION_PROC_MODULE: InternalModule =
75 InternalModule::new().with_path(c"/initfs/test_mem_region_proc");
76
77static TEST_EXEC_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/test_exec");
79
80static TEST_EXEC_HELPER_MODULE: InternalModule =
82 InternalModule::new().with_path(c"/initfs/test_exec_helper");
83
84static EXT4_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/fs-ext4");
86
87static RAM_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/strate-fs-ramfs");
89
90static INIT_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/init");
92
93static CONSOLE_ADMIN_MODULE: InternalModule =
95 InternalModule::new().with_path(c"/initfs/console-admin");
96static STRATE_NET_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/strate-net");
98
99static STRATE_BUS_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/strate-bus");
101
102static DHCP_CLIENT_MODULE: InternalModule =
104 InternalModule::new().with_path(c"/initfs/bin/dhcp-client");
105
106static PING_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/bin/ping");
108
109static TELNETD_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/bin/telnetd");
111
112static UDP_TOOL_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/bin/udp-tool");
114
115static WEB_ADMIN_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/bin/web-admin");
117
118static STRATE_WASM_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/strate-wasm");
120
121static STRATE_WEBRTC_MODULE: InternalModule =
123 InternalModule::new().with_path(c"/initfs/strate-webrtc");
124
125static HELLO_WASM_MODULE: InternalModule =
127 InternalModule::new().with_path(c"/initfs/bin/hello.wasm");
128
129static WASM_TEST_TOML_MODULE: InternalModule =
131 InternalModule::new().with_path(c"/initfs/wasm-test.toml");
132
133#[used]
135#[link_section = ".requests"]
136static MODULES: ModuleRequest = ModuleRequest::new().with_internal_modules(&[
137 &TEST_PID_MODULE,
138 &TEST_SYSCALLS_MODULE,
139 &TEST_MEM_MODULE,
140 &TEST_MEM_STRESSED_MODULE,
141 &TEST_MEM_REGION_MODULE,
142 &TEST_MEM_REGION_PROC_MODULE,
143 &TEST_EXEC_MODULE,
144 &TEST_EXEC_HELPER_MODULE,
145 &EXT4_MODULE,
146 &RAM_MODULE,
147 &INIT_MODULE,
148 &CONSOLE_ADMIN_MODULE,
149 &STRATE_NET_MODULE,
150 &STRATE_BUS_MODULE,
151 &DHCP_CLIENT_MODULE,
152 &PING_MODULE,
153 &TELNETD_MODULE,
154 &UDP_TOOL_MODULE,
155 &WEB_ADMIN_MODULE,
156 &STRATE_WASM_MODULE,
157 &STRATE_WEBRTC_MODULE,
158 &HELLO_WASM_MODULE,
159 &WASM_TEST_TOML_MODULE,
160]);
161
162static mut FS_EXT4_MODULE: Option<(u64, u64)> = None;
164static mut TEST_MEM_ELF_MODULE: Option<(u64, u64)> = None;
166static mut TEST_SYSCALLS_ELF_MODULE: Option<(u64, u64)> = None;
168static mut TEST_MEM_STRESSED_ELF_MODULE: Option<(u64, u64)> = None;
170static mut TEST_MEM_REGION_ELF_MODULE: Option<(u64, u64)> = None;
172static mut TEST_MEM_REGION_PROC_ELF_MODULE: Option<(u64, u64)> = None;
174static mut TEST_EXEC_ELF_MODULE: Option<(u64, u64)> = None;
176static mut TEST_EXEC_HELPER_ELF_MODULE: Option<(u64, u64)> = None;
178static mut STRATE_FS_RAMFS_MODULE: Option<(u64, u64)> = None;
180static mut INIT_ELF_MODULE: Option<(u64, u64)> = None;
182static mut CONSOLE_ADMIN_ELF_MODULE: Option<(u64, u64)> = None;
184static mut STRATE_NET_ELF_MODULE: Option<(u64, u64)> = None;
186static mut STRATE_BUS_ELF_MODULE: Option<(u64, u64)> = None;
188static mut DHCP_CLIENT_ELF_MODULE: Option<(u64, u64)> = None;
190static mut PING_ELF_MODULE: Option<(u64, u64)> = None;
192static mut TELNETD_ELF_MODULE: Option<(u64, u64)> = None;
194
195static mut UDP_TOOL_ELF_MODULE: Option<(u64, u64)> = None;
197static mut WEB_ADMIN_ELF_MODULE: Option<(u64, u64)> = None;
199static mut STRATE_WASM_ELF_MODULE: Option<(u64, u64)> = None;
201static mut STRATE_WEBRTC_ELF_MODULE: Option<(u64, u64)> = None;
203static mut HELLO_WASM_FILE_MODULE: Option<(u64, u64)> = None;
205static mut WASM_TEST_TOML_FILE_MODULE: Option<(u64, u64)> = None;
207
208const MAX_BOOT_MEMORY_REGIONS: usize = 256;
209static mut BOOT_MEMORY_MAP: [super::entry::MemoryRegion; MAX_BOOT_MEMORY_REGIONS] =
210 [super::entry::MemoryRegion {
211 base: 0,
212 size: 0,
213 kind: super::entry::MemoryKind::Reserved,
214 }; MAX_BOOT_MEMORY_REGIONS];
215static mut BOOT_MEMORY_MAP_LEN: usize = 0;
216
217pub fn fs_ext4_module() -> Option<(u64, u64)> {
219 unsafe { FS_EXT4_MODULE }
221}
222
223pub fn test_mem_module() -> Option<(u64, u64)> {
225 unsafe { TEST_MEM_ELF_MODULE }
227}
228
229pub fn test_syscalls_module() -> Option<(u64, u64)> {
231 unsafe { TEST_SYSCALLS_ELF_MODULE }
233}
234
235pub fn test_mem_stressed_module() -> Option<(u64, u64)> {
237 unsafe { TEST_MEM_STRESSED_ELF_MODULE }
239}
240
241pub fn test_mem_region_module() -> Option<(u64, u64)> {
243 unsafe { TEST_MEM_REGION_ELF_MODULE }
245}
246
247pub fn test_mem_region_proc_module() -> Option<(u64, u64)> {
249 unsafe { TEST_MEM_REGION_PROC_ELF_MODULE }
251}
252
253pub fn test_exec_module() -> Option<(u64, u64)> {
255 unsafe { TEST_EXEC_ELF_MODULE }
257}
258
259pub fn test_exec_helper_module() -> Option<(u64, u64)> {
261 unsafe { TEST_EXEC_HELPER_ELF_MODULE }
263}
264
265pub fn strate_fs_ramfs_module() -> Option<(u64, u64)> {
267 unsafe { STRATE_FS_RAMFS_MODULE }
269}
270
271pub fn init_module() -> Option<(u64, u64)> {
273 unsafe { INIT_ELF_MODULE }
275}
276
277pub fn console_admin_module() -> Option<(u64, u64)> {
279 unsafe { CONSOLE_ADMIN_ELF_MODULE }
281}
282
283pub fn strate_net_module() -> Option<(u64, u64)> {
285 unsafe { STRATE_NET_ELF_MODULE }
287}
288
289pub fn strate_bus_module() -> Option<(u64, u64)> {
291 unsafe { STRATE_BUS_ELF_MODULE }
293}
294
295pub fn dhcp_client_module() -> Option<(u64, u64)> {
297 unsafe { DHCP_CLIENT_ELF_MODULE }
299}
300
301pub fn ping_module() -> Option<(u64, u64)> {
303 unsafe { PING_ELF_MODULE }
305}
306
307pub fn telnetd_module() -> Option<(u64, u64)> {
309 unsafe { TELNETD_ELF_MODULE }
311}
312
313pub fn udp_tool_module() -> Option<(u64, u64)> {
315 unsafe { UDP_TOOL_ELF_MODULE }
317}
318
319pub fn web_admin_module() -> Option<(u64, u64)> {
321 unsafe { WEB_ADMIN_ELF_MODULE }
323}
324
325pub fn strate_wasm_module() -> Option<(u64, u64)> {
327 unsafe { STRATE_WASM_ELF_MODULE }
329}
330
331pub fn strate_webrtc_module() -> Option<(u64, u64)> {
333 unsafe { STRATE_WEBRTC_ELF_MODULE }
335}
336
337pub fn hello_wasm_module() -> Option<(u64, u64)> {
339 unsafe { HELLO_WASM_FILE_MODULE }
341}
342
343pub fn wasm_test_toml_module() -> Option<(u64, u64)> {
345 unsafe { WASM_TEST_TOML_FILE_MODULE }
347}
348
349fn path_matches(module_path: &[u8], expected_path: &[u8]) -> bool {
351 let expected_no_leading = expected_path.strip_prefix(b"/").unwrap_or(expected_path);
352 module_path == expected_path
353 || module_path.ends_with(expected_path)
354 || module_path == expected_no_leading
355 || module_path.ends_with(expected_no_leading)
356}
357
358#[inline]
360const fn module_addr_to_phys(addr: u64, hhdm_offset: u64) -> u64 {
361 if hhdm_offset != 0 && addr >= hhdm_offset {
362 addr - hhdm_offset
363 } else {
364 addr
365 }
366}
367
368#[derive(Default, Clone, Copy)]
369struct ResolvedModules {
370 test_pid: Option<(u64, u64)>,
371 test_syscalls: Option<(u64, u64)>,
372 test_mem: Option<(u64, u64)>,
373 test_mem_stressed: Option<(u64, u64)>,
374 test_mem_region: Option<(u64, u64)>,
375 test_mem_region_proc: Option<(u64, u64)>,
376 test_exec: Option<(u64, u64)>,
377 test_exec_helper: Option<(u64, u64)>,
378 fs_ext4: Option<(u64, u64)>,
379 fs_ram: Option<(u64, u64)>,
380 init: Option<(u64, u64)>,
381 console_admin: Option<(u64, u64)>,
382 strate_net: Option<(u64, u64)>,
383 strate_bus: Option<(u64, u64)>,
384 dhcp_client: Option<(u64, u64)>,
385 ping: Option<(u64, u64)>,
386 telnetd: Option<(u64, u64)>,
387
388 udp_tool: Option<(u64, u64)>,
389 web_admin: Option<(u64, u64)>,
390 strate_wasm: Option<(u64, u64)>,
391 strate_webrtc: Option<(u64, u64)>,
392 hello_wasm: Option<(u64, u64)>,
393 wasm_test_toml: Option<(u64, u64)>,
394}
395
396fn resolve_modules_once(modules: &[&limine::file::File], hhdm_offset: u64) -> ResolvedModules {
398 let mut resolved = ResolvedModules::default();
399 for module in modules {
400 let path = module.path().to_bytes();
401 let info = (
402 module_addr_to_phys(module.addr() as u64, hhdm_offset),
403 module.size(),
404 );
405 if path_matches(path, b"/initfs/test_pid") {
406 resolved.test_pid = Some(info);
407 } else if path_matches(path, b"/initfs/test_syscalls") {
408 resolved.test_syscalls = Some(info);
409 } else if path_matches(path, b"/initfs/test_mem") {
410 resolved.test_mem = Some(info);
411 } else if path_matches(path, b"/initfs/test_mem_stressed") {
412 resolved.test_mem_stressed = Some(info);
413 } else if path_matches(path, b"/initfs/test_mem_region") {
414 resolved.test_mem_region = Some(info);
415 } else if path_matches(path, b"/initfs/test_mem_region_proc") {
416 resolved.test_mem_region_proc = Some(info);
417 } else if path_matches(path, b"/initfs/test_exec") {
418 resolved.test_exec = Some(info);
419 } else if path_matches(path, b"/initfs/test_exec_helper") {
420 resolved.test_exec_helper = Some(info);
421 } else if path_matches(path, b"/initfs/fs-ext4") {
422 resolved.fs_ext4 = Some(info);
423 } else if path_matches(path, b"/initfs/strate-fs-ramfs") {
424 resolved.fs_ram = Some(info);
425 } else if path_matches(path, b"/initfs/init") {
426 resolved.init = Some(info);
427 } else if path_matches(path, b"/initfs/console-admin") {
428 resolved.console_admin = Some(info);
429 } else if path_matches(path, b"/initfs/strate-net") {
430 resolved.strate_net = Some(info);
431 } else if path_matches(path, b"/initfs/strate-bus") {
432 resolved.strate_bus = Some(info);
433 } else if path_matches(path, b"/initfs/bin/dhcp-client") {
434 resolved.dhcp_client = Some(info);
435 } else if path_matches(path, b"/initfs/bin/ping") {
436 resolved.ping = Some(info);
437 } else if path_matches(path, b"/initfs/bin/telnetd") {
438 resolved.telnetd = Some(info);
439 } else if path_matches(path, b"/initfs/bin/udp-tool") {
440 resolved.udp_tool = Some(info);
441 } else if path_matches(path, b"/initfs/bin/web-admin") {
442 resolved.web_admin = Some(info);
443 } else if path_matches(path, b"/initfs/strate-wasm") {
444 resolved.strate_wasm = Some(info);
445 } else if path_matches(path, b"/initfs/strate-webrtc") {
446 resolved.strate_webrtc = Some(info);
447 } else if path_matches(path, b"/initfs/bin/hello.wasm") {
448 resolved.hello_wasm = Some(info);
449 } else if path_matches(path, b"/initfs/wasm-test.toml") {
450 resolved.wasm_test_toml = Some(info);
451 }
452 }
453 resolved
454}
455
456fn map_limine_region_kind(kind: limine::memory_map::EntryType) -> super::entry::MemoryKind {
458 if kind == limine::memory_map::EntryType::USABLE {
459 super::entry::MemoryKind::Free
460 } else if kind == limine::memory_map::EntryType::ACPI_RECLAIMABLE {
461 super::entry::MemoryKind::Reclaim
462 } else {
463 super::entry::MemoryKind::Reserved
464 }
465}
466
467#[used]
469#[link_section = ".requests_start_marker"]
470static _START_MARKER: RequestsStartMarker = RequestsStartMarker::new();
471
472#[used]
473#[link_section = ".requests_end_marker"]
474static _END_MARKER: RequestsEndMarker = RequestsEndMarker::new();
475
476#[inline(always)]
478fn hlt_loop() -> ! {
479 loop {
480 unsafe {
481 core::arch::asm!("hlt", options(nomem, nostack, preserves_flags));
482 }
483 }
484}
485
486#[no_mangle]
495#[allow(static_mut_refs)]
496pub unsafe extern "C" fn kmain() -> ! {
497 assert!(BASE_REVISION.is_supported());
499
500 {
502 let mut early_port = unsafe { uart_16550::SerialPort::new(0x3F8) };
504 early_port.init();
505 let _ = core::fmt::Write::write_str(
506 &mut early_port,
507 "[kmain] *** Strat9-OS kernel entry ***\r\n",
508 );
509 }
510
511 let (
513 fb_addr,
514 fb_width,
515 fb_height,
516 fb_stride,
517 fb_bpp,
518 fb_red_mask_size,
519 fb_red_mask_shift,
520 fb_green_mask_size,
521 fb_green_mask_shift,
522 fb_blue_mask_size,
523 fb_blue_mask_shift,
524 ) = if let Some(fb_response) = FRAMEBUFFER.get_response() {
525 if let Some(fb) = fb_response.framebuffers().next() {
526 (
527 fb.addr() as u64,
528 fb.width() as u32,
529 fb.height() as u32,
530 fb.pitch() as u32,
531 fb.bpp(),
532 fb.red_mask_size(),
533 fb.red_mask_shift(),
534 fb.green_mask_size(),
535 fb.green_mask_shift(),
536 fb.blue_mask_size(),
537 fb.blue_mask_shift(),
538 )
539 } else {
540 (0, 0, 0, 0, 0, 8, 16, 8, 8, 8, 0)
541 }
542 } else {
543 (0, 0, 0, 0, 0, 8, 16, 8, 8, 8, 0)
544 };
545
546 let rsdp_addr = RSDP.get_response().map(|r| r.address() as u64).unwrap_or(0);
548
549 if fb_addr != 0 && fb_width != 0 && fb_height != 0 {
551 let format = crate::hardware::video::framebuffer::PixelFormat {
552 red_mask: ((1 << fb_red_mask_size) - 1) << fb_red_mask_shift,
553 red_shift: fb_red_mask_shift as u8,
554 green_mask: ((1 << fb_green_mask_size) - 1) << fb_green_mask_shift,
555 green_shift: fb_green_mask_shift as u8,
556 blue_mask: ((1 << fb_blue_mask_size) - 1) << fb_blue_mask_shift,
557 blue_shift: fb_blue_mask_shift as u8,
558 bits_per_pixel: fb_bpp as u8,
559 };
560
561 if let Err(e) = crate::hardware::video::framebuffer::Framebuffer::init_limine(
562 fb_addr, fb_width, fb_height, fb_stride, format,
563 ) {
564 serial_println!("[limine] Framebuffer init failed: {}", e);
565 }
566 }
567
568 let hhdm_offset = HHDM.get_response().map(|r| r.offset()).unwrap_or(0);
570
571 let (memory_map_base, memory_map_size) = if let Some(memory_map_response) =
574 MEMORY_MAP.get_response()
575 {
576 let entries = memory_map_response.entries();
577 let count = core::cmp::min(entries.len(), MAX_BOOT_MEMORY_REGIONS);
578 unsafe {
579 BOOT_MEMORY_MAP_LEN = count;
580 for (i, entry) in entries.iter().take(count).enumerate() {
581 BOOT_MEMORY_MAP[i] = super::entry::MemoryRegion {
582 base: entry.base,
583 size: entry.length,
584 kind: map_limine_region_kind(entry.entry_type),
585 };
586 }
587 (
588 BOOT_MEMORY_MAP.as_ptr() as u64,
589 (BOOT_MEMORY_MAP_LEN * core::mem::size_of::<super::entry::MemoryRegion>()) as u64,
590 )
591 }
592 } else {
593 (0, 0)
594 };
595
596 let (fallback_elf_base, fallback_elf_size, ext4_base, ext4_size, ram_base, ram_size) =
599 if let Some(module_response) = MODULES.get_response() {
600 let modules = module_response.modules();
601 crate::serial_println!("[limine] modules reported: {}", modules.len());
602 for (idx, module) in modules.iter().enumerate() {
603 #[cfg(feature = "selftest")]
604 {
605 let raw_addr = module.addr() as u64;
606 let phys_addr = module_addr_to_phys(raw_addr, hhdm_offset);
607 let (m0, m1, m2, m3) = if module.size() >= 4 {
608 unsafe {
609 let p = raw_addr as *const u8;
610 (
611 core::ptr::read_volatile(p),
612 core::ptr::read_volatile(p.add(1)),
613 core::ptr::read_volatile(p.add(2)),
614 core::ptr::read_volatile(p.add(3)),
615 )
616 }
617 } else {
618 (0, 0, 0, 0)
619 };
620 crate::serial_println!(
621 "[limine] module[{}]: path='{}' addr={:#x} phys={:#x} magic={:02x}{:02x}{:02x}{:02x} size={}",
622 idx,
623 module.path().to_string_lossy(),
624 raw_addr,
625 phys_addr,
626 m0,
627 m1,
628 m2,
629 m3,
630 module.size()
631 );
632 }
633 #[cfg(not(feature = "selftest"))]
634 {
635 crate::serial_println!(
636 "[limine] module[{}]: path='{}' size={}",
637 idx,
638 module.path().to_string_lossy(),
639 module.size()
640 );
641 }
642 }
643 let resolved = resolve_modules_once(modules, hhdm_offset);
644 let (init_base, init_size) = resolved.test_pid.unwrap_or((0, 0));
645 let (test_syscalls_base, test_syscalls_size) = resolved.test_syscalls.unwrap_or((0, 0));
646 let (test_mem_base, test_mem_size) = resolved.test_mem.unwrap_or((0, 0));
647 let (test_mem_stressed_base, test_mem_stressed_size) =
648 resolved.test_mem_stressed.unwrap_or((0, 0));
649 let (test_mem_region_base, test_mem_region_size) =
650 resolved.test_mem_region.unwrap_or((0, 0));
651 let (test_mem_region_proc_base, test_mem_region_proc_size) =
652 resolved.test_mem_region_proc.unwrap_or((0, 0));
653 let (test_exec_base, test_exec_size) = resolved.test_exec.unwrap_or((0, 0));
654 let (test_exec_helper_base, test_exec_helper_size) =
655 resolved.test_exec_helper.unwrap_or((0, 0));
656 let (ext4_base, ext4_size) = resolved.fs_ext4.unwrap_or((0, 0));
657 let (ram_base, ram_size) = resolved.fs_ram.unwrap_or((0, 0));
658
659 if test_mem_base != 0 && test_mem_size != 0 {
660 unsafe { TEST_MEM_ELF_MODULE = Some((test_mem_base, test_mem_size)) };
661 crate::serial_println!(
662 "[limine] /initfs/test_mem found: base={:#x} size={}",
663 test_mem_base,
664 test_mem_size
665 );
666 }
667 if test_syscalls_base != 0 && test_syscalls_size != 0 {
668 unsafe {
669 TEST_SYSCALLS_ELF_MODULE = Some((test_syscalls_base, test_syscalls_size))
670 };
671 crate::serial_println!(
672 "[limine] /initfs/test_syscalls found: base={:#x} size={}",
673 test_syscalls_base,
674 test_syscalls_size
675 );
676 }
677 if test_mem_stressed_base != 0 && test_mem_stressed_size != 0 {
678 unsafe {
679 TEST_MEM_STRESSED_ELF_MODULE =
680 Some((test_mem_stressed_base, test_mem_stressed_size))
681 };
682 crate::serial_println!(
683 "[limine] /initfs/test_mem_stressed found: base={:#x} size={}",
684 test_mem_stressed_base,
685 test_mem_stressed_size
686 );
687 }
688 if test_mem_region_base != 0 && test_mem_region_size != 0 {
689 unsafe {
690 TEST_MEM_REGION_ELF_MODULE = Some((test_mem_region_base, test_mem_region_size))
691 };
692 crate::serial_println!(
693 "[limine] /initfs/test_mem_region found: base={:#x} size={}",
694 test_mem_region_base,
695 test_mem_region_size
696 );
697 } else {
698 crate::serial_println!(
699 "[limine] WARN: /initfs/test_mem_region not found in modules"
700 );
701 }
702 if test_mem_region_proc_base != 0 && test_mem_region_proc_size != 0 {
703 unsafe {
704 TEST_MEM_REGION_PROC_ELF_MODULE =
705 Some((test_mem_region_proc_base, test_mem_region_proc_size))
706 };
707 crate::serial_println!(
708 "[limine] /initfs/test_mem_region_proc found: base={:#x} size={}",
709 test_mem_region_proc_base,
710 test_mem_region_proc_size
711 );
712 } else {
713 crate::serial_println!(
714 "[limine] WARN: /initfs/test_mem_region_proc not found in modules"
715 );
716 }
717 if test_exec_base != 0 && test_exec_size != 0 {
718 unsafe { TEST_EXEC_ELF_MODULE = Some((test_exec_base, test_exec_size)) };
719 crate::serial_println!(
720 "[limine] /initfs/test_exec found: base={:#x} size={}",
721 test_exec_base,
722 test_exec_size
723 );
724 } else {
725 crate::serial_println!("[limine] WARN: /initfs/test_exec not found in modules");
726 }
727 if test_exec_helper_base != 0 && test_exec_helper_size != 0 {
728 unsafe {
729 TEST_EXEC_HELPER_ELF_MODULE =
730 Some((test_exec_helper_base, test_exec_helper_size))
731 };
732 crate::serial_println!(
733 "[limine] /initfs/test_exec_helper found: base={:#x} size={}",
734 test_exec_helper_base,
735 test_exec_helper_size
736 );
737 } else {
738 crate::serial_println!(
739 "[limine] WARN: /initfs/test_exec_helper not found in modules"
740 );
741 }
742
743 if let Some((base, size)) = resolved.init {
745 unsafe { INIT_ELF_MODULE = Some((base, size)) };
746 crate::serial_println!(
747 "[limine] /initfs/init found: base={:#x} size={}",
748 base,
749 size
750 );
751 } else {
752 crate::serial_println!("[limine] WARN: /initfs/init not found in modules");
753 }
754 if let Some((base, size)) = resolved.console_admin {
755 unsafe { CONSOLE_ADMIN_ELF_MODULE = Some((base, size)) };
756 crate::serial_println!(
757 "[limine] /initfs/console-admin found: base={:#x} size={}",
758 base,
759 size
760 );
761 } else {
762 crate::serial_println!("[limine] WARN: /initfs/console-admin not found in modules");
763 }
764 if let Some((base, size)) = resolved.strate_net {
765 unsafe { STRATE_NET_ELF_MODULE = Some((base, size)) };
766 crate::serial_println!(
767 "[limine] /initfs/strate-net found: base={:#x} size={}",
768 base,
769 size
770 );
771 } else {
772 crate::serial_println!("[limine] WARN: /initfs/strate-net not found in modules");
773 }
774 if let Some((base, size)) = resolved.strate_bus {
775 unsafe { STRATE_BUS_ELF_MODULE = Some((base, size)) };
776 crate::serial_println!(
777 "[limine] /initfs/strate-bus found: base={:#x} size={}",
778 base,
779 size
780 );
781 } else {
782 crate::serial_println!("[limine] WARN: /initfs/strate-bus not found in modules");
783 }
784 if let Some((base, size)) = resolved.dhcp_client {
785 unsafe { DHCP_CLIENT_ELF_MODULE = Some((base, size)) };
786 crate::serial_println!(
787 "[limine] /initfs/bin/dhcp-client found: base={:#x} size={}",
788 base,
789 size
790 );
791 } else {
792 crate::serial_println!(
793 "[limine] WARN: /initfs/bin/dhcp-client not found in modules"
794 );
795 }
796 if let Some((base, size)) = resolved.ping {
797 unsafe { PING_ELF_MODULE = Some((base, size)) };
798 crate::serial_println!(
799 "[limine] /initfs/bin/ping found: base={:#x} size={}",
800 base,
801 size
802 );
803 } else {
804 crate::serial_println!("[limine] WARN: /initfs/bin/ping not found in modules");
805 }
806 if let Some((base, size)) = resolved.telnetd {
807 unsafe { TELNETD_ELF_MODULE = Some((base, size)) };
808 crate::serial_println!(
809 "[limine] /initfs/bin/telnetd found: base={:#x} size={}",
810 base,
811 size
812 );
813 } else {
814 crate::serial_println!("[limine] WARN: /initfs/bin/telnetd not found in modules");
815 }
816
817 if let Some((base, size)) = resolved.udp_tool {
818 unsafe { UDP_TOOL_ELF_MODULE = Some((base, size)) };
819 crate::serial_println!(
820 "[limine] /initfs/bin/udp-tool found: base={:#x} size={}",
821 base,
822 size
823 );
824 } else {
825 crate::serial_println!("[limine] WARN: /initfs/bin/udp-tool not found in modules");
826 }
827 if let Some((base, size)) = resolved.web_admin {
828 unsafe { WEB_ADMIN_ELF_MODULE = Some((base, size)) };
829 crate::serial_println!(
830 "[limine] /initfs/bin/web-admin found: base={:#x} size={}",
831 base,
832 size
833 );
834 } else {
835 crate::serial_println!("[limine] WARN: /initfs/bin/web-admin not found in modules");
836 }
837 if let Some((base, size)) = resolved.strate_wasm {
838 unsafe { STRATE_WASM_ELF_MODULE = Some((base, size)) };
839 crate::serial_println!(
840 "[limine] /initfs/strate-wasm found: base={:#x} size={}",
841 base,
842 size
843 );
844 } else {
845 crate::serial_println!("[limine] WARN: /initfs/strate-wasm not found in modules");
846 }
847 if let Some((base, size)) = resolved.strate_webrtc {
848 unsafe { STRATE_WEBRTC_ELF_MODULE = Some((base, size)) };
849 crate::serial_println!(
850 "[limine] /initfs/strate-webrtc found: base={:#x} size={}",
851 base,
852 size
853 );
854 } else {
855 crate::serial_println!("[limine] WARN: /initfs/strate-webrtc not found in modules");
856 }
857 if let Some((base, size)) = resolved.hello_wasm {
858 unsafe { HELLO_WASM_FILE_MODULE = Some((base, size)) };
859 crate::serial_println!(
860 "[limine] /initfs/bin/hello.wasm found: base={:#x} size={}",
861 base,
862 size
863 );
864 } else {
865 crate::serial_println!(
866 "[limine] WARN: /initfs/bin/hello.wasm not found in modules"
867 );
868 }
869 if let Some((base, size)) = resolved.wasm_test_toml {
870 unsafe { WASM_TEST_TOML_FILE_MODULE = Some((base, size)) };
871 crate::serial_println!(
872 "[limine] /initfs/wasm-test.toml found: base={:#x} size={}",
873 base,
874 size
875 );
876 } else {
877 crate::serial_println!(
878 "[limine] WARN: /initfs/wasm-test.toml not found in modules"
879 );
880 }
881
882 if init_base == 0 {
883 crate::serial_println!("[limine] WARN: /initfs/test_pid not found in modules");
884 }
885 if ext4_base == 0 {
886 crate::serial_println!("[limine] WARN: /initfs/fs-ext4 not found in modules");
887 }
888 if ram_base == 0 {
889 crate::serial_println!(
890 "[limine] WARN: /initfs/strate-fs-ramfs not found in modules"
891 );
892 }
893 (
894 init_base, init_size, ext4_base, ext4_size, ram_base, ram_size,
895 )
896 } else {
897 (0u64, 0u64, 0u64, 0u64, 0u64, 0u64)
898 };
899
900 if ext4_base != 0 && ext4_size != 0 {
901 unsafe {
903 FS_EXT4_MODULE = Some((ext4_base, ext4_size));
904 }
905 }
906
907 if ram_base != 0 && ram_size != 0 {
908 unsafe {
910 STRATE_FS_RAMFS_MODULE = Some((ram_base, ram_size));
911 }
912 }
913
914 let (cmdline_ptr, cmdline_len) = if let Some(cmdline_resp) = EXEC_CMDLINE.get_response() {
916 let cstr = cmdline_resp.cmdline();
917 let bytes = cstr.to_bytes_with_nul();
918 let ptr = bytes.as_ptr() as u64;
919 let len = bytes.len() as u64;
920 if let Ok(s) = cstr.to_str() {
921 crate::serial_println!("[limine] cmdline: '{}'", s);
922 }
923 (ptr, len)
924 } else {
925 crate::serial_println!("[limine] no cmdline provided");
926 (0, 0)
927 };
928
929 let args = super::entry::KernelArgs {
930 magic: strat9_abi::boot::STRAT9_BOOT_MAGIC,
931 abi_version: strat9_abi::boot::STRAT9_BOOT_ABI_VERSION,
932 kernel_base: EXECUTABLE_ADDRESS
933 .get_response()
934 .map(|r| r.physical_base())
935 .unwrap_or(0x100000),
936 kernel_size: EXECUTABLE_FILE
937 .get_response()
938 .map(|r| r.file().size())
939 .unwrap_or(0),
940 stack_base: 0x80000,
941 stack_size: 0x10000,
942 env_base: 0,
943 env_size: 0,
944 acpi_rsdp_base: rsdp_addr,
945 acpi_rsdp_size: if rsdp_addr != 0 { 36 } else { 0 },
946 memory_map_base,
947 memory_map_size,
948 initfs_base: fallback_elf_base,
949 initfs_size: fallback_elf_size,
950 framebuffer_addr: fb_addr,
951 framebuffer_width: fb_width,
952 framebuffer_height: fb_height,
953 framebuffer_stride: fb_stride,
954 framebuffer_bpp: fb_bpp,
955 framebuffer_red_mask_size: fb_red_mask_size,
956 framebuffer_red_mask_shift: fb_red_mask_shift,
957 framebuffer_green_mask_size: fb_green_mask_size,
958 framebuffer_green_mask_shift: fb_green_mask_shift,
959 framebuffer_blue_mask_size: fb_blue_mask_size,
960 framebuffer_blue_mask_shift: fb_blue_mask_shift,
961 _padding1: [0; 4],
962 hhdm_offset,
963 cmdline_ptr,
964 cmdline_len,
965 };
966
967 crate::kernel_main(&args as *const _);
969}