kernel启动流程-head.S的执行__7.__cpu_setup

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

T0SZ: TTBR0_EL1的转换内存区域的总位数为2^(64-T0SZ),对于64位系统一般用到的地址不会是64位而是少于64位, 一 般是48位,比如T0SZ为16,说明需要转换的地址是48位。

返回head.S

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

将SCTLR_EL1_SET保存在x0中,用于设置SCTLR_EL1, 其中会包含开启MMU的设置
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
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值