Open dkhayes117 opened 4 years ago
Definitely! You can copy the linker script from the corresponding riscv-rt
source tree into your project under a different name and use it in .cargo/config
instead of one provided by riscv-rt
.
So this line "-C", "link-arg=-Thifive1-link.x" would change to "-C", "link-arg=-newlink.x" if newlink.x was in my project tree ?
Change it to:
"-C", "link-arg=-Thifive1-memory.x",
"-C", "link-arg=-Tnewlink.x"
(you also need to include memory definitions before the linker script)
Will I need to modify the memory-hifive1-revb.x too, or just the linker?
Only if you need a different memory layout or you do not have a bootloader.
Are the region alias' sensitive to renaming? For example, keeping U and M level code separate wouldn't I need to have a .textM and a .textU etc?
Maybe I can build and run my M level code with one linker and memory file (original). Then once completed, build and run the U level code with a modified linker and memory file that has different memory addresses. Or should this be a single process with some kind of compile time flags/switches?
Region aliases are different things, they were added to prevent hardcoding FLASH
everywhere and to allow some flexibility. If you have different .textX
section names, you can try to group them in the linker script in a way you want.
I've never done this before, obviously. How completely nuts does this look?
INCLUDE memory-fe310.x
MEMORY
{
MFLASH ORIGIN = 0x20000000, LENGTH = 2M
UFLASH ORIGIN = 0x20200000, LENGTH = 2M
MRAM ORIGIN = 0x80000000, LENGTH = 8K
URAM ORIGIN = 0x80002000, LENGTH = 8K
}
REGION_ALIAS("REGION_MTEXT", MFLASH); REGION_ALIAS("REGION_MRODATA", MFLASH); REGION_ALIAS("REGION_MDATA", MRAM); REGION_ALIAS("REGION_MBSS", MRAM); REGION_ALIAS("REGION_MHEAP", MRAM); REGION_ALIAS("REGION_MSTACK", MRAM);
REGION_ALIAS("REGION_UTEXT", UFLASH); REGION_ALIAS("REGION_URODATA", UFLASH); REGION_ALIAS("REGION_UDATA", URAM); REGION_ALIAS("REGION_UBSS", URAM); REGION_ALIAS("REGION_UHEAP", URAM); REGION_ALIAS("REGION_USTACK", URAM);
/Skip first 64k allocated for bootloader/ _stext = 0x20010000;
You don't need the first INCLUDE as you defined your own RAM regions, but other things look sane
Wow, really? LOL, cool. Obviously, I can tweak the region sizes a bit to not waste space, just divided everything in half to start. I will get rid of the include line.
Next, I need to modify the link.x file to handle these regions, correct?
Correct. Or you can create two different memory.x files, one for M-mode and one for U-mode and use them to link two different binaries with the same (possibly modified) link.x file.
Right, that makes sense. If I did that, then I wouldn't need the change the region names just the memory boundaries. I would also have to $cargo run twice this way. Once to load m-mode stuff, and once to load the u-mode stuff?
Yes, you're right.
I really appreciate your help!
One more thought. I plan on entering the user mode memory section by setting the stack pointer address and changing to u mode. When I write my user mode code, I don't need an #[entry] attribute point included, just in the machine mode code. That should allow the machine code to be called on start up, then I will use the mret process to move into the user mode portion from m-mode. Should that work?
Probably you need to write your own startup code for the user mode and place it somewhere (beginning of the user mode .text
as an option). In any case, you need to have something, that will be KEEP
ed while linking, otherwise you likely end up with an empty user mode binary.
I see what you are saying. Do you have any suggestions for the memory definition file. When I try to build with the extra -C argument, it says that "RAM" is already defined. The ram is being defined somewhere else during linking. I think it might be in the hifive/build.rs file. It seems to be pointing to the default memory file. Not sure how to modify this without changing the repo file.
Nope, the problem is the quickstart template is adding the -Thifive1-link.x argument which calls the hifive-memory.x file then link.x linker. I think I can just do this
"-C", "link-arg=-Tnew-memory.x", "-C", "link-arg=-Tlink.x"
This seems to be working, but the ram doesn't start at the origin I define, it always puts it at 0x80000000.
Strange, try to rebuild the project. Sometimes these script files don't get updated and linker uses the old version.
Yahoo! That worked. I ran cargo clean
then cargo build --workspace
Is it possible to modify the linker script on my project? I want to keep all machine mode and user mode functions separated in memory. I thought that I might can build the machine code and the user code separately, then change the linker script somehow to load them into separate memory locations. Then I can use the PMP to sandbox my user mode operation.