fn main() {
use std::{env, fs, path::PathBuf};
if env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default() == "riscv64" {
let ld = PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("linker.ld");
fs::write(&ld, LINKER_SCRIPT).unwrap();
println!("cargo:rustc-link-arg=-T{}", ld.display());
}
}
const LINKER_SCRIPT: &[u8] = b"
OUTPUT_ARCH(riscv)
ENTRY(_m_start)
/* M-mode code base address: start of RAM on QEMU virt platform */
M_BASE_ADDRESS = 0x80000000;
/* S-mode code base address: M-mode jumps here after init */
S_BASE_ADDRESS = 0x80200000;
SECTIONS {
/* ===== M-mode region (provided by tg-sbi) ===== */
. = M_BASE_ADDRESS;
.text.m_entry : { *(.text.m_entry) }
.text.m_trap : { *(.text.m_trap) }
.bss.m_stack : { *(.bss.m_stack) }
.bss.m_data : { *(.bss.m_data) }
/* ===== S-mode region (this program) ===== */
. = S_BASE_ADDRESS;
.text : {
KEEP(*(.text.entry)) /* _start entry, must come first */
*(.text .text.*) /* other code */
}
.rodata : {
*(.rodata .rodata.*)
*(.srodata .srodata.*)
}
.data : {
*(.data .data.*)
*(.sdata .sdata.*)
}
.bss : {
*(.bss.uninit) /* stack space */
*(.bss .bss.*)
*(.sbss .sbss.*)
}
}";