Skip to main content

os/
main.rs

1//! The main module and entrypoint
2//!
3//! Various facilities of the kernels are implemented as submodules. The most
4//! important ones are:
5//!
6//! - [`trap`]: Handles all cases of switching from userspace to the kernel
7//! - [`syscall`]: System call handling and implementation
8//!
9//! The operating system also starts in this module. Kernel code starts
10//! executing from `entry.asm`, after which [`rust_main()`] is called to
11//! initialize various pieces of functionality. (See its source code for
12//! details.)
13//!
14//! We then call [`batch::run_next_app()`] and for the first time go to
15//! userspace.
16
17#![deny(missing_docs)]
18#![deny(warnings)]
19#![no_std]
20#![no_main]
21
22macro_rules! linker_symbol_addr {
23    ($symbol:path) => {
24        ($symbol as *const ()).addr()
25    };
26}
27
28use core::arch::global_asm;
29
30use log::*;
31#[macro_use]
32mod console;
33pub mod batch;
34mod lang_items;
35mod logging;
36mod sbi;
37mod sync;
38pub mod syscall;
39pub mod trap;
40
41global_asm!(include_str!("entry.asm"));
42global_asm!(include_str!("link_app.S"));
43
44/// clear BSS segment
45fn clear_bss() {
46    unsafe extern "C" {
47        safe fn sbss();
48        safe fn ebss();
49    }
50    unsafe {
51        core::slice::from_raw_parts_mut(
52            linker_symbol_addr!(sbss) as *mut u8,
53            linker_symbol_addr!(ebss) - linker_symbol_addr!(sbss),
54        )
55        .fill(0);
56    }
57}
58
59/// the rust entry-point of os
60#[unsafe(no_mangle)]
61pub fn rust_main() -> ! {
62    unsafe extern "C" {
63        safe fn stext(); // begin addr of text segment
64        safe fn etext(); // end addr of text segment
65        safe fn srodata(); // start addr of Read-Only data segment
66        safe fn erodata(); // end addr of Read-Only data ssegment
67        safe fn sdata(); // start addr of data segment
68        safe fn edata(); // end addr of data segment
69        safe fn sbss(); // start addr of BSS segment
70        safe fn ebss(); // end addr of BSS segment
71        safe fn boot_stack_lower_bound(); // stack lower bound
72        safe fn boot_stack_top(); // stack top
73    }
74    clear_bss();
75    logging::init();
76    println!("[kernel] Hello, world!");
77    trace!(
78        "[kernel] .text [{:#x}, {:#x})",
79        linker_symbol_addr!(stext),
80        linker_symbol_addr!(etext)
81    );
82    debug!(
83        "[kernel] .rodata [{:#x}, {:#x})",
84        linker_symbol_addr!(srodata),
85        linker_symbol_addr!(erodata)
86    );
87    info!(
88        "[kernel] .data [{:#x}, {:#x})",
89        linker_symbol_addr!(sdata),
90        linker_symbol_addr!(edata)
91    );
92    warn!(
93        "[kernel] boot_stack top=bottom={:#x}, lower_bound={:#x}",
94        linker_symbol_addr!(boot_stack_top),
95        linker_symbol_addr!(boot_stack_lower_bound)
96    );
97    error!(
98        "[kernel] .bss [{:#x}, {:#x})",
99        linker_symbol_addr!(sbss),
100        linker_symbol_addr!(ebss)
101    );
102    trap::init();
103    batch::init();
104    batch::run_next_app();
105}