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");
57static TEST_SYSCALLS_MODULE: InternalModule =
59 InternalModule::new().with_path(c"/initfs/test_syscalls");
60static TEST_MEM_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/test_mem");
62static TEST_MEM_STRESSED_MODULE: InternalModule =
64 InternalModule::new().with_path(c"/initfs/test_mem_stressed");
65static TEST_MEM_REGION_MODULE: InternalModule =
67 InternalModule::new().with_path(c"/initfs/test_mem_region");
68static TEST_MEM_REGION_PROC_MODULE: InternalModule =
70 InternalModule::new().with_path(c"/initfs/test_mem_region_proc");
71static TEST_EXEC_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/test_exec");
73static TEST_EXEC_HELPER_MODULE: InternalModule =
75 InternalModule::new().with_path(c"/initfs/test_exec_helper");
76static EXT4_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/fs-ext4");
78static RAM_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/strate-fs-ramfs");
80static INIT_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/init");
82static CONSOLE_ADMIN_MODULE: InternalModule =
84 InternalModule::new().with_path(c"/initfs/console-admin");
85static STRATE_NET_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/strate-net");
87static STRATE_BUS_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/strate-bus");
89static DHCP_CLIENT_MODULE: InternalModule =
91 InternalModule::new().with_path(c"/initfs/bin/dhcp-client");
92static PING_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/bin/ping");
94static TELNETD_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/bin/telnetd");
96static SSHD_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/bin/sshd");
98static UDP_TOOL_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/bin/udp-tool");
100static WEB_ADMIN_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/bin/web-admin");
102static STRATE_WASM_MODULE: InternalModule = InternalModule::new().with_path(c"/initfs/strate-wasm");
104static STRATE_WEBRTC_MODULE: InternalModule =
106 InternalModule::new().with_path(c"/initfs/strate-webrtc");
107static HELLO_WASM_MODULE: InternalModule =
109 InternalModule::new().with_path(c"/initfs/bin/hello.wasm");
110static WASM_TEST_TOML_MODULE: InternalModule =
112 InternalModule::new().with_path(c"/initfs/wasm-test.toml");
113
114#[used]
116#[link_section = ".requests"]
117static MODULES: ModuleRequest = ModuleRequest::new().with_internal_modules(&[
118 &TEST_PID_MODULE,
119 &TEST_SYSCALLS_MODULE,
120 &TEST_MEM_MODULE,
121 &TEST_MEM_STRESSED_MODULE,
122 &TEST_MEM_REGION_MODULE,
123 &TEST_MEM_REGION_PROC_MODULE,
124 &TEST_EXEC_MODULE,
125 &TEST_EXEC_HELPER_MODULE,
126 &EXT4_MODULE,
127 &RAM_MODULE,
128 &INIT_MODULE,
129 &CONSOLE_ADMIN_MODULE,
130 &STRATE_NET_MODULE,
131 &STRATE_BUS_MODULE,
132 &DHCP_CLIENT_MODULE,
133 &PING_MODULE,
134 &TELNETD_MODULE,
135 &SSHD_MODULE,
136 &UDP_TOOL_MODULE,
137 &WEB_ADMIN_MODULE,
138 &STRATE_WASM_MODULE,
139 &STRATE_WEBRTC_MODULE,
140 &HELLO_WASM_MODULE,
141 &WASM_TEST_TOML_MODULE,
142]);
143
144static mut FS_EXT4_MODULE: Option<(u64, u64)> = None;
146static mut TEST_MEM_ELF_MODULE: Option<(u64, u64)> = None;
148static mut TEST_SYSCALLS_ELF_MODULE: Option<(u64, u64)> = None;
150static mut TEST_MEM_STRESSED_ELF_MODULE: Option<(u64, u64)> = None;
152static mut TEST_MEM_REGION_ELF_MODULE: Option<(u64, u64)> = None;
154static mut TEST_MEM_REGION_PROC_ELF_MODULE: Option<(u64, u64)> = None;
156static mut TEST_EXEC_ELF_MODULE: Option<(u64, u64)> = None;
158static mut TEST_EXEC_HELPER_ELF_MODULE: Option<(u64, u64)> = None;
160static mut STRATE_FS_RAMFS_MODULE: Option<(u64, u64)> = None;
162static mut INIT_ELF_MODULE: Option<(u64, u64)> = None;
164static mut CONSOLE_ADMIN_ELF_MODULE: Option<(u64, u64)> = None;
166static mut STRATE_NET_ELF_MODULE: Option<(u64, u64)> = None;
168static mut STRATE_BUS_ELF_MODULE: Option<(u64, u64)> = None;
170static mut DHCP_CLIENT_ELF_MODULE: Option<(u64, u64)> = None;
172static mut PING_ELF_MODULE: Option<(u64, u64)> = None;
174static mut TELNETD_ELF_MODULE: Option<(u64, u64)> = None;
176static mut SSHD_ELF_MODULE: Option<(u64, u64)> = None;
178static mut UDP_TOOL_ELF_MODULE: Option<(u64, u64)> = None;
180static mut WEB_ADMIN_ELF_MODULE: Option<(u64, u64)> = None;
182static mut STRATE_WASM_ELF_MODULE: Option<(u64, u64)> = None;
184static mut STRATE_WEBRTC_ELF_MODULE: Option<(u64, u64)> = None;
186static mut HELLO_WASM_FILE_MODULE: Option<(u64, u64)> = None;
188static mut WASM_TEST_TOML_FILE_MODULE: Option<(u64, u64)> = None;
190
191const MAX_BOOT_MEMORY_REGIONS: usize = 256;
192static mut BOOT_MEMORY_MAP: [super::entry::MemoryRegion; MAX_BOOT_MEMORY_REGIONS] =
193 [super::entry::MemoryRegion {
194 base: 0,
195 size: 0,
196 kind: super::entry::MemoryKind::Reserved,
197 }; MAX_BOOT_MEMORY_REGIONS];
198static mut BOOT_MEMORY_MAP_LEN: usize = 0;
199
200pub fn fs_ext4_module() -> Option<(u64, u64)> {
202 unsafe { FS_EXT4_MODULE }
204}
205
206pub fn test_mem_module() -> Option<(u64, u64)> {
208 unsafe { TEST_MEM_ELF_MODULE }
210}
211
212pub fn test_syscalls_module() -> Option<(u64, u64)> {
214 unsafe { TEST_SYSCALLS_ELF_MODULE }
216}
217
218pub fn test_mem_stressed_module() -> Option<(u64, u64)> {
220 unsafe { TEST_MEM_STRESSED_ELF_MODULE }
222}
223
224pub fn test_mem_region_module() -> Option<(u64, u64)> {
226 unsafe { TEST_MEM_REGION_ELF_MODULE }
228}
229
230pub fn test_mem_region_proc_module() -> Option<(u64, u64)> {
232 unsafe { TEST_MEM_REGION_PROC_ELF_MODULE }
234}
235
236pub fn test_exec_module() -> Option<(u64, u64)> {
238 unsafe { TEST_EXEC_ELF_MODULE }
240}
241
242pub fn test_exec_helper_module() -> Option<(u64, u64)> {
244 unsafe { TEST_EXEC_HELPER_ELF_MODULE }
246}
247
248pub fn strate_fs_ramfs_module() -> Option<(u64, u64)> {
250 unsafe { STRATE_FS_RAMFS_MODULE }
252}
253
254pub fn init_module() -> Option<(u64, u64)> {
256 unsafe { INIT_ELF_MODULE }
258}
259
260pub fn console_admin_module() -> Option<(u64, u64)> {
262 unsafe { CONSOLE_ADMIN_ELF_MODULE }
264}
265
266pub fn strate_net_module() -> Option<(u64, u64)> {
268 unsafe { STRATE_NET_ELF_MODULE }
270}
271
272pub fn strate_bus_module() -> Option<(u64, u64)> {
274 unsafe { STRATE_BUS_ELF_MODULE }
276}
277
278pub fn dhcp_client_module() -> Option<(u64, u64)> {
280 unsafe { DHCP_CLIENT_ELF_MODULE }
282}
283
284pub fn ping_module() -> Option<(u64, u64)> {
286 unsafe { PING_ELF_MODULE }
288}
289
290pub fn telnetd_module() -> Option<(u64, u64)> {
292 unsafe { TELNETD_ELF_MODULE }
294}
295
296pub fn sshd_module() -> Option<(u64, u64)> {
298 unsafe { SSHD_ELF_MODULE }
300}
301
302pub fn udp_tool_module() -> Option<(u64, u64)> {
304 unsafe { UDP_TOOL_ELF_MODULE }
306}
307
308pub fn web_admin_module() -> Option<(u64, u64)> {
310 unsafe { WEB_ADMIN_ELF_MODULE }
312}
313
314pub fn strate_wasm_module() -> Option<(u64, u64)> {
316 unsafe { STRATE_WASM_ELF_MODULE }
318}
319
320pub fn strate_webrtc_module() -> Option<(u64, u64)> {
322 unsafe { STRATE_WEBRTC_ELF_MODULE }
324}
325
326pub fn hello_wasm_module() -> Option<(u64, u64)> {
328 unsafe { HELLO_WASM_FILE_MODULE }
330}
331
332pub fn wasm_test_toml_module() -> Option<(u64, u64)> {
334 unsafe { WASM_TEST_TOML_FILE_MODULE }
336}
337
338fn path_matches(module_path: &[u8], expected_path: &[u8]) -> bool {
340 let expected_no_leading = expected_path.strip_prefix(b"/").unwrap_or(expected_path);
341 module_path == expected_path
342 || module_path.ends_with(expected_path)
343 || module_path == expected_no_leading
344 || module_path.ends_with(expected_no_leading)
345}
346
347#[inline]
349const fn module_addr_to_phys(addr: u64, hhdm_offset: u64) -> u64 {
350 if hhdm_offset != 0 && addr >= hhdm_offset {
351 addr - hhdm_offset
352 } else {
353 addr
354 }
355}
356
357#[derive(Default, Clone, Copy)]
358struct ResolvedModules {
359 test_pid: Option<(u64, u64)>,
360 test_syscalls: Option<(u64, u64)>,
361 test_mem: Option<(u64, u64)>,
362 test_mem_stressed: Option<(u64, u64)>,
363 test_mem_region: Option<(u64, u64)>,
364 test_mem_region_proc: Option<(u64, u64)>,
365 test_exec: Option<(u64, u64)>,
366 test_exec_helper: Option<(u64, u64)>,
367 fs_ext4: Option<(u64, u64)>,
368 fs_ram: Option<(u64, u64)>,
369 init: Option<(u64, u64)>,
370 console_admin: Option<(u64, u64)>,
371 strate_net: Option<(u64, u64)>,
372 strate_bus: Option<(u64, u64)>,
373 dhcp_client: Option<(u64, u64)>,
374 ping: Option<(u64, u64)>,
375 telnetd: Option<(u64, u64)>,
376 sshd: Option<(u64, u64)>,
377 udp_tool: Option<(u64, u64)>,
378 web_admin: Option<(u64, u64)>,
379 strate_wasm: Option<(u64, u64)>,
380 strate_webrtc: Option<(u64, u64)>,
381 hello_wasm: Option<(u64, u64)>,
382 wasm_test_toml: Option<(u64, u64)>,
383}
384
385fn resolve_modules_once(modules: &[&limine::file::File], hhdm_offset: u64) -> ResolvedModules {
387 let mut resolved = ResolvedModules::default();
388 for module in modules {
389 let path = module.path().to_bytes();
390 let info = (
391 module_addr_to_phys(module.addr() as u64, hhdm_offset),
392 module.size(),
393 );
394 if path_matches(path, b"/initfs/test_pid") {
395 resolved.test_pid = Some(info);
396 } else if path_matches(path, b"/initfs/test_syscalls") {
397 resolved.test_syscalls = Some(info);
398 } else if path_matches(path, b"/initfs/test_mem") {
399 resolved.test_mem = Some(info);
400 } else if path_matches(path, b"/initfs/test_mem_stressed") {
401 resolved.test_mem_stressed = Some(info);
402 } else if path_matches(path, b"/initfs/test_mem_region") {
403 resolved.test_mem_region = Some(info);
404 } else if path_matches(path, b"/initfs/test_mem_region_proc") {
405 resolved.test_mem_region_proc = Some(info);
406 } else if path_matches(path, b"/initfs/test_exec") {
407 resolved.test_exec = Some(info);
408 } else if path_matches(path, b"/initfs/test_exec_helper") {
409 resolved.test_exec_helper = Some(info);
410 } else if path_matches(path, b"/initfs/fs-ext4") {
411 resolved.fs_ext4 = Some(info);
412 } else if path_matches(path, b"/initfs/strate-fs-ramfs") {
413 resolved.fs_ram = Some(info);
414 } else if path_matches(path, b"/initfs/init") {
415 resolved.init = Some(info);
416 } else if path_matches(path, b"/initfs/console-admin") {
417 resolved.console_admin = Some(info);
418 } else if path_matches(path, b"/initfs/strate-net") {
419 resolved.strate_net = Some(info);
420 } else if path_matches(path, b"/initfs/strate-bus") {
421 resolved.strate_bus = Some(info);
422 } else if path_matches(path, b"/initfs/bin/dhcp-client") {
423 resolved.dhcp_client = Some(info);
424 } else if path_matches(path, b"/initfs/bin/ping") {
425 resolved.ping = Some(info);
426 } else if path_matches(path, b"/initfs/bin/telnetd") {
427 resolved.telnetd = Some(info);
428 } else if path_matches(path, b"/initfs/bin/sshd") {
429 resolved.sshd = Some(info);
430 } else if path_matches(path, b"/initfs/bin/udp-tool") {
431 resolved.udp_tool = Some(info);
432 } else if path_matches(path, b"/initfs/bin/web-admin") {
433 resolved.web_admin = Some(info);
434 } else if path_matches(path, b"/initfs/strate-wasm") {
435 resolved.strate_wasm = Some(info);
436 } else if path_matches(path, b"/initfs/strate-webrtc") {
437 resolved.strate_webrtc = Some(info);
438 } else if path_matches(path, b"/initfs/bin/hello.wasm") {
439 resolved.hello_wasm = Some(info);
440 } else if path_matches(path, b"/initfs/wasm-test.toml") {
441 resolved.wasm_test_toml = Some(info);
442 }
443 }
444 resolved
445}
446
447fn map_limine_region_kind(kind: limine::memory_map::EntryType) -> super::entry::MemoryKind {
449 if kind == limine::memory_map::EntryType::USABLE {
450 super::entry::MemoryKind::Free
451 } else if kind == limine::memory_map::EntryType::ACPI_RECLAIMABLE {
452 super::entry::MemoryKind::Reclaim
453 } else {
454 super::entry::MemoryKind::Reserved
455 }
456}
457
458#[used]
460#[link_section = ".requests_start_marker"]
461static _START_MARKER: RequestsStartMarker = RequestsStartMarker::new();
462
463#[used]
464#[link_section = ".requests_end_marker"]
465static _END_MARKER: RequestsEndMarker = RequestsEndMarker::new();
466
467#[inline(always)]
469fn hlt_loop() -> ! {
470 loop {
471 unsafe {
472 core::arch::asm!("hlt", options(nomem, nostack, preserves_flags));
473 }
474 }
475}
476
477#[no_mangle]
486#[allow(static_mut_refs)]
487pub unsafe extern "C" fn kmain() -> ! {
488 assert!(BASE_REVISION.is_supported());
490
491 {
493 let mut early_port = unsafe { uart_16550::SerialPort::new(0x3F8) };
495 early_port.init();
496 let _ = core::fmt::Write::write_str(
497 &mut early_port,
498 "[kmain] *** Strat9-OS kernel entry ***\r\n",
499 );
500 }
501
502 let (
504 fb_addr,
505 fb_width,
506 fb_height,
507 fb_stride,
508 fb_bpp,
509 fb_red_mask_size,
510 fb_red_mask_shift,
511 fb_green_mask_size,
512 fb_green_mask_shift,
513 fb_blue_mask_size,
514 fb_blue_mask_shift,
515 ) = if let Some(fb_response) = FRAMEBUFFER.get_response() {
516 if let Some(fb) = fb_response.framebuffers().next() {
517 (
518 fb.addr() as u64,
519 fb.width() as u32,
520 fb.height() as u32,
521 fb.pitch() as u32,
522 fb.bpp(),
523 fb.red_mask_size(),
524 fb.red_mask_shift(),
525 fb.green_mask_size(),
526 fb.green_mask_shift(),
527 fb.blue_mask_size(),
528 fb.blue_mask_shift(),
529 )
530 } else {
531 (0, 0, 0, 0, 0, 8, 16, 8, 8, 8, 0)
532 }
533 } else {
534 (0, 0, 0, 0, 0, 8, 16, 8, 8, 8, 0)
535 };
536
537 let rsdp_addr = RSDP.get_response().map(|r| r.address() as u64).unwrap_or(0);
539
540 if fb_addr != 0 && fb_width != 0 && fb_height != 0 {
542 let format = crate::hardware::video::framebuffer::PixelFormat {
543 red_mask: ((1 << fb_red_mask_size) - 1) << fb_red_mask_shift,
544 red_shift: fb_red_mask_shift as u8,
545 green_mask: ((1 << fb_green_mask_size) - 1) << fb_green_mask_shift,
546 green_shift: fb_green_mask_shift as u8,
547 blue_mask: ((1 << fb_blue_mask_size) - 1) << fb_blue_mask_shift,
548 blue_shift: fb_blue_mask_shift as u8,
549 bits_per_pixel: fb_bpp as u8,
550 };
551
552 if let Err(e) = crate::hardware::video::framebuffer::Framebuffer::init_limine(
553 fb_addr, fb_width, fb_height, fb_stride, format,
554 ) {
555 serial_println!("[limine] Framebuffer init failed: {}", e);
556 }
557 }
558
559 let hhdm_offset = HHDM.get_response().map(|r| r.offset()).unwrap_or(0);
561
562 let (memory_map_base, memory_map_size) = if let Some(memory_map_response) =
565 MEMORY_MAP.get_response()
566 {
567 let entries = memory_map_response.entries();
568 let count = core::cmp::min(entries.len(), MAX_BOOT_MEMORY_REGIONS);
569 unsafe {
570 BOOT_MEMORY_MAP_LEN = count;
571 for (i, entry) in entries.iter().take(count).enumerate() {
572 BOOT_MEMORY_MAP[i] = super::entry::MemoryRegion {
573 base: entry.base,
574 size: entry.length,
575 kind: map_limine_region_kind(entry.entry_type),
576 };
577 }
578 (
579 BOOT_MEMORY_MAP.as_ptr() as u64,
580 (BOOT_MEMORY_MAP_LEN * core::mem::size_of::<super::entry::MemoryRegion>()) as u64,
581 )
582 }
583 } else {
584 (0, 0)
585 };
586
587 let (fallback_elf_base, fallback_elf_size, ext4_base, ext4_size, ram_base, ram_size) =
590 if let Some(module_response) = MODULES.get_response() {
591 let modules = module_response.modules();
592 crate::serial_println!("[limine] modules reported: {}", modules.len());
593 for (idx, module) in modules.iter().enumerate() {
594 #[cfg(feature = "selftest")]
595 {
596 let raw_addr = module.addr() as u64;
597 let phys_addr = module_addr_to_phys(raw_addr, hhdm_offset);
598 let (m0, m1, m2, m3) = if module.size() >= 4 {
599 unsafe {
600 let p = raw_addr as *const u8;
601 (
602 core::ptr::read_volatile(p),
603 core::ptr::read_volatile(p.add(1)),
604 core::ptr::read_volatile(p.add(2)),
605 core::ptr::read_volatile(p.add(3)),
606 )
607 }
608 } else {
609 (0, 0, 0, 0)
610 };
611 crate::serial_println!(
612 "[limine] module[{}]: path='{}' addr={:#x} phys={:#x} magic={:02x}{:02x}{:02x}{:02x} size={}",
613 idx,
614 module.path().to_string_lossy(),
615 raw_addr,
616 phys_addr,
617 m0,
618 m1,
619 m2,
620 m3,
621 module.size()
622 );
623 }
624 #[cfg(not(feature = "selftest"))]
625 {
626 crate::serial_println!(
627 "[limine] module[{}]: path='{}' size={}",
628 idx,
629 module.path().to_string_lossy(),
630 module.size()
631 );
632 }
633 }
634 let resolved = resolve_modules_once(modules, hhdm_offset);
635 let (init_base, init_size) = resolved.test_pid.unwrap_or((0, 0));
636 let (test_syscalls_base, test_syscalls_size) = resolved.test_syscalls.unwrap_or((0, 0));
637 let (test_mem_base, test_mem_size) = resolved.test_mem.unwrap_or((0, 0));
638 let (test_mem_stressed_base, test_mem_stressed_size) =
639 resolved.test_mem_stressed.unwrap_or((0, 0));
640 let (test_mem_region_base, test_mem_region_size) =
641 resolved.test_mem_region.unwrap_or((0, 0));
642 let (test_mem_region_proc_base, test_mem_region_proc_size) =
643 resolved.test_mem_region_proc.unwrap_or((0, 0));
644 let (test_exec_base, test_exec_size) = resolved.test_exec.unwrap_or((0, 0));
645 let (test_exec_helper_base, test_exec_helper_size) =
646 resolved.test_exec_helper.unwrap_or((0, 0));
647 let (ext4_base, ext4_size) = resolved.fs_ext4.unwrap_or((0, 0));
648 let (ram_base, ram_size) = resolved.fs_ram.unwrap_or((0, 0));
649
650 if test_mem_base != 0 && test_mem_size != 0 {
651 unsafe { TEST_MEM_ELF_MODULE = Some((test_mem_base, test_mem_size)) };
652 crate::serial_println!(
653 "[limine] /initfs/test_mem found: base={:#x} size={}",
654 test_mem_base,
655 test_mem_size
656 );
657 }
658 if test_syscalls_base != 0 && test_syscalls_size != 0 {
659 unsafe {
660 TEST_SYSCALLS_ELF_MODULE = Some((test_syscalls_base, test_syscalls_size))
661 };
662 crate::serial_println!(
663 "[limine] /initfs/test_syscalls found: base={:#x} size={}",
664 test_syscalls_base,
665 test_syscalls_size
666 );
667 }
668 if test_mem_stressed_base != 0 && test_mem_stressed_size != 0 {
669 unsafe {
670 TEST_MEM_STRESSED_ELF_MODULE =
671 Some((test_mem_stressed_base, test_mem_stressed_size))
672 };
673 crate::serial_println!(
674 "[limine] /initfs/test_mem_stressed found: base={:#x} size={}",
675 test_mem_stressed_base,
676 test_mem_stressed_size
677 );
678 }
679 if test_mem_region_base != 0 && test_mem_region_size != 0 {
680 unsafe {
681 TEST_MEM_REGION_ELF_MODULE = Some((test_mem_region_base, test_mem_region_size))
682 };
683 crate::serial_println!(
684 "[limine] /initfs/test_mem_region found: base={:#x} size={}",
685 test_mem_region_base,
686 test_mem_region_size
687 );
688 } else {
689 crate::serial_println!(
690 "[limine] WARN: /initfs/test_mem_region not found in modules"
691 );
692 }
693 if test_mem_region_proc_base != 0 && test_mem_region_proc_size != 0 {
694 unsafe {
695 TEST_MEM_REGION_PROC_ELF_MODULE =
696 Some((test_mem_region_proc_base, test_mem_region_proc_size))
697 };
698 crate::serial_println!(
699 "[limine] /initfs/test_mem_region_proc found: base={:#x} size={}",
700 test_mem_region_proc_base,
701 test_mem_region_proc_size
702 );
703 } else {
704 crate::serial_println!(
705 "[limine] WARN: /initfs/test_mem_region_proc not found in modules"
706 );
707 }
708 if test_exec_base != 0 && test_exec_size != 0 {
709 unsafe { TEST_EXEC_ELF_MODULE = Some((test_exec_base, test_exec_size)) };
710 crate::serial_println!(
711 "[limine] /initfs/test_exec found: base={:#x} size={}",
712 test_exec_base,
713 test_exec_size
714 );
715 } else {
716 crate::serial_println!("[limine] WARN: /initfs/test_exec not found in modules");
717 }
718 if test_exec_helper_base != 0 && test_exec_helper_size != 0 {
719 unsafe {
720 TEST_EXEC_HELPER_ELF_MODULE =
721 Some((test_exec_helper_base, test_exec_helper_size))
722 };
723 crate::serial_println!(
724 "[limine] /initfs/test_exec_helper found: base={:#x} size={}",
725 test_exec_helper_base,
726 test_exec_helper_size
727 );
728 } else {
729 crate::serial_println!(
730 "[limine] WARN: /initfs/test_exec_helper not found in modules"
731 );
732 }
733
734 if let Some((base, size)) = resolved.init {
736 unsafe { INIT_ELF_MODULE = Some((base, size)) };
737 crate::serial_println!(
738 "[limine] /initfs/init found: base={:#x} size={}",
739 base,
740 size
741 );
742 } else {
743 crate::serial_println!("[limine] WARN: /initfs/init not found in modules");
744 }
745 if let Some((base, size)) = resolved.console_admin {
746 unsafe { CONSOLE_ADMIN_ELF_MODULE = Some((base, size)) };
747 crate::serial_println!(
748 "[limine] /initfs/console-admin found: base={:#x} size={}",
749 base,
750 size
751 );
752 } else {
753 crate::serial_println!("[limine] WARN: /initfs/console-admin not found in modules");
754 }
755 if let Some((base, size)) = resolved.strate_net {
756 unsafe { STRATE_NET_ELF_MODULE = Some((base, size)) };
757 crate::serial_println!(
758 "[limine] /initfs/strate-net found: base={:#x} size={}",
759 base,
760 size
761 );
762 } else {
763 crate::serial_println!("[limine] WARN: /initfs/strate-net not found in modules");
764 }
765 if let Some((base, size)) = resolved.strate_bus {
766 unsafe { STRATE_BUS_ELF_MODULE = Some((base, size)) };
767 crate::serial_println!(
768 "[limine] /initfs/strate-bus found: base={:#x} size={}",
769 base,
770 size
771 );
772 } else {
773 crate::serial_println!("[limine] WARN: /initfs/strate-bus not found in modules");
774 }
775 if let Some((base, size)) = resolved.dhcp_client {
776 unsafe { DHCP_CLIENT_ELF_MODULE = Some((base, size)) };
777 crate::serial_println!(
778 "[limine] /initfs/bin/dhcp-client found: base={:#x} size={}",
779 base,
780 size
781 );
782 } else {
783 crate::serial_println!(
784 "[limine] WARN: /initfs/bin/dhcp-client not found in modules"
785 );
786 }
787 if let Some((base, size)) = resolved.ping {
788 unsafe { PING_ELF_MODULE = Some((base, size)) };
789 crate::serial_println!(
790 "[limine] /initfs/bin/ping found: base={:#x} size={}",
791 base,
792 size
793 );
794 } else {
795 crate::serial_println!("[limine] WARN: /initfs/bin/ping not found in modules");
796 }
797 if let Some((base, size)) = resolved.telnetd {
798 unsafe { TELNETD_ELF_MODULE = Some((base, size)) };
799 crate::serial_println!(
800 "[limine] /initfs/bin/telnetd found: base={:#x} size={}",
801 base,
802 size
803 );
804 } else {
805 crate::serial_println!("[limine] WARN: /initfs/bin/telnetd not found in modules");
806 }
807 if let Some((base, size)) = resolved.sshd {
808 unsafe { SSHD_ELF_MODULE = Some((base, size)) };
809 crate::serial_println!(
810 "[limine] /initfs/bin/sshd found: base={:#x} size={}",
811 base,
812 size
813 );
814 } else {
815 crate::serial_println!("[limine] WARN: /initfs/bin/sshd not found in modules");
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}