I'm using an ARM Cortex-A72 processor running a custom real-time operating system. I'm trying to understand how address translation is performed, but there are some points I couldn't grasp fully.
I believe it might be easier to proceed with a concrete example. Therefore, I'm sharing some memory addresses for which I know both the virtual and physical addresses:
- Virtual_1 = 0xc7c01000, Physical_1 = 0x09170000
- Virtual_2 = 0xc7c11000, Physical_2 = 0x0916E000
- Virtual_3 = 0x01060000, Physical_3 = 0x101F1000
Now, I'm also sharing some register values with you:
TTBR0_EL1 0x3000095c92000 844427443118080
TTBR1_EL1 0x0 0
TTBR0_EL2 0x0 0
TCR_EL1 0x80003500 2147497216
TCR_EL2 0x0 0
VTCR_EL2 0x0 0
SCTLR 0x10c51905 281352453
SCTLR_EL2 0x0 0
MAIR_EL1 0xffbb00 16759552
ID_AA64MMFR0_EL1 0x1124 4388
Following the instructions in the ARM official documentation and using the data above, I attempted to calculate the translation process from virtual addresses to physical addresses but was unsuccessful. When I input the values for level 1 translation as specified by ARM, I get the following result:
As you can see in the image, the first 19 bits of the virtual address do not match the first 19 bits of the physical address, and also I cannot access the first level descriptor address. I suspect that Level-1 address translation is not used due to this mismatch.
Assuming that Level-2 address translation is employed, I attempted to perform the Level-2 translation process, but again, I was unsuccessful. Below is the information regarding Level-2 translation:
In the Level-2 translation, I cannot access the Level 1 Descriptor Address. Therefore, I'm unable to reach the Level 2 Descriptor Address, Level 2 Table Base Address, and Small Page Base Address values.
(gdb) x/4x 0x95c931f0
0x95c931f0: Cannot access memory at address 0x95c931f0
As a result, I am looking for answers to the following questions:
- Is "Level 1 Address Translation" or "Level 2 Address Translation" being used? How can I determine this from register values?
- Where are the Level 1 and Level 2 Table addresses located?
- How is the address translation process carried out?
- At the end of the day, how can I get the physical address from the virtual address(or vice versa)?
Some additional information;
- Bootloader and application executables run on QEMU. Therefore, I cannot use hardware debugger.
- I'm using GDB for debugging.
EDIT-1:
I dumped all the RAM starting from the physical RAM starting address and started examining it. I had a few inferences about this issue that I wanted to share with you.
- Virtual_1, Virtual_2, Virtual_3 addresses are located at two different offset addresses in RAM.
- Physical_1 address is located at three different offset addresses in RAM, Physical_2 address is located at two different offset addresses in RAM, Physical_3 address is not located in RAM.
- The physical address equivalents of Virtual_1 and Virtual_2 addresses are sequential in offset values starting with 0x4aXXX.
00 01 02 03 04 05 06 07
Ex: 0x95c40000 + 0x4A0A4 -> 00 10 c0 c7 00 00 17 09
0xc7c01000 0x09170000
- Virtual_1, Virtual_2, Virtual_3 addresses are sequential in RAM with offset values starting with 0x56fXX.
Bytes -> 00 01 02 03 04 05 06 07
Ex: 0x95c40000 + 0x56f08 -> 00 10 c1 c7 00 10 c0 c7
Hex -> 0xc7c11000 0xc7c01000
08 09 0a 0b 0c 0d 0e 0f
00 00 00 00 00 00 00 00
0x00000000 0x00000000
00 01 02 03 04 05 06 07
01 00 06 01 00 00 06 01
0x01060001 0x1060000
In the last case, the RAM location of the virtual, physical, virtual address and the RAM location of the physical address are as follows;
Virtual_1 = 0xc7c01000
Physical_1 = 0x9170000
MemVirt = 0x95C40000 + 0x4a0a4 / 0x56f0c
MemPhy = 0x95C40000 + 0x4a0a8 / 0x4a0b8 / 0x4cba8
Virtual_2 = 0xc7c11000
Physical_2 = 0x916E000
MemVirt_2 = 0x95C40000 + 0x4a174 / 0x56f08
MemPhy_2 = 0x95C40000 + 0x4a178 / 0x4a188
Virtual_3 = 0x1060000
Physical_3 = 0x101F1000
MemVirt_3 = 0x95C40000 + 0x4a00c / 0x56f18
MemPhy_3 = ?
Thanks in advance!

