Переглянути джерело

style: add helper macros to retrieve symbol constants

- Add `extern_symbol_value` to retrieve far relative symbol values.
- Get `BSS_LENGTH` and `__kernel_end` using `extern_symbol_addr`.
- Get `_ap_start` using `extern_symbol_value`.

Signed-off-by: greatbridf <greatbridf@icloud.com>
greatbridf 1 тиждень тому
батько
коміт
53ae1851d9

+ 10 - 18
crates/eonix_hal/src/arch/riscv64/bootstrap.rs

@@ -36,6 +36,7 @@ use crate::bootstrap::BootStrapData;
 use crate::mm::{
     ArchMemory, BasicPageAlloc, BasicPageAllocRef, ScopedAllocator,
 };
+use crate::{extern_symbol_addr, extern_symbol_value};
 
 #[unsafe(link_section = ".bootstrap.stack")]
 static BOOT_STACK: [u8; 4096 * 16] = [0; 4096 * 16];
@@ -156,10 +157,6 @@ pub unsafe extern "C" fn riscv64_start(hart_id: usize, dtb_addr: PAddr) -> ! {
     }
 }
 
-unsafe extern "C" {
-    fn BSS_LENGTH();
-}
-
 /// TODO:
 /// 对kernel image添加更细的控制,或者不加也行
 fn setup_kernel_page_table(alloc: BasicPageAllocRef) {
@@ -171,17 +168,17 @@ fn setup_kernel_page_table(alloc: BasicPageAllocRef) {
 
     let attr = PageAttribute::WRITE
         | PageAttribute::READ
-        | PageAttribute::EXECUTE
         | PageAttribute::GLOBAL
         | PageAttribute::PRESENT;
 
     const KERNEL_BSS_START: VAddr = VAddr::from(0xffffffff40000000);
 
+    let bss_length = extern_symbol_addr!(BSS_LENGTH);
+
     // Map kernel BSS
-    let bss_range = VRange::from(KERNEL_BSS_START).grow(BSS_LENGTH as usize);
+    let bss_range = VRange::from(KERNEL_BSS_START).grow(bss_length);
     for pte in global_page_table.iter_kernel(bss_range) {
         let page = alloc.alloc().unwrap();
-        let attr = attr.difference(PageAttribute::EXECUTE);
 
         pte.set(page.into_raw(), attr.into());
     }
@@ -192,7 +189,7 @@ fn setup_kernel_page_table(alloc: BasicPageAllocRef) {
         core::ptr::write_bytes(
             KERNEL_BSS_START.addr() as *mut (),
             0,
-            BSS_LENGTH as usize,
+            bss_length,
         );
     }
 
@@ -247,15 +244,6 @@ fn setup_cpu(alloc: impl FrameAlloc, hart_id: usize) {
     percpu_area.register(cpu.cpuid());
 }
 
-fn get_ap_start_addr() -> usize {
-    unsafe extern "C" {
-        fn _ap_start();
-    }
-    static AP_START_VALUE: &'static unsafe extern "C" fn() =
-        &(_ap_start as unsafe extern "C" fn());
-    unsafe { (AP_START_VALUE as *const _ as *const usize).read_volatile() }
-}
-
 fn bootstrap_smp(alloc: impl Allocator, page_alloc: &RefCell<BasicPageAlloc>) {
     let local_hart_id = CPU::local().cpuid();
     let mut ap_count = 0;
@@ -286,7 +274,11 @@ fn bootstrap_smp(alloc: impl Allocator, page_alloc: &RefCell<BasicPageAlloc>) {
         }
 
         unsafe {
-            hart_start(hart_id, PhysicalAddress::new(get_ap_start_addr()), 0);
+            hart_start(
+                hart_id,
+                PhysicalAddress::new(extern_symbol_value!(_ap_start)),
+                0,
+            );
         }
 
         while AP_COUNT.load(Ordering::Acquire) == ap_count {

+ 3 - 5
crates/eonix_hal/src/arch/riscv64/mm.rs

@@ -16,6 +16,7 @@ use riscv::register::satp;
 use super::config::mm::{PHYS_MAP_VIRT, ROOT_PAGE_TABLE_PFN};
 use super::fdt::{FdtExt, FDT};
 use crate::arch::riscv64::config::mm::KIMAGE_OFFSET;
+use crate::extern_symbol_addr;
 use crate::mm::BasicPageAlloc;
 
 const PAGE_TABLE_BASE: PFN = PFN::from_val(ROOT_PAGE_TABLE_PFN);
@@ -291,12 +292,9 @@ where
     T: PresentRam,
 {
     fn free_ram(self) -> impl Iterator<Item = PRange> {
-        unsafe extern "C" {
-            fn __kernel_start();
-            fn __kernel_end();
-        }
+        let kernel_end = extern_symbol_addr!(__kernel_end) - KIMAGE_OFFSET;
+        let kernel_end = PAddr::from(kernel_end).ceil();
 
-        let kernel_end = PAddr::from(__kernel_end as usize - KIMAGE_OFFSET);
         let paddr_after_kimage_aligned = kernel_end.ceil_to(0x200000);
 
         core::iter::once(PRange::new(kernel_end, paddr_after_kimage_aligned))

+ 14 - 0
crates/eonix_hal/src/lib.rs

@@ -69,3 +69,17 @@ macro_rules! extern_symbol_addr {
         $crate::symbol_addr!($sym, $type)
     }};
 }
+
+#[macro_export]
+macro_rules! extern_symbol_value {
+    ($sym:ident) => {{
+        unsafe extern "C" {
+            fn $sym();
+        }
+
+        static SYMBOL_ADDR: &'static unsafe extern "C" fn() =
+            &($sym as unsafe extern "C" fn());
+
+        unsafe { (SYMBOL_ADDR as *const _ as *const usize).read_volatile() }
+    }};
+}