1. 程式人生 > 其它 >kernel啟動流程-7.head.S的執行____cpu_setup

kernel啟動流程-7.head.S的執行____cpu_setup

技術標籤:# kernel startboot

1. 前言

kernel版本:5.10
平臺:arm64

本專題主要基於《arm64_linux head.S的執行流程》系列文章,前者是基於3.18,本專題針對的是核心5.10。主要分析head.S的執行過程。本文主要記錄head.S的__cpu_setup執行過程。

2. __cpu_setup

#arch/arm64/mm/proc.S
/*
 *      __cpu_setup
 *
 *      Initialise the processor for turning the MMU on.
 *
 * Output:
 *      Return
in x0 the value of the SCTLR_EL1 register. */ .pushsection ".idmap.text", "awx" SYM_FUNC_START(__cpu_setup)

為開啟mmu做一些cpu的初始化工作

TLB/FP/ASIMD/DCC/PMU/AMU初始化

tlbi    vmalle1                         // Invalidate local TLB
dsb     nsh 

mov     x1, #3 << 20
msr     cpacr_el1, x1
// Enable FP/ASIMD mov x1, #1 << 12 // Reset mdscr_el1 and disable msr mdscr_el1, x1 // access to the DCC from EL0 isb // Unmask debug exceptions now, enable_dbg // since this is
per-cpu reset_pmuserenr_el0 x1 // Disable PMU access from EL0 reset_amuserenr_el0 x1 // Disable AMU access from EL0

Memory region attributes

/*                                                                                                                                                                           
 * Memory region attributes                                                                                                                                                  
 */                                                                                                                                                                          
mov_q   x5, MAIR_EL1_SET 
msr     mair_el1, x5      
  • ARM將memory分成兩種型別:normal memory和device memory,對於每種memory區域都通過對應虛擬地址的頁表項標明瞭它的memory屬性,但是頁表項中並沒有直接存放memory屬性,而是存放了一個memory attribute index,這個index將通過MAIR_ELx進行索引;

  • MAIR_ELx全稱Memory Attribute Indirection Register ,它放了8個memory attribute值,通過頁表項中的atrribute index來索引其中的一個memory屬性

MAIR_EL1_SET巨集定義如下:

/*
 * Default MAIR_EL1. MT_NORMAL_TAGGED is initially mapped as Normal memory and
 * changed during __cpu_setup to Normal Tagged if the system supports MTE.
 */
#define MAIR_EL1_SET                                                    \
        (MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRnE, MT_DEVICE_nGnRnE) |      \
         MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRE, MT_DEVICE_nGnRE) |        \
         MAIR_ATTRIDX(MAIR_ATTR_DEVICE_GRE, MT_DEVICE_GRE) |            \
         MAIR_ATTRIDX(MAIR_ATTR_NORMAL_NC, MT_NORMAL_NC) |              \
         MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL) |                    \
         MAIR_ATTRIDX(MAIR_ATTR_NORMAL_WT, MT_NORMAL_WT) |              \
         MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL_TAGGED))
         
#define MAIR_ATTRIDX(attr, idx)         ((attr) << ((idx) * 8))

其中memory attribute index包含如下定義:

/*                                                                                                                                                                                   
 * Memory types available.                                                                                                                                                           
 *                                                                                                                                                                                   
 * IMPORTANT: MT_NORMAL must be index 0 since vm_get_page_prot() may 'or' in                                                                                                         
 *            the MT_NORMAL_TAGGED memory type for PROT_MTE mappings. Note                                                                                                           
 *            that protection_map[] only contains MT_NORMAL attributes.                                                                                                              
 */                                                                                                                                                                                  
#define MT_NORMAL               0                                                                                                                                                    
#define MT_NORMAL_TAGGED        1                                                                                                                                                    
#define MT_NORMAL_NC            2                                                                                                                                                    
#define MT_NORMAL_WT            3                                                                                                                                                    
#define MT_DEVICE_nGnRnE        4                                                                                                                                                    
#define MT_DEVICE_nGnRE         5                                                                                                                                                    
#define MT_DEVICE_GRE           6 

memory屬性值定義如下:

/* MAIR_ELx memory attributes (used by Linux) */                                                                                                                                     
#define MAIR_ATTR_DEVICE_nGnRnE         UL(0x00)                                                                                                                                     
#define MAIR_ATTR_DEVICE_nGnRE          UL(0x04)                                                                                                                                     
#define MAIR_ATTR_DEVICE_GRE            UL(0x0c)                                                                                                                                     
#define MAIR_ATTR_NORMAL_NC             UL(0x44)                                                                                                                                     
#define MAIR_ATTR_NORMAL_WT             UL(0xbb)                                                                                                                                     
#define MAIR_ATTR_NORMAL_TAGGED         UL(0xf0)                                                                                                                                     
#define MAIR_ATTR_NORMAL                UL(0xff)                                                                                                                                     
#define MAIR_ATTR_MASK                  UL(0xff)  

設定TCR_EL1

/*                                                                                                                                                                           
 * Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for                                                                                                         
 * both user and kernel.                                                                                                                                                     
 */                                                                                                                                                                          
mov_q   x10, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \                                                                                                         
                TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \                                                                                                              
                TCR_TBI0 | TCR_A1 | TCR_KASAN_FLAGS                                                                                                                          
tcr_clear_errata_bits x10, x9, x5

ldr_l           x9, idmap_t0sz      

tcr_set_t0sz    x10, x9
/*
 * Set the IPS bits in TCR_EL1.                                                                                                                                              
 */
tcr_compute_pa_size x10, #TCR_IPS_SHIFT, x5, x6
msr     tcr_el1, x10

返回head.S

/*
 * Prepare SCTLR                                                                                                                                                             
 */
mov_q   x0, SCTLR_EL1_SET
ret                                     // return to head.S

SCTLR_EL1_SET巨集定義如下:

#arch/arm64/include/asm/sysreg.h

#define SCTLR_EL1_SET   (SCTLR_ELx_M    | SCTLR_ELx_C    | SCTLR_ELx_SA   |\
                         SCTLR_EL1_SA0  | SCTLR_EL1_SED  | SCTLR_ELx_I    |\
                         SCTLR_EL1_DZE  | SCTLR_EL1_UCT                   |\
                         SCTLR_EL1_NTWE | SCTLR_ELx_IESB | SCTLR_EL1_SPAN |\
                         SCTLR_ELx_ITFSB| SCTLR_ELx_ATA  | SCTLR_EL1_ATA0 |\
                         ENDIAN_SET_EL1 | SCTLR_EL1_UCI  | SCTLR_EL1_RES1)

參考文件

  1. http://www.wowotech.net/linux_kenrel/__cpu_setup.html
    ARM64的啟動過程之(三):為開啟MMU而進行的CPU初始化
  2. https://blog.csdn.net/weixin_42135087/article/details/109351663
    [mmu/cache]-ARMV8 MMU記憶體管理中的Memory attributes和Cache policies