ostd/lib.rs
1// SPDX-License-Identifier: MPL-2.0
2//! The standard library for Asterinas and other Rust OSes.
3#![feature(alloc_error_handler)]
4#![feature(allocator_api)]
5#![feature(btree_cursors)]
6#![feature(const_ptr_sub_ptr)]
7#![feature(const_trait_impl)]
8#![feature(core_intrinsics)]
9#![feature(coroutines)]
10#![feature(fn_traits)]
11#![feature(iter_advance_by)]
12#![feature(iter_from_coroutine)]
13#![feature(let_chains)]
14#![feature(linkage)]
15#![feature(min_specialization)]
16//#![feature(negative_impls)]
17#![feature(ptr_metadata)]
18#![feature(ptr_sub_ptr)]
19#![feature(sync_unsafe_cell)]
20#![feature(trait_upcasting)]
21#![feature(unbounded_shifts)]
22#![expect(internal_features)]
23#![no_std]
24#![warn(missing_docs)]
25#![feature(proc_macro_hygiene)]
26
27extern crate alloc;
28
29use vstd_extra::prelude;
30
31//#[cfg(target_arch = "x86_64")]
32#[path = "arch/x86/mod.rs"]
33#[allow(rustdoc::invalid_rust_codeblocks)]
34pub mod arch;
35//#[cfg(target_arch = "riscv64")]
36//#[path = "arch/riscv/mod.rs"]
37//pub mod arch;
38pub mod boot;
39/*pub mod bus;
40pub mod console;
41pub mod cpu;*/
42pub mod error;
43/*pub mod io;
44pub mod logger;*/
45#[allow(unused_parens)]
46#[allow(unused_braces)]
47#[allow(rustdoc::invalid_rust_codeblocks)]
48#[allow(rustdoc::invalid_html_tags)]
49#[allow(rustdoc::broken_intra_doc_links)]
50#[allow(rustdoc::missing_docs)]
51pub mod mm;
52/*pub mod panic;
53pub mod prelude;
54pub mod smp;*/
55#[allow(rustdoc::invalid_rust_codeblocks)]
56#[allow(rustdoc::broken_intra_doc_links)]
57pub mod sync;
58pub mod task;
59/* pub mod timer;
60pub mod trap;
61pub mod user;*/
62#[path = "../specs/lib.rs"]
63pub mod specs;
64pub mod util;
65
66/*use core::sync::atomic::{AtomicBool, Ordering};
67
68pub use ostd_macros::{
69 global_frame_allocator, global_heap_allocator, global_heap_allocator_slot_map, main,
70 panic_handler,
71};
72pub use ostd_pod::Pod;
73
74pub use self::{error::Error, prelude::Result};
75
76/// Initializes OSTD.
77///
78/// This function represents the first phase booting up the system. It makes
79/// all functionalities of OSTD available after the call.
80///
81/// # Safety
82///
83/// This function should be called only once and only on the BSP.
84//
85// TODO: We need to refactor this function to make it more modular and
86// make inter-initialization-dependencies more clear and reduce usages of
87// boot stage only global variables.
88#[doc(hidden)]
89unsafe fn init() {
90 arch::enable_cpu_features();
91
92 // SAFETY: This function is called only once, before `allocator::init`
93 // and after memory regions are initialized.
94 unsafe { mm::frame::allocator::init_early_allocator() };
95
96 #[cfg(target_arch = "x86_64")]
97 arch::if_tdx_enabled!({
98 } else {
99 arch::serial::init();
100 });
101 #[cfg(not(target_arch = "x86_64"))]
102 arch::serial::init();
103
104 logger::init();
105
106 // SAFETY:
107 // 1. They are only called once in the boot context of the BSP.
108 // 2. The number of CPUs are available because ACPI has been initialized.
109 // 3. No CPU-local objects have been accessed yet.
110 unsafe { cpu::init_on_bsp() };
111
112 // SAFETY: We are on the BSP and APs are not yet started.
113 let meta_pages = unsafe { mm::frame::meta::init() };
114 // The frame allocator should be initialized immediately after the metadata
115 // is initialized. Otherwise the boot page table can't allocate frames.
116 // SAFETY: This function is called only once.
117 unsafe { mm::frame::allocator::init() };
118
119 mm::kspace::init_kernel_page_table(meta_pages);
120
121 sync::init();
122
123 boot::init_after_heap();
124
125 mm::dma::init();
126
127 unsafe { arch::late_init_on_bsp() };
128
129 #[cfg(target_arch = "x86_64")]
130 arch::if_tdx_enabled!({
131 arch::serial::init();
132 });
133
134 smp::init();
135
136 // SAFETY: This function is called only once on the BSP.
137 unsafe {
138 mm::kspace::activate_kernel_page_table();
139 }
140
141 bus::init();
142
143 arch::irq::enable_local();
144
145 invoke_ffi_init_funcs();
146
147 IN_BOOTSTRAP_CONTEXT.store(false, Ordering::Relaxed);
148}
149
150/// Indicates whether the kernel is in bootstrap context.
151pub(crate) static IN_BOOTSTRAP_CONTEXT: AtomicBool = AtomicBool::new(true);
152
153/// Invoke the initialization functions defined in the FFI.
154/// The component system uses this function to call the initialization functions of
155/// the components.
156fn invoke_ffi_init_funcs() {
157 extern "C" {
158 fn __sinit_array();
159 fn __einit_array();
160 }
161 let call_len = (__einit_array as usize - __sinit_array as usize) / 8;
162 for i in 0..call_len {
163 unsafe {
164 let function = (__sinit_array as usize + 8 * i) as *const fn();
165 (*function)();
166 }
167 }
168}
169
170/// Simple unit tests for the ktest framework.
171#[cfg(ktest)]
172mod test {
173 use crate::prelude::*;
174
175 #[ktest]
176 #[expect(clippy::eq_op)]
177 fn trivial_assertion() {
178 assert_eq!(0, 0);
179 }
180
181 #[ktest]
182 #[should_panic]
183 fn failing_assertion() {
184 assert_eq!(0, 1);
185 }
186
187 #[ktest]
188 #[should_panic(expected = "expected panic message")]
189 fn expect_panic() {
190 panic!("expected panic message");
191 }
192}
193
194#[doc(hidden)]
195pub mod ktest {
196 //! The module re-exports everything from the [`ostd_test`] crate, as well
197 //! as the test entry point macro.
198 //!
199 //! It is rather discouraged to use the definitions here directly. The
200 //! `ktest` attribute is sufficient for all normal use cases.
201
202 pub use ostd_macros::{test_main as main, test_panic_handler as panic_handler};
203 pub use ostd_test::*;
204}
205*/