1 ARMv8 Memory Management
1.1 Memory layout in Aarch64 Linux
The ARMv8 architecture can support 48-bit virtual addresses and is configured as a 4-level page table (4K pages) or a 3-level page table (64K pages). However, this Linux system only uses 39-bit virtual addresses (512G kernel, 512G user), and is configured as a 3-level page table (4K pages) or a 2-level page table (64K pages).
The address bits 63:39 of user space are set to zero, and the address bits 63:39 of kernel space are set to one. The 63rd bit of the virtual address can be used to select TTBRx. swapper_pg_dir only contains kernel global mappings, and the user's pgd contains user (non-global) mappings. The swapper_pg_dir address is in TTBR1 and is not written to TTBR0.
AArch64Linux memory layout:
Start End Size Use
--------------------------------------------------------------------------------------------------
000000000000000 0000007fffffffff 512GB user
ffffff80000000000 ffffffbbfffcffff ~240GB vmalloc
ffffffbbfffd0000 ffffffbcfffdffff 64KB [guardpage]
ffffffbbfffe0000 ffffffbcfffeffff 64KB PCII/O space
ffffffbbffff0000 ffffffbcffffffff 64KB [guard page]
ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
ffffffbe00000000 ffffffbffbffffff ~8GB [guard,future vmmemap]
ffffffbffc000000 ffffffbfffffffff 64MB modules
ffffffc000000000 ffffffffffffffff 256GB memory
1.2 AArch64 virtual address format
1.2.1 Virtual Address for 4K Pages
1.2.2 Virtual Addresses for 64K Pages
2 Analysis of the head.S page table creation process
2.1 Page table creation function __create_page_tables
This function is used to create the page tables required for the FDT (device tree) and kernel image when the kernel is started. After the kernel is running normally, create_mapping needs to be run to create page tables for all physical memory, which will overwrite the page tables created by __create_page_tables.
The page table source file is created when the kernel starts running: arm64/kernel/head.Sline345
/*
* Setup the initial page tables. We only setup the barest amount which is
* required to get the kernel running. The following sections are required:
* -identity mapping to enable the MMU (low address, TTBR0)
* -first few MB of the kernel linear mapping to jump to once the MMU has
* been enabled, including the FDT blob (TTBR1)
*/
__create_page_tables:
pgtbl x25, x26, x24 //idmap_pg_dir and swapper_pg_dir addresses
/*
* Clear the two newly created page tables TTBR0, TTBR1
*/
mov x0,x25
add x6,x26, #SWAPPER_DIR_SIZE
1: stp xzr,xzr, [x0], #16
stp xzr,xzr, [x0], #16
stp xzr,xzr, [x0], #16
stp xzr,xzr, [x0], #16
cmp x0,x6
b.lo 1b
ldr x7,=MM_MMUFLAGS
/*
* Create the identity mapping.
*/
add x0, x25,#PAGE_SIZE // sectiontable address
adr x3, __turn_mmu_on // virtual/physical address
create_pgd_entry x25, x0, x3, x5, x6 //See 1.1.3 for details
create_block_map x0, x7, x3, x5, x5, idmap=1
/*
* Map the kernel image (starting withPHYS_OFFSET).
*/
add x0,x26, #PAGE_SIZE //section table address
mov x5,#PAGE_OFFSET
create_pgd_entry x26, x0, x5, x3, x6
ldr x6,=KERNEL_END - 1
mov x3,x24 // physoffset
create_block_map x0, x7, x3, x5, x6
/*
* Map the FDT blob (maximum 2MB; must be within 512MB of
* PHYS_OFFSET).
*/
mov x3,x21 // FDTphys address
and x3,x3, #~((1 << 21) - 1) // 2MBaligned
mov x6,#PAGE_OFFSET
sub x5,x3, x24 //subtract PHYS_OFFSET
tst x5,#~((1 << 29) - 1) //within 512MB?
csel x21,xzr, x21, ne // zero the FDTpointer
b.ne 1f
add x5,x5,x6 // __va(FDTblob)
add x6,x5, #1 << 21 // 2MB for the FDT blob
sub x6,x6, #1 //inclusive range
create_block_map x0, x7, x3, x5, x6
1:
ret
ENDPROC(__create_page_tables)
2.1.1 pgtbl x25, x26, x24 analysis
pgtbl is a macro, defined as follows:
arm64/kernel/head.S line55
.macro pgtbl,ttb0, ttb1, phys
add ttb1,phys, #TEXT_OFFSET - SWAPPER_DIR_SIZE
sub ttb0,ttb1, #IDMAP_DIR_SIZE
.endm
pgtbl x25,x26, x24 //Expanded as follows
add x26,x24, #TEXT_OFFSET -SWAPPER_DIR_SIZE
sub x25,x26,#IDMAP_DIR_SIZE
The variables are defined as follows:
#defineSWAPPER_DIR_SIZE (3 * PAGE_SIZE)
#defineIDMAP_DIR_SIZE (2 * PAGE_SIZE)
illustrate:
1. For an introduction to TTBR0 and TTBR1, see Page B4-1708 of the ARM ARM manual.
2. x25 holds the address of TTBR0 (TTBR0 holds the base address of translation table 0).
3. X26 stores TTBR1 (TTBR1 holds the base address of translation table 1).
4. X24 stores PHYS_OFFSET, /* PHYS_OFFSET - the physical address of the start of memory. */
#definePHYS_OFFSET ({ memstart_addr; })
5. TEXT_OFFSET is the parameter passed in when the Bootloader is started. It is the offset relative to the RAM start address when the kernel Image is loaded.
6. PAGE_OFFSEST: the virtual address of the start of the kernel image.
Figure 1 pgtbl macro analysis
2.1.2 MM_MMUFLAGS explanation
In file arm64/kernel/head.S line71:
/*
* Initial memory map attributes.
*/
#ifndefCONFIG_SMP
#definePTE_FLAGS PTE_TYPE_PAGE | PTE_AF
#definePMD_FLAGS PMD_TYPE_SECT | PMD_SECT_AF
#else
#definePTE_FLAGS PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
#definePMD_FLAGS PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
#endif
#ifdefCONFIG_ARM64_64K_PAGES
#defineMM_MMUFLAGS PTE_ATTRINDX(MT_NORMAL) | PTE_FLAGS
#defineIO_MMUFLAGS PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_XN | PTE_FLAGS
#else
#defineMM_MMUFLAGS PMD_ATTRINDX(MT_NORMAL) |PMD_FLAGS
#defineIO_MMUFLAGS PMD_ATTRINDX(MT_DEVICE_nGnRE) | PMD_SECT_XN | PMD_FLAGS
#endif
According to the above macro definition, MM_MMUFLAGS sets the MMU according to the page size (64K or 4K) selected when you compiled the kernel.
2.1.3 create_pgd_entry/create_block_map macro explanation
1. create_pgd_entry
/*
* Macro to populate the PGD for the corresponding block entry in the next
* level (tbl) for the given virtual address.
*
* Preserves: pgd,tbl,virt
* Corrupts: tmp1, tmp2
*/
.macro create_pgd_entry,pgd, tbl, virt, tmp1, tmp2
lsr tmp1,virt, #PGDIR_SHIFT
and tmp1,tmp1, #PTRS_PER_PGD - 1 // PGD index
orr tmp2,tbl, #3 // PGD entrytable type
str tmp2,[pgd, tmp1, lsl #3]
.endm
According to the above definition, create_pgd_entry x25, x0, x3, x5, x6 are expanded as follows:
lsr x5, x3,# PGDIR_SHIFT //X3 stores the address of __turn_mmu_on, right shift PGDIR_SHIFT (30) bits
and x5, x5, #PTRS_PER_PGD – 1//Set <38:30>
orr x6, x0, #3 //x0 stores the PGD entry (i.e., the lower-level page table address), and the lower three bits are used for the valid bits of the entry
str x6, [ x25, x5, lsl #3] //Store the entry in TTBR0(x25) at the offset x5 and shift left 3 bits (multiply by 8, because entry is 8 bytes).
For easier understanding, see the following figure:
Figure 2 48-bit virtual address composition for 4K pages
Note: The table name corresponding to the virtual address in the above figure is:
PGD: Global Descriptor Table
PUD: converted to PGD, not used in Linux
PMD: Page Table Middle Descriptor Table
PTE: Page Table
The Linux kernel only uses 39 bits of virtual address
Figure 3 64-bit page table entry format
Figure 4
Similarly, create_pgd_entry x26, x0, x5, x3, x6 are expanded as follows:
lsr x3, x5,#PGDIR_SHIFT //X5 stores PAGE_OFFSET = 0xffffffc000000000, right shift PGDIR_SHIFT bits and store in X3
and x3, x3,#PTRS_PER_PGD – 1//Set <38:30>
orr x6, x0, #3 //x0 stores the next page pointed to by TTBR1. The lower three bits are used for the valid bits of the table entry and stored in x6
str x6, [ x26, x3,lsl #3] //Store the entry in TTBR0(x25) at the position where the offset is x5 and shifted 3 bits to the left
The above content is to fill in the page table entry with an offset of x3*8 (because an entry is 8 bytes) in the page table pointed to by TTBR1, and the content is x6 (that is, the position pointed to by x0 in Figure 4)
2. create_block_map
/*
* Macro to populate block entries in the pagetable for the start..end
* virtual range (inclusive).
*
* Preserves: tbl, flags
* Corrupts: phys, start, end, pstate
*/
.macro create_block_map,tbl,flags,phys,start,end,idmap=0
lsr phys,phys, #BLOCK_SHIFT
.if idmap
and start,phys, #PTRS_PER_PTE - 1 // table index
.else
lsr start,start, #BLOCK_SHIFT
and start,start, #PTRS_PER_PTE - 1 // table index
.endif
orr phys,flags, phys, lsl #BLOCK_SHIFT //table entry
.ifnc start,end
lsr end,end, #BLOCK_SHIFT
and end,end, #PTRS_PER_PTE - 1 // tableend index
.endif
9999: str phys,[tbl, start, lsl #3] // store the entry
.ifnc start,end //ifnc: if string1!=string2
add start,start, #1 // next entry
add phys,phys, #BLOCK_SIZE // next block
cmp start,end
b.ls 9999b
.endif
.endm
According to the above macro definition, create_block_map x0, x7, x3, x5, x5, idmap=1, the translation is as follows:
lsr x3, x3, # BLOCK_SHIFT
and x5, x3 # PTRS_PER_PTE – 1
orr x3, x7, x3, lsl # BLOCK_SHIFT
9999:
str x3, [x0, x5, lsl #3]
Similarly, create_block_map x0, x7, x3, x5, x6 is expanded as follows:
lsr x3,x3, #BLOCK_SHIFT
lsr x5,x5, #BLOCK_SHIFT
and x5,x5, #PTRS_PER_PTE - 1 // table index
orr x3,x7, x3, lsl #BLOCK_SHIFT // tableentry
lsr x6,x6, #BLOCK_SHIFT
and x6,x6, #PTRS_PER_PTE - 1 // table endindex
9999: str x3,[x0, x5, lsl #3] // store the entry
add x5,x5, #1 // next entry
add x3,x3, #BLOCK_SIZE // next block
cmp x5, x6
b.ls 9999b
The purpose of create_block_mapx0, x7, x3, x5, x6 macros is to create all the mapping relationships of the kernel image.
3 Questions and Answers
3.1 How to notify the OS kernel of the physical memory size before TLB is opened?
The bootloader passes the physical memory start address and size to the Linux kernel through the device tree (devicetree.dts file). The size of the physical memory needs to be specified in the bootloader, i.e., the dts file. The memory declaration in the dts file is as follows:
Previous article:Several other questions about ARMv8
Next article:Analysis of the working principle of the microcontroller P0 port
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- 4G DTU
- Two key processes for PCB board rework
- Who can convert .brd file to altium designer
- 400 V DC-BUS solution for UPS based on TI C2000
- CST Antenna Simulation and Engineering Design
- Build a car and drive to the distant land! Learn TI automotive reference designs and take a skills test to win prizes!
- EEWORLD University Hall----Rigol National Tour Seminar: Heartbeat, Infinite Possibilities
- Scooter current waveform
- Low-cost intelligent fire and theft alarm system
- Power management device sales reached $15.8 billion