-
-
Notifications
You must be signed in to change notification settings - Fork 846
MMU: If we're identity mapping the kernel image, why not loading the kernel at a high half physical address already? #83
-
In the MMU tutorial it is mentioned that identity mapping the kernel image is to avoid complexity, which makes sense. However, since several tutorials we are assuming that the kernel is loaded at 0x8_0000 always. What keeps us from changing that and loading the kernel at a high-half physical address?
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 6 comments 1 reply
-
Define "higher-half"...
We could use the chainloader and copy the kernel to some other address that is still backed by DRAM and identity-map that region. Mustn't be 0x8_0000
.
What's more tricky is if you want your kernel linked for an address that only exists virtually, like really high, e.g. greater than 0xFFFF_0000_0000_0000
as already teased by Tutorial 15.
Then you have to take care of two phases: Before and after MMU init.
Every code that runs after MMU init is ideally statically linked to this high address for performance reasons. However, since the addresses will only exist virtually, the code that runs before MMU init cannot be linked/depend on to the target virtual address.
A common trick is to compile the parts before MMU init as position independent code (PIC). In Rust, its actually not that trivial to only compile some parts of a binary as PIC and others not.
Anyhow, Tutorial 16 will be all about that (remapping the kernel to higher half). I hope I find some time over the winter holidays to get it done.
Beta Was this translation helpful? Give feedback.
All reactions
-
Why don't have all the kernel PIC? Is it really bad for performance?
Beta Was this translation helpful? Give feedback.
All reactions
-
I was thinking about these two options before we get to tutorial 16 (looking forward to it btw...):
-
'kernel_address' in config.txt to eliminate the 0x8_0000 constraint by pi itself. The new address would have to be a physical one though.
-
or as we are already using a boot loader, the loader has to be at 0x8_0000 but not the kernel, so we can have the chain loader pre-init the MMU then load the kernel?
Beta Was this translation helpful? Give feedback.
All reactions
-
After more digging, and excluding the option of a boot loader, I'm. thinking about 2 implementation options:
-
Place the initialization code up to MMU enabling at 0x8_0000. and placing the rest of the code in a different par in .text at the kernel higher half address. Still need to figure out how to do that without reverting to assembly.
-
As you suggested, find a way to compile the init files up to MMU enabling with PIC and the rest with no PIC and linking the whole at the kernel high half address.
Beta Was this translation helpful? Give feedback.
All reactions
-
AFAICS, compiling PIC is currently only possible in crate granularity. Not per object files. At least in a comfortable way.
So I'll probably end up with two binaries concatenated together (cat bin1.img bin2.img
basically), the first one being PIC and starting at 0x8_.... as always and setting up the second kernel's tables for its binary, and then just jumping to the second binary's virtual entry point.
Maybe there is a more elegant way, but this is all subject to experiments I'll still need to do.
Beta Was this translation helpful? Give feedback.
All reactions
-
How do you plan on making the translation table global static accessible to both?
I saw the linux kernel completely rewriting the relocation tables after boot...
In. the meantime, I'll do some experimentation with placing code. with the linker using https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute and see if I can jump to the kernel code after the MMU is setup.
Beta Was this translation helpful? Give feedback.
All reactions
-
I will explore a few ideas, not sure yet. Maybe I build the second binary first, get the offset of the page tables struct in that binary and patch their location offset into the first binary somehow (e.g. through an additional linker symbol). Or something I haven't thought of yet :D
Beta Was this translation helpful? Give feedback.