1#![doc = include_str!("../README.md")]
4#![feature(alloc_error_handler)]
5#![feature(allocator_api)]
6#![feature(btree_cursors)]
7#![feature(core_intrinsics)]
8#![feature(iter_advance_by)]
9#![feature(linkage)]
10#![feature(macro_metavar_expr)]
11#![feature(min_specialization)]
12#![feature(negative_impls)]
13#![feature(ptr_metadata)]
14#![feature(sync_unsafe_cell)]
15#![expect(internal_features)]
16#![no_std]
17#![warn(missing_docs)]
18
19extern crate alloc;
20#[macro_use]
21extern crate ostd_pod;
22
23#[cfg_attr(target_arch = "x86_64", path = "arch/x86/mod.rs")]
24#[cfg_attr(target_arch = "riscv64", path = "arch/riscv/mod.rs")]
25#[cfg_attr(target_arch = "loongarch64", path = "arch/loongarch/mod.rs")]
26pub mod arch;
27
28pub mod boot;
29pub mod bus;
30pub mod console;
31pub mod cpu;
32mod error;
33mod ex_table;
34pub mod io;
35pub mod irq;
36pub mod logger;
37pub mod mm;
38pub mod panic;
39pub mod power;
40pub mod prelude;
41pub mod smp;
42pub mod sync;
43pub mod task;
44pub mod timer;
45pub mod user;
46pub mod util;
47
48#[cfg(feature = "coverage")]
49mod coverage;
50
51use core::sync::atomic::{AtomicBool, Ordering};
52
53pub use ostd_macros::{
54 global_frame_allocator, global_heap_allocator, global_heap_allocator_slot_map, main,
55 panic_handler,
56};
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 unsafe { arch::late_init_on_bsp() };
113
114 #[cfg(target_arch = "x86_64")]
115 arch::if_tdx_enabled!({
116 arch::serial::init();
117 });
118
119 smp::init();
120
121 unsafe { crate::mm::page_table::boot_pt::dismiss() };
126
127 arch::irq::enable_local();
128
129 invoke_ffi_init_funcs();
130
131 IN_BOOTSTRAP_CONTEXT.store(false, Ordering::Relaxed);
132}
133
134pub(crate) static IN_BOOTSTRAP_CONTEXT: AtomicBool = AtomicBool::new(true);
136
137fn invoke_ffi_init_funcs() {
141 unsafe extern "C" {
142 fn __sinit_array();
143 fn __einit_array();
144 }
145 let call_len = (__einit_array as *const () as usize - __sinit_array as *const () as usize) / 8;
146 for i in 0..call_len {
147 unsafe {
148 let function = (__sinit_array as *const () as usize + 8 * i) as *const fn();
149 (*function)();
150 }
151 }
152}
153
154mod feature_validation {
155 #[cfg(all(not(target_arch = "riscv64"), feature = "riscv_sv39_mode"))]
156 compile_error!(
157 "feature \"riscv_sv39_mode\" cannot be specified for architectures other than RISC-V"
158 );
159}
160
161#[cfg(ktest)]
163mod test {
164 use crate::prelude::*;
165
166 #[ktest]
167 #[expect(clippy::eq_op)]
168 fn trivial_assertion() {
169 assert_eq!(0, 0);
170 }
171
172 #[ktest]
173 #[should_panic]
174 fn failing_assertion() {
175 assert_eq!(0, 1);
176 }
177
178 #[ktest]
179 #[should_panic(expected = "expected panic message")]
180 fn expect_panic() {
181 panic!("expected panic message");
182 }
183}
184
185#[doc(hidden)]
186pub mod ktest {
187 pub use ostd_macros::{test_main as main, test_panic_handler as panic_handler};
194 pub use ostd_test::*;
195}