소스 검색

feat: add kernel config framework, rework panicking

Support defining and specifying configs in build.rs. Add
arch_has_stacktrace and arch_has_shutdown to control behavior on
panicking. Move the codes into panic.rs entirely.

TODO: How can we add dependencies based on arch configs in a more
elegant way?

Signed-off-by: greatbridf <greatbridf@icloud.com>
greatbridf 1 주 전
부모
커밋
7d47e631da
5개의 변경된 파일148개의 추가작업 그리고 61개의 파일을 삭제
  1. 2 2
      .rustfmt.toml
  2. 11 2
      Cargo.toml
  3. 64 1
      build.rs
  4. 12 44
      src/lib.rs
  5. 59 12
      src/panic.rs

+ 2 - 2
.rustfmt.toml

@@ -42,13 +42,13 @@ binop_separator = "Front"
 remove_nested_parens = true
 combine_control_expr = true
 short_array_element_width_threshold = 10
-overflow_delimited_expr = false
+overflow_delimited_expr = true
 struct_field_align_threshold = 0
 enum_discrim_align_threshold = 0
 match_arm_blocks = true
 match_arm_leading_pipes = "Never"
 force_multiline_blocks = false
-fn_params_layout = "Tall"
+fn_params_layout = "Compressed"
 brace_style = "SameLineWhere"
 control_brace_style = "AlwaysSameLine"
 trailing_semicolon = true

+ 11 - 2
Cargo.toml

