Since our kernel will be using multiple cores, enabling the MMU as early as possible is very important, as we will need to be able to use atomic instructions to have proper exclusion between cores. This is why it is the first thing that core 0 does after the inital hardware setup.
When setting up the MMU, there are five important system registers we need to configure. These registers control how virtual memory is translated, how different types of memory behave, and whether the MMU and caches are enabled:
TTBR0_EL1
– Base address for translation tables used by the lower virtual address spaceTTBR1_EL1
– Base address for translation tables used by the upper virtual address spaceMAIR_EL1
– Defines memory types and their cacheability behaviorTCR_EL1
– Configures address space size, granule size, and memory attributesSCTLR_EL1
– Enables the MMU, data/instruction caches, and other control flagsWe don’t need to fully understand each of these registers just yet, I just wanted to introduce them. Their purpose will become clearer once we start enabling the MMU. Before we can use them, we first need to define the structure and layout of our memory translation tables, which is what we will do next.