Эх сурвалжийг харах

feat(hal): add riscv64's linker scrpit

Heinz 8 сар өмнө
parent
commit
384477d57e

+ 15 - 0
crates/eonix_hal/build.rs

@@ -7,6 +7,18 @@ fn read_dependent_script(script: &str) -> Result<String, Box<dyn std::error::Err
     Ok(content)
 }
 
+fn process_ldscript_riscv64(script: &mut String) -> Result<(), Box<dyn std::error::Error>> {
+    println!("cargo:extra-link-args= --no-check-sections");
+
+    let memory = read_dependent_script("src/arch/riscv64/memory.x")?;
+    let link = read_dependent_script("src/arch/riscv64/link.x")?;
+
+    *script = memory + script;
+    script.push_str(&link);
+
+    Ok(())
+}
+
 fn process_ldscript_x86(script: &mut String) -> Result<(), Box<dyn std::error::Error>> {
     // Otherwise `bootstrap.rs` might be ignored and not linked in.
     println!("cargo:extra-link-args=--undefined=move_mbr --no-check-sections");
@@ -28,6 +40,9 @@ fn process_ldscript_arch(
         "x86_64" => {
             process_ldscript_x86(script)?;
         }
+        "riscv64" => {
+            process_ldscript_riscv64(script)?;
+        }
         _ => panic!("Unsupported architecture: {}", arch),
     }
 

+ 85 - 0
crates/eonix_hal/src/arch/riscv64/link.x

@@ -0,0 +1,85 @@
+SECTIONS {
+    .text _stext : AT(RAM) {
+        __kernel_start = .;
+        __stext = .;
+
+        *(.text.entry);
+        *(.text .text.*);
+
+        . = ALIGN(0x1000);
+    } > REGION_TEXT
+
+    __etext = .;
+}
+
+SECTIONS {
+    .text.syscall_fns :
+    {
+
+        KEEP(*(.syscall_fns*));
+
+    } > REGION_TEXT
+}
+INSERT AFTER .text;
+
+SECTIONS {
+    .rodata.fixups :
+    {
+        . = ALIGN(16);
+        FIX_START = .;
+
+        KEEP(*(.fix));
+
+        FIX_END = .;
+    } > REGION_RODATA
+
+    .rodata.syscalls :
+    {
+        . = ALIGN(16);
+        __raw_syscall_handlers_start = .;
+
+        RAW_SYSCALL_HANDLERS = .;
+        KEEP(*(.raw_syscalls*));
+
+        __raw_syscall_handlers_end = .;
+
+        RAW_SYSCALL_HANDLERS_SIZE =
+            ABSOLUTE(__raw_syscall_handlers_end - __raw_syscall_handlers_start);
+    } > REGION_RODATA
+}
+INSERT AFTER .rodata;
+
+SECTIONS {
+    .percpu 0 : ALIGN(16)
+    {
+        __spercpu = .;
+
+        PERCPU_START = .;
+
+        . = ALIGN(16);
+
+        *(.percpu .percpu*);
+
+        . = ALIGN(16);
+        __epercpu = .;
+    } > LOWMEM AT> REGION_RODATA
+
+    PERCPU_DATA_START = LOADADDR(.percpu);
+    PERCPU_LENGTH = ABSOLUTE(__epercpu - __spercpu);
+
+    KIMAGE_PAGES = (__edata - _stext + 0x1000 - 1) / 0x1000;
+    KIMAGE_32K_COUNT = (KIMAGE_PAGES + 8 - 1) / 8;
+    __kernel_end = .;
+
+    BSS_LENGTH = ABSOLUTE(__ebss - __sbss);
+}
+INSERT AFTER .rodata;
+
+SECTIONS {
+    .bootregion : {
+        . = ALIGN(4096);
+        *(.bootstack);
+        *(.bootdata);
+    } > REGION_BOOT
+}
+INSERT AFTER .rodata;

+ 17 - 0
crates/eonix_hal/src/arch/riscv64/memory.x

@@ -0,0 +1,17 @@
+OUTPUT_ARCH(riscv)
+ENTRY(_start)
+
+RAM = 0x80200000;
+
+MEMORY {
+    LOWMEM : org = 0x0000000000000000, len = 1M
+    KBSS   : org = 0xffffffff00000000, len = 2M
+    KIMAGE : org = 0xffffffff80200000, len = 2M
+}
+
+REGION_ALIAS("REGION_TEXT", KIMAGE);
+REGION_ALIAS("REGION_RODATA", KIMAGE);
+REGION_ALIAS("REGION_BOOT", KIMAGE);
+REGION_ALIAS("REGION_DATA", KIMAGE);
+REGION_ALIAS("REGION_BSS", KBSS);
+REGION_ALIAS("REGION_EHFRAME", KIMAGE);