@@ -47,10 +47,16 @@ futures = { version = "0.3.31", features = [
 static_assertions = "1.1.0"
 cfg-if = "1.0.4"
 
-[target.'cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))'.dependencies]
-virtio-drivers = { version = "0.11.0" }
+[target.'cfg(target_arch = "x86_64")'.dependencies]
+unwinding = { version = "0.2.8", default-features = false, features = [
+    "unwinder",
+    "fde-static",
+    "personality",
+    "panic",
+] }
 
 [target.'cfg(target_arch = "riscv64")'.dependencies]
+virtio-drivers = { version = "0.11.0" }
 unwinding = { version = "0.2.8", default-features = false, features = [
     "unwinder",
     "fde-static",
@@ -58,6 +64,9 @@ unwinding = { version = "0.2.8", default-features = false, features = [
     "panic",
 ] }
 
+[target.'cfg(target_arch = "loongarch64")'.dependencies]
+virtio-drivers = { version = "0.11.0" }
+
 [features]
 default = []
 trace_pci = []

+ 64 - 1
build.rs

@@ -1,6 +1,69 @@
+const ARCH_CONFIGS: &[&str] = &["has_stacktrace", "has_shutdown"];
+
+// Define configs
+
+fn define_config(config: &str) {
+    println!("cargo::rustc-check-cfg=cfg({config})");
+}
+
+fn define_arch_config(config: &str) {
+    define_config(&format!("arch_{config}"));
+}
+
+fn define_arch_configs() {
+    for config in ARCH_CONFIGS {
+        define_arch_config(config);
+    }
+}
+
+fn define_configs() {
+    define_arch_configs();
+}
+
+// Set configs
+
+fn set_config(config: &str) {
+    println!("cargo::rustc-cfg={config}");
+}
+
+fn set_arch_config(config: &str) {
+    set_config(&format!("arch_{config}"));
+}
+
+fn set_arch_configs_x86() {
+    set_arch_config("has_stacktrace");
+}
+
+fn set_arch_configs_riscv64() {
+    set_arch_config("has_stacktrace");
+    set_arch_config("has_shutdown");
+}
+
+fn set_arch_configs_loongarch64() {
+    set_arch_config("has_shutdown");
+}
+
+fn set_arch_configs() {
+    match std::env::var("CARGO_CFG_TARGET_ARCH").as_deref().unwrap() {
+        "x86_64" => set_arch_configs_x86(),
+        "riscv64" => set_arch_configs_riscv64(),
+        "loongarch64" => set_arch_configs_loongarch64(),
+        arch => panic!("Unsupported architecture: {}", arch),
+    }
+}
+
+fn set_configs() {
+    set_arch_configs();
+}
+
 fn main() -> Result<(), Box<dyn std::error::Error>> {
+    define_configs();
+    set_configs();
+
     println!("cargo:rustc-link-arg=-T{}", "link.x");
-    if let Ok(extra_link_args) = std::env::var("DEP_EONIX_HAL_EXTRA_LINK_ARGS") {
+
+    if let Ok(extra_link_args) = std::env::var("DEP_EONIX_HAL_EXTRA_LINK_ARGS")
+    {
         for arg in extra_link_args.split_whitespace() {
             println!("cargo:rustc-link-arg={}", arg);
         }

+ 12 - 44
src/lib.rs

@@ -13,9 +13,6 @@ extern crate alloc;
 #[macro_use]
 extern crate static_assertions;
 
-#[cfg(any(target_arch = "riscv64", target_arch = "x86_64"))]
-extern crate unwinding;
-
 mod driver;
 mod fs;
 mod hash;
@@ -23,7 +20,6 @@ mod io;
 mod kernel;
 mod kernel_init;
 mod net;
-#[cfg(any(target_arch = "riscv64", target_arch = "x86_64"))]
 mod panic;
 mod path;
 mod prelude;
@@ -47,7 +43,9 @@ use eonix_runtime::scheduler::RUNTIME;
 use kernel::mem::GlobalPageAlloc;
 use kernel::task::{KernelStack, ProcessList, ProgramLoader};
 use kernel::vfs::dentry::Dentry;
-use kernel::vfs::mount::{do_mount, MS_NOATIME, MS_NODEV, MS_NOSUID, MS_RDONLY};
+use kernel::vfs::mount::{
+    do_mount, MS_NOATIME, MS_NODEV, MS_NOSUID, MS_RDONLY,
+};
 use kernel::vfs::types::Permission;
 use kernel::vfs::FsContext;
 use kernel::CharDevice;
@@ -55,40 +53,6 @@ use kernel_init::setup_memory;
 use path::Path;
 use prelude::*;
 
-#[cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))]
-fn do_panic() -> ! {
-    #[cfg(target_arch = "riscv64")]
-    panic::stack_trace();
-
-    shutdown();
-}
-
-#[cfg(not(any(target_arch = "riscv64", target_arch = "loongarch64")))]
-fn do_panic() -> ! {
-    // Spin forever.
-    loop {
-        spin_loop();
-    }
-}
-
-#[panic_handler]
-fn panic(info: &core::panic::PanicInfo) -> ! {
-    if let Some(location) = info.location() {
-        println_fatal!(
-            "panicked at {}:{}:{}",
-            location.file(),
-            location.line(),
-            location.column()
-        );
-    } else {
-        println_fatal!("panicked at <UNKNOWN>");
-    }
-    println_fatal!();
-    println_fatal!("{}", info.message());
-
-    do_panic()
-}
-
 static BSP_OK: AtomicBool = AtomicBool::new(false);
 static CPU_SHUTTING_DOWN: AtomicUsize = AtomicUsize::new(0);
 
@@ -220,9 +184,10 @@ async fn init_process(early_kstack: PRange) {
     let load_info = {
         // mount fat32 /mnt directory
         let fs_context = FsContext::global();
-        let mnt_dir = Dentry::open(fs_context, Path::new(b"/mnt/").unwrap(), true)
-            .await
-            .unwrap();
+        let mnt_dir =
+            Dentry::open(fs_context, Path::new(b"/mnt/").unwrap(), true)
+                .await
+                .unwrap();
 
         mnt_dir
             .mkdir(Permission::new(0o755))
@@ -239,12 +204,15 @@ async fn init_process(early_kstack: PRange) {
         .await
         .unwrap();
 
-        let init_names = [&b"/init"[..], &b"/sbin/init"[..], &b"/mnt/initsh"[..]];
+        let init_names =
+            [&b"/init"[..], &b"/sbin/init"[..], &b"/mnt/initsh"[..]];
 
         let mut init_name = None;
         let mut init = None;
         for name in init_names {
-            if let Ok(dentry) = Dentry::open(fs_context, Path::new(name).unwrap(), true).await {
+            if let Ok(dentry) =
+                Dentry::open(fs_context, Path::new(name).unwrap(), true).await
+            {
                 if dentry.is_valid() {
                     init_name = Some(CString::new(name).unwrap());
                     init = Some(dentry);

+ 59 - 12
src/panic.rs

@@ -1,16 +1,61 @@
-use core::ffi::c_void;
+use core::panic::PanicInfo;
 
 use eonix_log::println_fatal;
-use unwinding::abi::{
-    UnwindContext, UnwindReasonCode, _Unwind_Backtrace, _Unwind_GetIP, _Unwind_GetRegionStart,
-};
 
-pub fn stack_trace() {
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    if let Some(location) = info.location() {
+        println_fatal!(
+            "panicked at {}:{}:{}",
+            location.file(),
+            location.line(),
+            location.column()
+        );
+    } else {
+        println_fatal!("panicked at <UNKNOWN>");
+    }
+    println_fatal!();
+    println_fatal!("{}", info.message());
+
+    #[cfg(arch_has_stacktrace)]
+    stacktrace::print_stacktrace();
+
+    panic_forever();
+}
+
+fn panic_forever() -> ! {
+    #[cfg(arch_has_shutdown)]
+    {
+        eonix_hal::arch_exported::bootstrap::shutdown();
+    }
+    #[cfg(not(arch_has_shutdown))]
+    {
+        // Spin forever
+        loop {
+            core::hint::spin_loop();
+        }
+    }
+}
+
+#[cfg(arch_has_stacktrace)]
+mod stacktrace {
+    extern crate unwinding;
+
+    use core::ffi::c_void;
+
+    use eonix_log::println_fatal;
+    use unwinding::abi::{
+        UnwindContext, UnwindReasonCode, _Unwind_Backtrace, _Unwind_GetIP,
+        _Unwind_GetRegionStart,
+    };
+
     struct CallbackData {
         counter: usize,
     }
 
-    extern "C" fn callback(unwind_ctx: &UnwindContext<'_>, arg: *mut c_void) -> UnwindReasonCode {
+    extern "C" fn unwind_print(
+        unwind_ctx: &UnwindContext<'_>, arg: *mut c_void,
+    ) -> UnwindReasonCode {
         let data = unsafe { &mut *(arg as *mut CallbackData) };
         data.counter += 1;
 
@@ -24,12 +69,14 @@ pub fn stack_trace() {
         UnwindReasonCode::NO_REASON
     }
 
-    println_fatal!("--------------8< CUT HERE 8<--------------");
-    println_fatal!("Stacktrace:");
-    println_fatal!();
+    pub fn print_stacktrace() {
+        println_fatal!("--------------8< CUT HERE 8<--------------");
+        println_fatal!("Stacktrace:");
+        println_fatal!();
 
-    let mut data = CallbackData { counter: 0 };
-    _Unwind_Backtrace(callback, &raw mut data as *mut c_void);
+        let mut data = CallbackData { counter: 0 };
+        _Unwind_Backtrace(unwind_print, &raw mut data as *mut c_void);
 
-    println_fatal!("--------------8< CUT HERE 8<--------------");
+        println_fatal!("--------------8< CUT HERE 8<--------------");
+    }
 }