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

Modify the Linker Script #19

Open
dkhayes117 opened this issue Sep 23, 2020 · 21 comments
Open

Modify the Linker Script #19

dkhayes117 opened this issue Sep 23, 2020 · 21 comments

Comments

@dkhayes117
Copy link

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.

@Disasm
Copy link
Member

Disasm commented Sep 23, 2020

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.

@dkhayes117
Copy link
Author

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 ?

@Disasm
Copy link
Member

Disasm commented Sep 23, 2020

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)

@dkhayes117
Copy link
Author

Will I need to modify the memory-hifive1-revb.x too, or just the linker?

@Disasm
Copy link
Member

Disasm commented Sep 23, 2020

Only if you need a different memory layout or you do not have a bootloader.

@dkhayes117
Copy link
Author

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?

@Disasm
Copy link
Member

Disasm commented Sep 23, 2020

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.

@dkhayes117
Copy link
Author

dkhayes117 commented Sep 23, 2020

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;

@Disasm
Copy link
Member

Disasm commented Sep 23, 2020

You don't need the first INCLUDE as you defined your own RAM regions, but other things look sane

@dkhayes117
Copy link
Author

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?

@Disasm
Copy link
Member

Disasm commented Sep 23, 2020

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.

@dkhayes117
Copy link
Author

dkhayes117 commented Sep 23, 2020

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?

@Disasm
Copy link
Member

Disasm commented Sep 23, 2020

Yes, you're right.

@dkhayes117
Copy link
Author

I really appreciate your help!

@dkhayes117
Copy link
Author

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?

@Disasm
Copy link
Member

Disasm commented Sep 23, 2020

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 KEEPed while linking, otherwise you likely end up with an empty user mode binary.

@dkhayes117
Copy link
Author

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.

@dkhayes117
Copy link
Author

dkhayes117 commented Sep 24, 2020

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"

@dkhayes117
Copy link
Author

This seems to be working, but the ram doesn't start at the origin I define, it always puts it at 0x80000000.

@Disasm
Copy link
Member

Disasm commented Sep 25, 2020

Strange, try to rebuild the project. Sometimes these script files don't get updated and linker uses the old version.

@dkhayes117
Copy link
Author

dkhayes117 commented Sep 25, 2020

Yahoo! That worked. I ran cargo clean then cargo build --workspace

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

2 participants