4

following is the snippet of linker script.

.data :
{
    *(.data*)
}
> ram
. = ALIGN(4);

/* Set Stack after code & data */
_stack_start = .;

How can I access the _stack_start (start address for stack) in my rust (without std library) ?

#![no_std]
#![no_main]
#![allow(dead_code)]

#[no_mangle]
pub fn _start() {
    // let sp: i32 = _stack_start; -> **This causes compilation error**

    type FnPtr = fn() -> ();
    let th: FnPtr = trap_handler;

    unsafe {
        asm!("csrw mtvec, {}" ,
            in(reg) th);
    }

    loop {}
}
Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
NastyBen
  • 43
  • 5

1 Answers1

4

Hey i do not really have a way of running your code but this source seems to do what you are trying to achieve. I suggest you read the whole thing but i will put the important parts in the answer.

They create symbols in the linker script:

.data : AT(ADDR(.rodata) + SIZEOF(.rodata))
{
  _sdata = .;
  *(.data .data.*);
  _edata = .;
} > RAM

and later declare them as extern "C" in rust:

extern "C" {
    static mut _sdata: u8;
    static mut _edata: u8;
}

Afterwards they use the address of those symbols this way:

let count = &_edata as *const u8 as usize - &_sdata as *const u8 as usize;

As for why the rust code uses addresses of those variables instead of their values i direct you to this SO answer.

I am not sure why the variables are declared as u8, but they are accessed by their address which is cast to usize anyways, so i suspect their type might be unimportant for the compiler.

msaw328
  • 1,459
  • 10
  • 18