ASM! macro symbol address

I’m using asm! macro in my code to init Raspberry Pi 3. So I have _start function:

#[no_mangle]
pub extern “C” fn _start() -> !{

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
         "::::"volatile");
}

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

unsafe { main(); }
loop{}

}

I need to place this code at address 0x80000. This works without the call to main function but I need of course to do something else beside the asm init:

0000000000080000 <main>:
   80000:       14000000        b       80000 <main>
   80004:       d53800a1        mrs     x1, mpidr_el1
   80008:       92400421        and     x1, x1, #0x3
   8000c:       f100003f        cmp     x1, #0x0
   80010:       54000061        b.ne    8001c <halt>  // b.any
   80014:       b26d03ff        mov     sp, #0x80000                    // #524288
   80018:       97fffffa        bl      80000 <main>

000000000008001c <halt>:
   8001c:       d503205f        wfe
   80020:       17ffffff        b       8001c <halt>

Is there some way to specify that the output of the asm! macro must be placed at 0x80000? To me it seems the code is optimized and relocated.

This crate is no_std and no_main.

You need to use a linker script to do that. Use the link_section attribute to place _start in it’s own section, then use the linker script to place that section at the desired address.

Also you will need the naked attribute to make sure there is no compiler generated code between the start of the function and the start of your asm.

Thanks @parched. Using #[link_section] and #[naked] attributes helped.

#[no_mangle]
#[naked]
#[link_section=".start"]
pub extern “C” fn _start() {}

A the section in linker script:

  . = 0x80000;
  .start : {
      KEEP(*(.start))
      . = ALIGN(8);
	}
	
  .text  : {
      *(.text .text.* .gnu.linkonce.t*)
  }
1 Like