gpt4 book ai didi

linker - 通过使用内联汇编的 Raspberry Pi3 的 Rust 启动代码

转载 作者:行者123 更新时间:2023-11-29 08:15:49 25 4
gpt4 key购买 nike

我正在用 Rust 为 Raspberry Pi 3 编写裸机代码,但是,我对放置在@0x80000 上的代码有疑问,因为它不是 _start 功能。

编译器设置为 AArch64 架构,我使用 LLD 作为链接器。

# .cargo/config
[build]
target = "aarch64-unknown-none"

[target.aarch64-unknown-none]
rustflags = [
# uncomment to use rustc LLD linker
"-C", "link-arg=-Tlayout.ld",
"-C", "linker=lld-link",
"-Z", "linker-flavor=ld.lld",
]

启动后调用的第一个函数:(获取核心ID,让主继续,其他停止;为主内存和初始化内存设置堆栈)

#[link_section = ".reset_vector"]
#[no_mangle]
pub extern "C" fn _start() -> !{

unsafe {
// Halt all cores but the primary
asm!(" mrs x1, mpidr_el1
and x1, x1, #3
cmp x1, #0
bne halt"::::"volatile");

// Setup stack pointer
asm!(" mov sp, #0x80000"::::"volatile");
}

init_runtime();

main();
loop{}
}

fn init_runtime() {
extern "C" {
static mut _sbss: u64;
static mut _ebss: u64;

static mut _sdata: u64;
static mut _edata: u64;

static _sidata: u64;
}

unsafe{
// Zero the BSS section in RAM
r0::zero_bss(&mut _sbss, &mut _ebss);
// Copy variables in DATA section in FLASH to RAM
r0::init_data(&mut _sdata, &mut _edata, &_sidata);
}
}

停止除主要核心之外的核心的功能:

#[no_mangle]
pub fn halt() {
unsafe {asm!("wfe"::::"volatile");}
}

我正在使用 r0 crate 来初始化内存:

fn init_runtime() {
extern "C" {
static mut _sbss: u64;
static mut _ebss: u64;

static mut _sdata: u64;
static mut _edata: u64;

static _sidata: u64;
}

unsafe{
// Zero the BSS section in RAM
r0::zero_bss(&mut _sbss, &mut _ebss);
// Copy variables in DATA section in FLASH to RAM
r0::init_data(&mut _sdata, &mut _edata, &_sidata);
}
}

最后是链接描述文件:

ENTRY(_start)

SECTIONS {
. = 0x80000;

.text : {
KEEP(*(.reset_vector));
__reset_vector = ABSOLUTE(.);
*(.text .text.* .gnu.linkonce.t*)
}

.rodata : {
*(.rodata .rodata.* .gnu.linkonce.r*)
}

.data : {
_sdata = .;
*(.data .data.* .gnu.linkonce.d*)
_edata = ALIGN(8);
}

.bss (NOLOAD) : {
. = ALIGN(32);
_bss = .;
*(.bss .bss.*)
*(COMMON)
_ebss = ALIGN(8);
}

__bss_length = (__bss_end - __bss_start);

/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
}

下面是反汇编:

(gdb) disassemble 0x0000000000080000, 0x000000000008035c
Dump of assembler code from 0x80000 to 0x8035c:
=> 0x0000000000080000 <core::mem::uninitialized+0>: sub sp, sp, #0x10
0x0000000000080004 <core::mem::uninitialized+4>: ldr x0, [sp, #8]
0x0000000000080008 <core::mem::uninitialized+8>: str x0, [sp]
0x000000000008000c <core::mem::uninitialized+12>: ldr x0, [sp]
0x0000000000080010 <core::mem::uninitialized+16>: add sp, sp, #0x10
0x0000000000080014 <core::mem::uninitialized+20>: ret

来自函数 _start 的指令需要放置在@0x80000 处,但情况并非如此,因为有那些 core::mem::uninitialized

如何修改链接描述文件,使 mrs x1, mpidr_el1 成为第一个被执行的指令?

最佳答案

经过漫长的夜战,我想出了办法。

首先在链接器中创建一个新部分:

ENTRY(reset)
SECTIONS {

. = 0x80000;
.reset : {
KEEP(*(.reset))
. = ALIGN(8);
}

.text : {
*(.text .text.* .gnu.linkonce.t*)
}
...

并修改代码:

#[link_section=".reset"]
#[no_mangle]
#[naked]
pub extern "C" fn reset () {
unsafe {
// Halt all cores but the primary and set stack pointer
asm!(" mrs x1, mpidr_el1
and x1, x1, #3
cmp x1, #0
bne halt
mov sp, #0x80000
b init
"::::"volatile");
}
}

其余的:

#[naked]
#[no_mangle]
pub fn init() {
extern "C" {
static mut _sbss: u64;
static mut _ebss: u64;

static mut _sdata: u64;
static mut _edata: u64;

static _sidata: u64;
}

unsafe{
// Zero the BSS section in RAM
r0::zero_bss(&mut _sbss, &mut _ebss);
// Copy variables in DATA section in FLASH to RAM
r0::init_data(&mut _sdata, &mut _edata, &_sidata);
}

extern "Rust" {
fn main() -> !;
}

unsafe { main(); }
}

通过拆分代码,重置中的初始化保持在 0x80000

Disassembly of section .reset:

0000000000080000 <reset>:
80000: d53800a1 mrs x1, mpidr_el1
80004: 92400421 and x1, x1, #0x3
80008: f100003f cmp x1, #0x0
8000c: 54001481 b.ne 8029c <halt> // b.any
80010: b26d03ff mov sp, #0x80000 // #524288
80014: 1400008d b 80248 <init>
80018: d65f03c0 ret
8001c: 00000000 .inst 0x00000000 ; undefined

关于linker - 通过使用内联汇编的 Raspberry Pi3 的 Rust 启动代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52470249/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com