mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 10:15:57 +01:00
arm: start documenting paging
This commit is contained in:
20
README.adoc
20
README.adoc
@@ -15096,6 +15096,26 @@ Bibliography:
|
||||
* https://stackoverflow.com/questions/51094092/how-to-make-timer-irq-work-on-qemu-machine-virt-cpu-cortex-a57
|
||||
* https://stackoverflow.com/questions/44198483/arm-timers-and-interrupts
|
||||
|
||||
==== ARM paging
|
||||
|
||||
TODO create a minimal working aarch64 example analogous to the x86 one at: https://github.com/cirosantilli/x86-bare-metal-examples/blob/6dc9a73830fc05358d8d66128f740ef9906f7677/paging.S
|
||||
|
||||
A general introduction to paging with x86 examples can be found at: https://cirosantilli.com/x86-paging[].
|
||||
|
||||
ARM paging is documented at <<armarm8-db>> Chapter D5 and is mostly called VMSAv8 in the ARMv8 manual (Virtual Memory System Architecture).
|
||||
|
||||
Paging is enabled by the `SCTLR_EL1.M` bit.
|
||||
|
||||
The base table address is selected by the register documented at <<armarm8-db>> D12.2.111 "TTBR0_EL1, Translation Table Base Register 0 (EL1)".
|
||||
|
||||
There is also a `TTBR1_EL1` register, which is for the second translation stage to speed up virtualization: https://en.wikipedia.org/wiki/Second_Level_Address_Translation and will not be used in this section.
|
||||
|
||||
The translation types are described at: <<armarm8-db>> D5.2.4 "Memory translation granule size".
|
||||
|
||||
From this we can see that the translation scheme uses up to 4 levels (0 to 3) and has possible granule sizes 4KiB, 16KiB and 64KiB.
|
||||
|
||||
Page table formats are described at <<armarm8-db>> D5.3.1 "VMSAv8-64 translation table level 0, level 1, and level 2 descriptor formats".
|
||||
|
||||
==== ARM baremetal bibliography
|
||||
|
||||
First, also consider the userland bibliography: <<arm-assembly-bibliography>>.
|
||||
|
||||
@@ -8,11 +8,25 @@ int main(void) {
|
||||
__asm__ ("mrs %0, sctlr_el1" : "=r" (sctlr_el1) : :);
|
||||
printf("SCTLR_EL1 0x%" PRIX32 "\n", sctlr_el1);
|
||||
printf("SCTLR_EL1.A 0x%" PRIX32 "\n", (sctlr_el1 >> 1) & 1);
|
||||
/* https://cirosantilli.com/linux-kernel-module-cheat#arm-paging */
|
||||
printf("SCTLR_EL1.M 0x%" PRIX32 "\n", (sctlr_el1 >> 0) & 1);
|
||||
|
||||
uint64_t CurrentEL;
|
||||
__asm__ ("mrs %0, CurrentEL;" : "=r" (CurrentEL) : :);
|
||||
printf("CurrentEL 0x%" PRIX64 "\n", CurrentEL);
|
||||
/* https://cirosantilli.com/linux-kernel-module-cheat#arm-exception-levels */
|
||||
printf("CurrentEL.EL 0x%" PRIX64 "\n", CurrentEL >> 2);
|
||||
|
||||
/* https://cirosantilli.com/linux-kernel-module-cheat#arm-paging */
|
||||
{
|
||||
uint64_t tcr_el1;
|
||||
__asm__ ("mrs %0, tcr_el1;" : "=r" (tcr_el1) : :);
|
||||
printf("TCR_EL1 0x%" PRIX64 "\n", tcr_el1);
|
||||
|
||||
uint64_t ttbr0_el1;
|
||||
__asm__ ("mrs %0, ttbr0_el1;" : "=r" (ttbr0_el1) : :);
|
||||
printf("TTBR0_EL1 0x%" PRIX64 "\n", ttbr0_el1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user