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