Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

riscv-rt: Linker relocation issue (QEMU / OpenSBI) #153

Open
chutchinson opened this issue Dec 16, 2022 · 6 comments
Open

riscv-rt: Linker relocation issue (QEMU / OpenSBI) #153

chutchinson opened this issue Dec 16, 2022 · 6 comments

Comments

@chutchinson
Copy link

chutchinson commented Dec 16, 2022

I am experimenting with the RISC-V ISA via QEMU emulation, and I am having trouble figuring out how to link in the _heap_size symbol appropriately, so that I can follow through with heap allocation. I followed the riscv-rt documentation closely. I am attempting to use QEMU with OpenSBI, but I am not experienced with linker configuration. Here is my memory layout specification:

MEMORY
{
    RAM : ORIGIN = 0x80200000, LENGTH = 0x8000000
    FLASH : ORIGIN = 0x20000000, LENGTH = 16M
}

REGION_ALIAS("REGION_TEXT", RAM);
REGION_ALIAS("REGION_RODATA", RAM);
REGION_ALIAS("REGION_DATA", RAM);
REGION_ALIAS("REGION_BSS", RAM);
REGION_ALIAS("REGION_HEAP", RAM);
REGION_ALIAS("REGION_STACK", RAM);

I understand that to mean that there is 16M of reserved flash memory at the beginning of the address space (OpenSBI), followed by RAM address space. I would expect all of the memory regions to fit within RAM since the FLASH space is reserved by QEMU OpenSBI firmware.

I have the following example program:

#![no_std]
#![no_main]

extern crate panic_halt;

mod uart;
mod print;

use riscv_rt::entry;

use uart::Uart;

extern "C" {
    static _heap_size: u8;
}

#[entry]
fn __start() -> ! {
    let heap_size = unsafe { &_heap_size as *const u8 as usize };
    println!("hello world");
    println!("heap size = {}", heap_size);
    loop {}
}

The problem is that the linker cannot relocate _heap_size provided by riscv-rt and I do not understand why. I tried changing the code model to medium:

relocation R_RISCV_PCREL_HI20 out of range: -524800 is not in [-524288, 524287]; references _heap_size
@hegza
Copy link

hegza commented Jan 27, 2023

Having worked with this crate & OpenSBI a little bit myself, I can't say for 100 % certain, but I think that the relatively large memory size reserved for RAM here (0x8000000 == 128 Mebibytes) causes the program to become "too large" for the link strategy used by this crate as defined in link.x. riscv-rt tries to optimally use all the space given to it, by filling out the necessary stuff at the beginning of the given memory area, and then reserving the rest for stack / heap. However, the rest can be too much for e.g., RISC-V jump instructions to handle.

One way to properly solve this would be to try to use a link script from OpenSBI/QEMU side and try to adapt your runtime into it.

A more hacky solution which would work for either verification of the issue or initial testing, could be to reduce the size you reserve for RAM and see if the program would be able to link in that case.

I would maybe think of riscv-rt:s default link strategy be a really good fit for small microcontrollers, but not necessarily the best solution for heavy lifters such as desktop operating systems and their bootloaders.

@georglauterbach
Copy link

georglauterbach commented Oct 27, 2023

I have the same issue, but reducing the size of RAM does not solve the issue. @hegza Any other ideas? I have a custom linker.x file that mimmicks this crate's link.x. In my case, no FLASH is involved. I am not sure what "link strategy" refers to; can you elaborate?

@georglauterbach
Copy link

When using this crate via git = "...", branch = "master" in Cargo.toml and then

MEMORY
{
  FLASH (rx) : ORIGIN = 0x20000000, LENGTH = 16M
  RAM (rwxa) : ORIGIN = 0x80200000, LENGTH = 16M
}

in the linker script addition, it seems to be working..

@romancardenas romancardenas transferred this issue from rust-embedded/riscv-rt Nov 28, 2023
@romancardenas romancardenas changed the title Linker relocation issue (QEMU / OpenSBI) riscv-rt: Linker relocation issue (QEMU / OpenSBI) Nov 28, 2023
@vilukissa68
Copy link

We ran into this or a similar issue with @hegza and were able to solve it by setting riscv64-unknown-elf-ld as linker in config.toml

linker = "riscv64-unknown-elf-ld"

@alistair23
Copy link

Why use OpenSBI though? Are you trying to write S-mode software?

@hegza
Copy link

hegza commented Jun 19, 2024

In our case it wasn't OpenSBI but an application thay needed access to a memory located in the high bits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants