1#![feature(alloc_error_handler)]
6#![feature(allocator_api)]
7#![feature(btree_cursors)]
8#![feature(core_intrinsics)]
9#![feature(iter_advance_by)]
10#![feature(linkage)]
11#![feature(macro_metavar_expr)]
12#![feature(min_specialization)]
13#![feature(negative_impls)]
14#![feature(ptr_metadata)]
15#![feature(sync_unsafe_cell)]
16#![expect(internal_features)]
17#![no_std]
18#![warn(missing_docs)]
19
20extern crate alloc;
21
22#[cfg_attr(target_arch = "x86_64", path = "arch/x86/mod.rs")]
23#[cfg_attr(target_arch = "riscv64", path = "arch/riscv/mod.rs")]
24#[cfg_attr(target_arch = "loongarch64", path = "arch/loongarch/mod.rs")]
25pub mod arch;
26
27pub mod boot;
28pub mod bus;
29pub mod console;
30pub mod cpu;
31mod error;
32mod ex_table;
33pub mod io;
34pub mod irq;
35pub mod logger;
36pub mod mm;
37pub mod panic;
38pub mod power;
39pub mod prelude;
40pub mod smp;
41pub mod sync;
42pub mod task;
43pub mod timer;
44pub mod user;
45pub mod util;
46
47#[cfg(feature = "coverage")]
48mod coverage;
49
50use core::sync::atomic::{AtomicBool, Ordering};
51
52pub use ostd_macros::{
53 global_frame_allocator, global_heap_allocator, global_heap_allocator_slot_map, main,
54 panic_handler,
55};
56pub use ostd_pod::Pod;
57
58pub use self::{error::Error, prelude::Result};
59
60unsafe fn init() {
73 arch::enable_cpu_features();
74
75 unsafe { mm::frame::allocator::init_early_allocator() };
78
79 #[cfg(target_arch = "x86_64")]
80 arch::if_tdx_enabled!({
81 } else {
82 arch::serial::init();
83 });
84 #[cfg(not(target_arch = "x86_64"))]
85 arch::serial::init();
86
87 logger::init();
88
89 unsafe { cpu::init_on_bsp() };
94
95 let meta_pages = unsafe { mm::frame::meta::init() };
97 unsafe { mm::frame::allocator::init() };
101
102 mm::kspace::init_kernel_page_table(meta_pages);
103
104 unsafe { mm::kspace::activate_kernel_page_table() };
106
107 sync::init();
108
109 boot::init_after_heap();
110
111 mm::dma::init();
112
113 unsafe { arch::late_init_on_bsp() };
115
116 #[cfg(target_arch = "x86_64")]
117 arch::if_tdx_enabled!({
118 arch::serial::init();
119 });
120
121 smp::init();
122
123 unsafe { crate::mm::page_table::boot_pt::dismiss() };
128
129 arch::irq::enable_local();
130
131 invoke_ffi_init_funcs();
132
133 IN_BOOTSTRAP_CONTEXT.store(false, Ordering::Relaxed);
134}
135
136pub(crate) static IN_BOOTSTRAP_CONTEXT: AtomicBool = AtomicBool::new(true);
138
139fn invoke_ffi_init_funcs() {
143 unsafe extern "C" {
144 fn __sinit_array();
145 fn __einit_array();
146 }
147 let call_len = (__einit_array as *const () as usize - __sinit_array as *const () as usize) / 8;
148 for i in 0..call_len {
149 unsafe {
150 let function = (__sinit_array as *const () as usize + 8 * i) as *const fn();
151 (*function)();
152 }
153 }
154}
155
156mod feature_validation {
157 #[cfg(all(not(target_arch = "riscv64"), feature = "riscv_sv39_mode"))]
158 compile_error!(
159 "feature \"riscv_sv39_mode\" cannot be specified for architectures other than RISC-V"
160 );
161}
162
163#[cfg(ktest)]
165mod test {
166 use crate::prelude::*;
167
168 #[ktest]
169 #[expect(clippy::eq_op)]
170 fn trivial_assertion() {
171 assert_eq!(0, 0);
172 }
173
174 #[ktest]
175 #[should_panic]
176 fn failing_assertion() {
177 assert_eq!(0, 1);
178 }
179
180 #[ktest]
181 #[should_panic(expected = "expected panic message")]
182 fn expect_panic() {
183 panic!("expected panic message");
184 }
185}
186
187#[doc(hidden)]
188pub mod ktest {
189 pub use ostd_macros::{test_main as main, test_panic_handler as panic_handler};
196 pub use ostd_test::*;
197}