Thanks for your answer simeonz!
simeonz wrote:
CRoemheld wrote:While the first mapping is from the standard of virtual memory layout, the second mapping is needed to make the OSDev tutorial work.
How do I deal with this issue? It should be noted that I want to make the virtual memory layout adhere to the one listed in the file. I thought about using either one of these approaches:
While the second mapping (the mapping of the kernel elf) is my current approach and it works perfectly fine, I am trying to find reasons to change it to the layout in the link. By changing to the other approach (kernel text mapping, 512MiB), I would need to rewrite my code so that the kernel entry point is still reachable.
Could you clarify? Why would using the Linux approach render the kernel entry point unreachable? Also, using your approach wouldn't render any functionality that Linux provides unfeasible in my opinion. All that Linux manages to do with this scheme (to my knowledge) is to fit inside the last 2GB and to translate virtual to physical addresses in that range using only address arithmetic.
Sorry, I'm a bit confused myself. As I said, I wanted to try to adhere to the linux mapping regarding the kernel. Since linux maps the kernel on 0xffffffff80000000, from physical address 0 going upwards, the addresses for the kernel symbols (entry point and all its functions) should be easily accessible by adding the physical addresses of the symbol to the kernel virtual start address (0xffffffff80000000):
0xffffffff80000000 + <symbol physical address>
Is the kernel mapping start address (0xffffffff80000000) just a kind of limit at which to map the kernel at any point upwards (between 0xffffffff80000000 - 0xffffffff9fffffff), or should the kernel definitely mapped at 0xffffffff80000000 and exactly mapping 512MiB of physical memory?
Since linux maps it at 0xffffffff80000000, starting from physical address 0x0, my kernel would be accessible at 0xffffffff80390000, since 0x390000 is the physical address of my kernel.
Then I tried to change the kernel VMA to 0xffffffff80000000. If I do that, the kernel entry point is located at 0xffffffff80000a70, but the mapping results in the address 0xffffffff80390a70, meaning the kernel won't start because it's the wrong address.
Before you tell me to add the offset of the kernel to the address, it won't work either since the entry point may now be reachable, but all other addresses are still at a different address:
I jump by using the %rax register: jump to 0xffffffff80390a70.
When a function inside the kernel is called, the addresses simply drop the 0x390000, resulting in addresses like 0xffffffff80002631. But as I said before, when mapping the kernel on 0xffffffff80000000 from physical memory 0x0 upwards, the functions always reside at 0xffffffff80390000, so the next call inside the kernel fails. So I'm trying to figure out how to change the kernel VMA in the linker script so that even the functions inside the kernel are reachable.
When I keep the VMA of currently 0xffffffff80200000, the entry point is now at 0xffffffff80200a70. BUT: In my current state, I am only mapping the kernel from physical address 0x390000 upwards, which means addresses like 0xffffffff80202631 from before is now reachable, since 0x2631 is the offset of the symbol from the kernel VMA. If I do that, it works fine, but it is not the kernel virtual address used in linux.
As you pointed out, you don't think it is a problem if i keep my current implementation regarding the kernel VMA and mapping it to 0xffffffff80200000 rather than 0xffffffff80000000 (because it is still in the range 0xffffffff80000000 - 0xffffffff9fffffff?).
In this case, I won't need the 512MiB kernel text mapping used in the linux kernel.
Again: TL;DR:
Is using virtual addresses like 0xffffffff80200000 rather than 0xffffffff80000000 for the kernel still considered to be similar/equal to the linux mapping?
Do I need to map 512MiB?
Should I definitely map the kernel twice, first by mapping to 0xfffffff80000000 from physical address 0x0 upwards and then directly to 0xffffffff80200000, but from the actual kernel physical address (0x390000) upwards?
If not, which virtual address should I use and why? Maybe a suggestion based on your own projects/experiences?