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