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 EXECUTABLE_FILE: ExecutableFileRequest = ExecutableFileRequest::new();
34
35#[used]
37#[link_section = ".requests"]
38static RSDP: RsdpRequest = RsdpRequest::new();
39
40#[used]
42#[link_section = ".requests"]
43static HHDM: HhdmRequest = HhdmRequest::new();
44
45#[used]
47#[link_section = ".requests"]
48static STACK_SIZE: StackSizeRequest = StackSizeRequest::new().with_size(0x10000); static TEST_PID_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/test_pid");
52static TEST_SYSCALLS_MODULE: InternalModule =
54 InternalModule::new().with_path(c"/initfs/test_syscalls");
55static TEST_MEM_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/test_mem");
57static TEST_MEM_STRESSED_MODULE: InternalModule =
59 InternalModule::new().with_path(c"/initfs/test_mem_stressed");
60static EXT4_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/fs-ext4");
62static RAM_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/strate-fs-ramfs");
64static INIT_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/init");
66static CONSOLE_ADMIN_MODULE: InternalModule =
68 InternalModule::new().with_path(c"/initfs/console-admin");
69static STRATE_NET_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/strate-net");
71static STRATE_BUS_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/strate-bus");
73static DHCP_CLIENT_MODULE: InternalModule =
75 InternalModule::new().with_path(c"/initfs/bin/dhcp-client");
76static PING_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/bin/ping");
78static TELNETD_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/bin/telnetd");
80static UDP_TOOL_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/bin/udp-tool");
82static STRATE_WASM_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/strate-wasm");
84static STRATE_WEBRTC_MODULE: InternalModule =
86 InternalModule::new().with_path(c"/initfs/strate-webrtc");
87static HELLO_WASM_MODULE: InternalModule =
89 InternalModule::new().with_path(c"/initfs/bin/hello.wasm");
90static WASM_TEST_TOML_MODULE: InternalModule =
92 InternalModule::new().with_path(c"/initfs/wasm-test.toml");
93
94#[used]
96#[link_section = ".requests"]
97static MODULES: ModuleRequest = ModuleRequest::new().with_internal_modules(&[
98 &TEST_PID_MODULE,
99 &TEST_SYSCALLS_MODULE,
100 &TEST_MEM_MODULE,
101 &TEST_MEM_STRESSED_MODULE,
102 &EXT4_MODULE,
103 &RAM_MODULE,
104 &INIT_MODULE,
105 &CONSOLE_ADMIN_MODULE,
106 &STRATE_NET_MODULE,
107 &STRATE_BUS_MODULE,
108 &DHCP_CLIENT_MODULE,
109 &PING_MODULE,
110 &TELNETD_MODULE,
111 &UDP_TOOL_MODULE,
112 &STRATE_WASM_MODULE,
113 &STRATE_WEBRTC_MODULE,
114 &HELLO_WASM_MODULE,
115 &WASM_TEST_TOML_MODULE,
116]);
117
118static mut FS_EXT4_MODULE: Option<(u64, u64)> = None;
120static mut TEST_MEM_ELF_MODULE: Option<(u64, u64)> = None;
122static mut TEST_SYSCALLS_ELF_MODULE: Option<(u64, u64)> = None;
124static mut TEST_MEM_STRESSED_ELF_MODULE: Option<(u64, u64)> = None;
126static mut STRATE_FS_RAMFS_MODULE: Option<(u64, u64)> = None;
128static mut INIT_ELF_MODULE: Option<(u64, u64)> = None;
130static mut CONSOLE_ADMIN_ELF_MODULE: Option<(u64, u64)> = None;
132static mut STRATE_NET_ELF_MODULE: Option<(u64, u64)> = None;
134static mut STRATE_BUS_ELF_MODULE: Option<(u64, u64)> = None;
136static mut DHCP_CLIENT_ELF_MODULE: Option<(u64, u64)> = None;
138static mut PING_ELF_MODULE: Option<(u64, u64)> = None;
140static mut TELNETD_ELF_MODULE: Option<(u64, u64)> = None;
142static mut UDP_TOOL_ELF_MODULE: Option<(u64, u64)> = None;
144static mut STRATE_WASM_ELF_MODULE: Option<(u64, u64)> = None;
146static mut STRATE_WEBRTC_ELF_MODULE: Option<(u64, u64)> = None;
148static mut HELLO_WASM_FILE_MODULE: Option<(u64, u64)> = None;
150static mut WASM_TEST_TOML_FILE_MODULE: Option<(u64, u64)> = None;
152
153const MAX_BOOT_MEMORY_REGIONS: usize = 256;
154static mut BOOT_MEMORY_MAP: [super::entry::MemoryRegion; MAX_BOOT_MEMORY_REGIONS] =
155 [super::entry::MemoryRegion {
156 base: 0,
157 size: 0,
158 kind: super::entry::MemoryKind::Reserved,
159 }; MAX_BOOT_MEMORY_REGIONS];
160static mut BOOT_MEMORY_MAP_LEN: usize = 0;
161
162pub fn fs_ext4_module() -> Option<(u64, u64)> {
164 unsafe { FS_EXT4_MODULE }
166}
167
168pub fn test_mem_module() -> Option<(u64, u64)> {
170 unsafe { TEST_MEM_ELF_MODULE }
172}
173
174pub fn test_syscalls_module() -> Option<(u64, u64)> {
176 unsafe { TEST_SYSCALLS_ELF_MODULE }
178}
179
180pub fn test_mem_stressed_module() -> Option<(u64, u64)> {
182 unsafe { TEST_MEM_STRESSED_ELF_MODULE }
184}
185
186pub fn strate_fs_ramfs_module() -> Option<(u64, u64)> {
188 unsafe { STRATE_FS_RAMFS_MODULE }
190}
191
192pub fn init_module() -> Option<(u64, u64)> {
194 unsafe { INIT_ELF_MODULE }
196}
197
198pub fn console_admin_module() -> Option<(u64, u64)> {
200 unsafe { CONSOLE_ADMIN_ELF_MODULE }
202}
203
204pub fn strate_net_module() -> Option<(u64, u64)> {
206 unsafe { STRATE_NET_ELF_MODULE }
208}
209
210pub fn strate_bus_module() -> Option<(u64, u64)> {
212 unsafe { STRATE_BUS_ELF_MODULE }
214}
215
216pub fn dhcp_client_module() -> Option<(u64, u64)> {
218 unsafe { DHCP_CLIENT_ELF_MODULE }
220}
221
222pub fn ping_module() -> Option<(u64, u64)> {
224 unsafe { PING_ELF_MODULE }
226}
227
228pub fn telnetd_module() -> Option<(u64, u64)> {
230 unsafe { TELNETD_ELF_MODULE }
232}
233
234pub fn udp_tool_module() -> Option<(u64, u64)> {
236 unsafe { UDP_TOOL_ELF_MODULE }
238}
239
240pub fn strate_wasm_module() -> Option<(u64, u64)> {
242 unsafe { STRATE_WASM_ELF_MODULE }
244}
245
246pub fn strate_webrtc_module() -> Option<(u64, u64)> {
248 unsafe { STRATE_WEBRTC_ELF_MODULE }
250}
251
252pub fn hello_wasm_module() -> Option<(u64, u64)> {
254 unsafe { HELLO_WASM_FILE_MODULE }
256}
257
258pub fn wasm_test_toml_module() -> Option<(u64, u64)> {
260 unsafe { WASM_TEST_TOML_FILE_MODULE }
262}
263
264fn path_matches(module_path: &[u8], expected_path: &[u8]) -> bool {
266 let expected_no_leading = expected_path.strip_prefix(b"/").unwrap_or(expected_path);
267 module_path == expected_path
268 || module_path.ends_with(expected_path)
269 || module_path == expected_no_leading
270 || module_path.ends_with(expected_no_leading)
271}
272
273#[inline]
275const fn module_addr_to_phys(addr: u64, hhdm_offset: u64) -> u64 {
276 if hhdm_offset != 0 && addr >= hhdm_offset {
277 addr - hhdm_offset
278 } else {
279 addr
280 }
281}
282
283#[derive(Default, Clone, Copy)]
284struct ResolvedModules {
285 test_pid: Option<(u64, u64)>,
286 test_syscalls: Option<(u64, u64)>,
287 test_mem: Option<(u64, u64)>,
288 test_mem_stressed: Option<(u64, u64)>,
289 fs_ext4: Option<(u64, u64)>,
290 fs_ram: Option<(u64, u64)>,
291 init: Option<(u64, u64)>,
292 console_admin: Option<(u64, u64)>,
293 strate_net: Option<(u64, u64)>,
294 strate_bus: Option<(u64, u64)>,
295 dhcp_client: Option<(u64, u64)>,
296 ping: Option<(u64, u64)>,
297 telnetd: Option<(u64, u64)>,
298 udp_tool: Option<(u64, u64)>,
299 strate_wasm: Option<(u64, u64)>,
300 strate_webrtc: Option<(u64, u64)>,
301 hello_wasm: Option<(u64, u64)>,
302 wasm_test_toml: Option<(u64, u64)>,
303}
304
305fn resolve_modules_once(modules: &[&limine::file::File], hhdm_offset: u64) -> ResolvedModules {
307 let mut resolved = ResolvedModules::default();
308 for module in modules {
309 let path = module.path().to_bytes();
310 let info = (
311 module_addr_to_phys(module.addr() as u64, hhdm_offset),
312 module.size(),
313 );
314 if path_matches(path, b"/initfs/test_pid") {
315 resolved.test_pid = Some(info);
316 } else if path_matches(path, b"/initfs/test_syscalls") {
317 resolved.test_syscalls = Some(info);
318 } else if path_matches(path, b"/initfs/test_mem") {
319 resolved.test_mem = Some(info);
320 } else if path_matches(path, b"/initfs/test_mem_stressed") {
321 resolved.test_mem_stressed = Some(info);
322 } else if path_matches(path, b"/initfs/fs-ext4") {
323 resolved.fs_ext4 = Some(info);
324 } else if path_matches(path, b"/initfs/strate-fs-ramfs") {
325 resolved.fs_ram = Some(info);
326 } else if path_matches(path, b"/initfs/init") {
327 resolved.init = Some(info);
328 } else if path_matches(path, b"/initfs/console-admin") {
329 resolved.console_admin = Some(info);
330 } else if path_matches(path, b"/initfs/strate-net") {
331 resolved.strate_net = Some(info);
332 } else if path_matches(path, b"/initfs/strate-bus") {
333 resolved.strate_bus = Some(info);
334 } else if path_matches(path, b"/initfs/bin/dhcp-client") {
335 resolved.dhcp_client = Some(info);
336 } else if path_matches(path, b"/initfs/bin/ping") {
337 resolved.ping = Some(info);
338 } else if path_matches(path, b"/initfs/bin/telnetd") {
339 resolved.telnetd = Some(info);
340 } else if path_matches(path, b"/initfs/bin/udp-tool") {
341 resolved.udp_tool = Some(info);
342 } else if path_matches(path, b"/initfs/strate-wasm") {
343 resolved.strate_wasm = Some(info);
344 } else if path_matches(path, b"/initfs/strate-webrtc") {
345 resolved.strate_webrtc = Some(info);
346 } else if path_matches(path, b"/initfs/bin/hello.wasm") {
347 resolved.hello_wasm = Some(info);
348 } else if path_matches(path, b"/initfs/wasm-test.toml") {
349 resolved.wasm_test_toml = Some(info);
350 }
351 }
352 resolved
353}
354
355fn map_limine_region_kind(kind: limine::memory_map::EntryType) -> super::entry::MemoryKind {
357 if kind == limine::memory_map::EntryType::USABLE {
358 super::entry::MemoryKind::Free
359 } else if kind == limine::memory_map::EntryType::ACPI_RECLAIMABLE {
360 super::entry::MemoryKind::Reclaim
361 } else {
362 super::entry::MemoryKind::Reserved
363 }
364}
365
366#[used]
368#[link_section = ".requests_start_marker"]
369static _START_MARKER: RequestsStartMarker = RequestsStartMarker::new();
370
371#[used]
372#[link_section = ".requests_end_marker"]
373static _END_MARKER: RequestsEndMarker = RequestsEndMarker::new();
374
375#[inline(always)]
377fn hlt_loop() -> ! {
378 loop {
379 unsafe {
380 core::arch::asm!("hlt", options(nomem, nostack, preserves_flags));
381 }
382 }
383}
384
385#[no_mangle]
394#[allow(static_mut_refs)]
395pub unsafe extern "C" fn kmain() -> ! {
396 assert!(BASE_REVISION.is_supported());
398
399 let (
401 fb_addr,
402 fb_width,
403 fb_height,
404 fb_stride,
405 fb_bpp,
406 fb_red_mask_size,
407 fb_red_mask_shift,
408 fb_green_mask_size,
409 fb_green_mask_shift,
410 fb_blue_mask_size,
411 fb_blue_mask_shift,
412 ) = if let Some(fb_response) = FRAMEBUFFER.get_response() {
413 if let Some(fb) = fb_response.framebuffers().next() {
414 (
415 fb.addr() as u64,
416 fb.width() as u32,
417 fb.height() as u32,
418 fb.pitch() as u32,
419 fb.bpp(),
420 fb.red_mask_size(),
421 fb.red_mask_shift(),
422 fb.green_mask_size(),
423 fb.green_mask_shift(),
424 fb.blue_mask_size(),
425 fb.blue_mask_shift(),
426 )
427 } else {
428 (0, 0, 0, 0, 0, 8, 16, 8, 8, 8, 0)
429 }
430 } else {
431 (0, 0, 0, 0, 0, 8, 16, 8, 8, 8, 0)
432 };
433
434 let rsdp_addr = RSDP.get_response().map(|r| r.address() as u64).unwrap_or(0);
436
437 if fb_addr != 0 && fb_width != 0 && fb_height != 0 {
439 let format = crate::hardware::video::framebuffer::PixelFormat {
440 red_mask: ((1 << fb_red_mask_size) - 1) << fb_red_mask_shift,
441 red_shift: fb_red_mask_shift as u8,
442 green_mask: ((1 << fb_green_mask_size) - 1) << fb_green_mask_shift,
443 green_shift: fb_green_mask_shift as u8,
444 blue_mask: ((1 << fb_blue_mask_size) - 1) << fb_blue_mask_shift,
445 blue_shift: fb_blue_mask_shift as u8,
446 bits_per_pixel: fb_bpp as u8,
447 };
448
449 if let Err(e) = crate::hardware::video::framebuffer::Framebuffer::init_limine(
450 fb_addr, fb_width, fb_height, fb_stride, format,
451 ) {
452 serial_println!("[limine] Framebuffer init failed: {}", e);
453 }
454 }
455
456 let hhdm_offset = HHDM.get_response().map(|r| r.offset()).unwrap_or(0);
458
459 let (memory_map_base, memory_map_size) = if let Some(memory_map_response) =
462 MEMORY_MAP.get_response()
463 {
464 let entries = memory_map_response.entries();
465 let count = core::cmp::min(entries.len(), MAX_BOOT_MEMORY_REGIONS);
466 unsafe {
467 BOOT_MEMORY_MAP_LEN = count;
468 for (i, entry) in entries.iter().take(count).enumerate() {
469 BOOT_MEMORY_MAP[i] = super::entry::MemoryRegion {
470 base: entry.base,
471 size: entry.length,
472 kind: map_limine_region_kind(entry.entry_type),
473 };
474 }
475 (
476 BOOT_MEMORY_MAP.as_ptr() as u64,
477 (BOOT_MEMORY_MAP_LEN * core::mem::size_of::<super::entry::MemoryRegion>()) as u64,
478 )
479 }
480 } else {
481 (0, 0)
482 };
483
484 let (
487 fallback_elf_base,
488 fallback_elf_size,
489 ext4_base,
490 ext4_size,
491 ram_base,
492 ram_size,
493 ) = if let Some(
494 module_response,
495 ) =
496 MODULES.get_response()
497 {
498 let modules = module_response.modules();
499 crate::serial_println!("[limine] modules reported: {}", modules.len());
500 for (idx, module) in modules.iter().enumerate() {
501 #[cfg(feature = "selftest")]
502 {
503 let raw_addr = module.addr() as u64;
504 let phys_addr = module_addr_to_phys(raw_addr, hhdm_offset);
505 let (m0, m1, m2, m3) = if module.size() >= 4 {
506 unsafe {
507 let p = raw_addr as *const u8;
508 (
509 core::ptr::read_volatile(p),
510 core::ptr::read_volatile(p.add(1)),
511 core::ptr::read_volatile(p.add(2)),
512 core::ptr::read_volatile(p.add(3)),
513 )
514 }
515 } else {
516 (0, 0, 0, 0)
517 };
518 crate::serial_println!(
519 "[limine] module[{}]: path='{}' addr={:#x} phys={:#x} magic={:02x}{:02x}{:02x}{:02x} size={}",
520 idx,
521 module.path().to_string_lossy(),
522 raw_addr,
523 phys_addr,
524 m0,
525 m1,
526 m2,
527 m3,
528 module.size()
529 );
530 }
531 #[cfg(not(feature = "selftest"))]
532 {
533 crate::serial_println!(
534 "[limine] module[{}]: path='{}' size={}",
535 idx,
536 module.path().to_string_lossy(),
537 module.size()
538 );
539 }
540 }
541 let resolved = resolve_modules_once(modules, hhdm_offset);
542 let (init_base, init_size) = resolved.test_pid.unwrap_or((0, 0));
543 let (test_syscalls_base, test_syscalls_size) = resolved.test_syscalls.unwrap_or((0, 0));
544 let (test_mem_base, test_mem_size) = resolved.test_mem.unwrap_or((0, 0));
545 let (test_mem_stressed_base, test_mem_stressed_size) =
546 resolved.test_mem_stressed.unwrap_or((0, 0));
547 let (ext4_base, ext4_size) = resolved.fs_ext4.unwrap_or((0, 0));
548 let (ram_base, ram_size) = resolved.fs_ram.unwrap_or((0, 0));
549
550 if test_mem_base != 0 && test_mem_size != 0 {
551 unsafe { TEST_MEM_ELF_MODULE = Some((test_mem_base, test_mem_size)) };
552 crate::serial_println!(
553 "[limine] /initfs/test_mem found: base={:#x} size={}",
554 test_mem_base,
555 test_mem_size
556 );
557 } else {
558 crate::serial_println!("[limine] WARN: /initfs/test_mem not found in modules");
559 }
560 if test_syscalls_base != 0 && test_syscalls_size != 0 {
561 unsafe { TEST_SYSCALLS_ELF_MODULE = Some((test_syscalls_base, test_syscalls_size)) };
562 crate::serial_println!(
563 "[limine] /initfs/test_syscalls found: base={:#x} size={}",
564 test_syscalls_base,
565 test_syscalls_size
566 );
567 } else {
568 crate::serial_println!("[limine] WARN: /initfs/test_syscalls not found in modules");
569 }
570 if test_mem_stressed_base != 0 && test_mem_stressed_size != 0 {
571 unsafe {
572 TEST_MEM_STRESSED_ELF_MODULE =
573 Some((test_mem_stressed_base, test_mem_stressed_size))
574 };
575 crate::serial_println!(
576 "[limine] /initfs/test_mem_stressed found: base={:#x} size={}",
577 test_mem_stressed_base,
578 test_mem_stressed_size
579 );
580 } else {
581 crate::serial_println!("[limine] WARN: /initfs/test_mem_stressed not found in modules");
582 }
583
584 if let Some((base, size)) = resolved.init {
586 unsafe { INIT_ELF_MODULE = Some((base, size)) };
587 crate::serial_println!(
588 "[limine] /initfs/init found: base={:#x} size={}",
589 base,
590 size
591 );
592 } else {
593 crate::serial_println!("[limine] WARN: /initfs/init not found in modules");
594 }
595 if let Some((base, size)) = resolved.console_admin {
596 unsafe { CONSOLE_ADMIN_ELF_MODULE = Some((base, size)) };
597 crate::serial_println!(
598 "[limine] /initfs/console-admin found: base={:#x} size={}",
599 base,
600 size
601 );
602 } else {
603 crate::serial_println!("[limine] WARN: /initfs/console-admin not found in modules");
604 }
605 if let Some((base, size)) = resolved.strate_net {
606 unsafe { STRATE_NET_ELF_MODULE = Some((base, size)) };
607 crate::serial_println!(
608 "[limine] /initfs/strate-net found: base={:#x} size={}",
609 base,
610 size
611 );
612 } else {
613 crate::serial_println!("[limine] WARN: /initfs/strate-net not found in modules");
614 }
615 if let Some((base, size)) = resolved.strate_bus {
616 unsafe { STRATE_BUS_ELF_MODULE = Some((base, size)) };
617 crate::serial_println!(
618 "[limine] /initfs/strate-bus found: base={:#x} size={}",
619 base,
620 size
621 );
622 } else {
623 crate::serial_println!("[limine] WARN: /initfs/strate-bus not found in modules");
624 }
625 if let Some((base, size)) = resolved.dhcp_client {
626 unsafe { DHCP_CLIENT_ELF_MODULE = Some((base, size)) };
627 crate::serial_println!(
628 "[limine] /initfs/bin/dhcp-client found: base={:#x} size={}",
629 base,
630 size
631 );
632 } else {
633 crate::serial_println!("[limine] WARN: /initfs/bin/dhcp-client not found in modules");
634 }
635 if let Some((base, size)) = resolved.ping {
636 unsafe { PING_ELF_MODULE = Some((base, size)) };
637 crate::serial_println!(
638 "[limine] /initfs/bin/ping found: base={:#x} size={}",
639 base,
640 size
641 );
642 } else {
643 crate::serial_println!("[limine] WARN: /initfs/bin/ping not found in modules");
644 }
645 if let Some((base, size)) = resolved.telnetd {
646 unsafe { TELNETD_ELF_MODULE = Some((base, size)) };
647 crate::serial_println!(
648 "[limine] /initfs/bin/telnetd found: base={:#x} size={}",
649 base,
650 size
651 );
652 } else {
653 crate::serial_println!("[limine] WARN: /initfs/bin/telnetd not found in modules");
654 }
655 if let Some((base, size)) = resolved.udp_tool {
656 unsafe { UDP_TOOL_ELF_MODULE = Some((base, size)) };
657 crate::serial_println!(
658 "[limine] /initfs/bin/udp-tool found: base={:#x} size={}",
659 base,
660 size
661 );
662 } else {
663 crate::serial_println!("[limine] WARN: /initfs/bin/udp-tool not found in modules");
664 }
665 if let Some((base, size)) = resolved.strate_wasm {
666 unsafe { STRATE_WASM_ELF_MODULE = Some((base, size)) };
667 crate::serial_println!(
668 "[limine] /initfs/strate-wasm found: base={:#x} size={}",
669 base,
670 size
671 );
672 } else {
673 crate::serial_println!("[limine] WARN: /initfs/strate-wasm not found in modules");
674 }
675 if let Some((base, size)) = resolved.strate_webrtc {
676 unsafe { STRATE_WEBRTC_ELF_MODULE = Some((base, size)) };
677 crate::serial_println!(
678 "[limine] /initfs/strate-webrtc found: base={:#x} size={}",
679 base,
680 size
681 );
682 } else {
683 crate::serial_println!("[limine] WARN: /initfs/strate-webrtc not found in modules");
684 }
685 if let Some((base, size)) = resolved.hello_wasm {
686 unsafe { HELLO_WASM_FILE_MODULE = Some((base, size)) };
687 crate::serial_println!(
688 "[limine] /initfs/bin/hello.wasm found: base={:#x} size={}",
689 base,
690 size
691 );
692 } else {
693 crate::serial_println!("[limine] WARN: /initfs/bin/hello.wasm not found in modules");
694 }
695 if let Some((base, size)) = resolved.wasm_test_toml {
696 unsafe { WASM_TEST_TOML_FILE_MODULE = Some((base, size)) };
697 crate::serial_println!(
698 "[limine] /initfs/wasm-test.toml found: base={:#x} size={}",
699 base,
700 size
701 );
702 } else {
703 crate::serial_println!("[limine] WARN: /initfs/wasm-test.toml not found in modules");
704 }
705
706 if init_base == 0 {
707 crate::serial_println!("[limine] WARN: /initfs/test_pid not found in modules");
708 }
709 if ext4_base == 0 {
710 crate::serial_println!("[limine] WARN: /initfs/fs-ext4 not found in modules");
711 }
712 if ram_base == 0 {
713 crate::serial_println!("[limine] WARN: /initfs/strate-fs-ramfs not found in modules");
714 }
715 (
716 init_base, init_size, ext4_base, ext4_size, ram_base, ram_size,
717 )
718 } else {
719 (0u64, 0u64, 0u64, 0u64, 0u64, 0u64)
720 };
721
722 if ext4_base != 0 && ext4_size != 0 {
723 unsafe {
725 FS_EXT4_MODULE = Some((ext4_base, ext4_size));
726 }
727 }
728
729 if ram_base != 0 && ram_size != 0 {
730 unsafe {
732 STRATE_FS_RAMFS_MODULE = Some((ram_base, ram_size));
733 }
734 }
735
736 let args = super::entry::KernelArgs {
737 magic: strat9_abi::boot::STRAT9_BOOT_MAGIC,
738 abi_version: strat9_abi::boot::STRAT9_BOOT_ABI_VERSION,
739 kernel_base: EXECUTABLE_ADDRESS
740 .get_response()
741 .map(|r| r.physical_base())
742 .unwrap_or(0x100000),
743 kernel_size: EXECUTABLE_FILE
744 .get_response()
745 .map(|r| r.file().size())
746 .unwrap_or(0),
747 stack_base: 0x80000,
748 stack_size: 0x10000,
749 env_base: 0,
750 env_size: 0,
751 acpi_rsdp_base: rsdp_addr,
752 acpi_rsdp_size: if rsdp_addr != 0 { 36 } else { 0 },
753 memory_map_base,
754 memory_map_size,
755 initfs_base: fallback_elf_base,
756 initfs_size: fallback_elf_size,
757 framebuffer_addr: fb_addr,
758 framebuffer_width: fb_width,
759 framebuffer_height: fb_height,
760 framebuffer_stride: fb_stride,
761 framebuffer_bpp: fb_bpp,
762 framebuffer_red_mask_size: fb_red_mask_size,
763 framebuffer_red_mask_shift: fb_red_mask_shift,
764 framebuffer_green_mask_size: fb_green_mask_size,
765 framebuffer_green_mask_shift: fb_green_mask_shift,
766 framebuffer_blue_mask_size: fb_blue_mask_size,
767 framebuffer_blue_mask_shift: fb_blue_mask_shift,
768 _padding1: 0,
769 hhdm_offset,
770 };
771
772 crate::kernel_main(&args as *const _);
774}