Modifying Linker Script



First of all many thanks for the greatly informative blog posts! It helps a lot for my understanding of RICS-V. I was playing around to understand the linker script for RISC-V. However, I could not find any information about follow entries from

.lalign :
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >flash AT>flash :flash

.dalign :
. = ALIGN(4);
PROVIDE( _data = . );
} >ram AT>flash :ram_init

When I mess around above entries such as putting a new entry around causes flash verification failed due to hash miss matching.

Could you let me know what those entries mean?

Warm Regards,
Jaesu Yu

(Jim Wilson) #2

I don’t have a hifive1, but the basic idea here is that code+data gets loaded into flash, and then when you start running the program we have to copy data from flash to ram to make it writable. If you look at freedom-e-sdk/bsp/env/start.S you will find code that does the copy, with a loop that starts loading from _data_lma and starts storing at _data, and loops until it reaches _edata. If you change anything here, then you will break the data segment support.


Dear Jim,

Many thanks for the information. Yes, that I have figured while I was going through the SDK, thanks for the confirmation!

One more concern is that if we do want to use ram function, placing a function beyond 0x8000 0000, can it be done with GNU tool chain? I can see options for -mcmodel=medlow
at indicate the code model. However, it says the ‘with in 2GB address space’. Does it mean that we can not place a function after 0x8000 0000 with HiFive1 SDK?

Jaesu Yu

(Jim Wilson) #4

The medlow code model gives you +/-2GB range from the pc. If the first byte of code references the last byte of data, and vice versa, then to make that work, we must restrict programs to 2GB total. However, on a 32-bit part like hifive1, the address space wraps around at +/-2GB, so you do actually have access to the entire 4GB address space with the medlow code model. The problem occurs on 64-bit parts where you don’t have access to the entire address space, and won’t be able to access addresses above 0x8000 0000 unless you use the medany code model, which has the same effective 2GB range but that 2GB range can be anywhere in memory.