Description
There's a usage sceneario in Rust for embedded rom bootloader. Some chips use eGON.BT0 format on boot, it has one jump instruction on head and the following should be boot tables.
Bit index | Content |
---|---|
0..4 | an instruction j main |
5..12 | bootloader magic |
12.. | following boot configurations |
It's ideal to write this instruction j main
using Rust naked function as follows, in this way we do not require further tools to help with filling this instruction.
#[naked]
#[link_section = ".head.text"]
#[export_name = "head_jump"]
pub unsafe extern "C" fn head_jump() {
asm!("j {}", sym main, options(noreturn))
}
The options(noreturn)
is required in current naked function or it won't compile. I expect this function to generate one instruction j main
only, however it generates an unimp
which is unexpected:
Disassembly of section .head.text:
0000000000000000 <head_jump>:
0: 6f 00 60 02 j 0x26 <_ZN18test_d1_flash_bare4main17h5fd8eeda800e7085E>
4: 00 00 unimp
Disassembly of section .text:
...
I didn't expect this unimp
instruction, for it will overlap bootloader magic, making this Rust image not bootable. What should I do?
I looked into RFC 2972, in section Naked Function Definition it shows:
- emit no additional instructions to the function body before the asm!() statement.
Should we expect that there would be additional instructions after what we have in asm!
macro?
Note: I try to remove the option(noreturn)
, it shows following compile error:
Compiling test-d1-flash-bare v0.1.0 (D:\RustSBI\test-d1-flash-bare)
error[E0787]: asm in naked functions must use `noreturn` option
--> src\main.rs:17:5
|
17 | asm!("j {}", sym start)
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider specifying that the asm block is responsible for returning from the function
|
17 | asm!("j {}", sym start, options(noreturn))
| +++++++++++++++++++
For more information about this error, try `rustc --explain E0787`.
error: could not compile `test-d1-flash-bare` due to previous error