目录

  • 1.前言
  • 2. el2_setup
    • 选择栈
    • 判断当前的异常级别
    • 设置EL2端模式
    • 设置EL0/EL1的端模式
    • VHE支持
    • Hyp configuration
    • access physical timer and counter
    • GIC设置
    • Populate ID registers
    • hstr_el2清零
    • EL2 debug
    • Statistical profiling
    • LORegions
    • Stage-2 translation
    • install_el2_stub
  • 3. 总结
  • 参考文档

1.前言

kernel版本:5.10
平台:arm64

本专题主要基于《arm64_linux head.S的执行流程》系列文章,前者是基于3.18,本专题针对的是内核5.10。主要分析head.S的执行过程。本文主要记录head.S的el2_setup执行过程。

2. el2_setup

选择栈

 msr     SPsel, #1

由于当前异常级别可能是EL1也可能是EL2,因此msr SPsel, #1切换到当前异常级别的SP,如果当前为EL1,则切换到SPEL1,如果当前为EL2,则切换到SPEL2

判断当前的异常级别

mrs     x0, CurrentEL
cmp     x0, #CurrentEL_EL2
b.eq    1f

从CurrentEL获取当前的异常级别,保存到x0中,并判断是否处于EL2, 如果处于EL2则直接跳转到1f设置EL2的端模式

设置EL2端模式

1:      mov_q   x0, (SCTLR_EL2_RES1 | ENDIAN_SET_EL2)
msr     sctlr_el2, x0

设置EL2下为大端存储

设置EL0/EL1的端模式

 mov_q   x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)msr     sctlr_el1, x0mov     w0, #BOOT_CPU_MODE_EL1isbret

如果处于EL1级别,设置EL0和EL1下为大端存储,将启动时的异常级别EL1保存到w0

VHE支持

#ifdef CONFIG_ARM64_VHE/** Check for VHE being present. For the rest of the EL2 setup,* x2 being non-zero indicates that we do have VHE, and that the* kernel is intended to run at EL2.*/mrs     x2, id_aa64mmfr1_el1ubfx    x2, x2, #ID_AA64MMFR1_VHE_SHIFT, #4
#elsemov     x2, xzr
#endif

通过读取id_aa64mmfr1_el1,存入X2, 判断CPU是支持虚拟主机扩展VHE模式,还是传统的分离Hyp模式。

vhe的全称是Virtualization Host Extension support。是armv8.1的新特性,其最终要就是支持type-2的hypervisors 这种扩展让kernel直接跑在el2上,这样可以减少host和guest之间share的寄存器,并减少overhead of virtualization 具体实现如下面的patch:https://lwn.net/Articles/650524/

Hyp configuration

/* Hyp configuration. */
mov_q   x0, HCR_HOST_NVHE_FLAGS
cbz     x2, set_hcr
mov_q   x0, HCR_HOST_VHE_FLAGS
set_hcr:msr     hcr_el2, x0isb

当寄存器x2,零表示Hyp模式;非零表示VHE模式
HCR_HOST_NVHE_FLAGS宏定义如下:

#define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA)

HCR_HOST_NVHE_FLAGS宏定义如下

#define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA)

access physical timer and counter

        /** Allow Non-secure EL1 and EL0 to access physical timer and counter.* This is not necessary for VHE, since the host kernel runs in EL2,* and EL0 accesses are configured in the later stage of boot process.* Note that when HCR_EL2.E2H == 1, CNTHCTL_EL2 has the same bit layout* as CNTKCTL_EL1, and CNTKCTL_EL1 accessing instructions are redefined* to access CNTHCTL_EL2. This allows the kernel designed to run at EL1* to transparently mess with the EL0 bits via CNTKCTL_EL1 access in* EL2.*/cbnz    x2, 1fmrs     x0, cnthctl_el2orr     x0, x0, #3                      // Enable EL1 physical timersmsr     cnthctl_el2, x0
1:msr     cntvoff_el2, xzr                // Clear virtual offset

Hyp模式, 启动计数器 ,设定Non-secure EL1 and EL0可访问物理定时器和计数器,虚拟偏移量清零;
VHE模式只需要清零偏移量

GIC设置

/* GICv3 system register access */
mrs     x0, id_aa64pfr0_el1
ubfx    x0, x0, #ID_AA64PFR0_GIC_SHIFT, #4
cbz     x0, 3f

ID_AA64PFR0_EL1的bit24~27如果为0表示不支持GIC V3, 为1表示支持GICV3

mrs_s   x0, SYS_ICC_SRE_EL2
orr     x0, x0, #ICC_SRE_EL2_SRE        // Set ICC_SRE_EL2.SRE==1
orr     x0, x0, #ICC_SRE_EL2_ENABLE     // Set ICC_SRE_EL2.Enable==1
msr_s   SYS_ICC_SRE_EL2, x0
isb                                     // Make sure SRE is now set
mrs_s   x0, SYS_ICC_SRE_EL2             // Read SRE back,
tbz     x0, #0, 3f                      // and check that it sticks
msr_s   SYS_ICH_HCR_EL2, xzr            // Reset ICC_HCR_EL2 to defaults

ICC_SRE_EL2_ENABLE表示Non-secure EL1 accesses to ICC_SRE_EL1 are permitted if EL3 is not present or ICC_SRE_EL3.Enable is 1, otherwise Non-secure EL1 accesses to ICC_SRE_EL1 trap to EL3

如果是GICv3,设置SYS_ICC_SRE_EL2、SYS_ICH_HCR_EL2寄存器,这两个寄存器是GICv3的CPU接口寄存器。设置完毕后需要重新读取来确认,如果设置不成功则跳转到3f

Populate ID registers

mrs     x0, midr_el1
mrs     x1, mpidr_el1
msr     vpidr_el2, x0
msr     vmpidr_el2, x1

根据物理CPU的ID寄存器和亲合属性寄存器,来设置虚拟CPU对应的寄存器

hstr_el2清零

msr     hstr_el2, xzr                   // Disable CP15 traps to EL2

将Hypervisor系统陷入寄存器HSTR_EL2清零。一般情况下,当客户虚拟机是AArch32位,会有Thumb和协处理器方式,不希望在访问相关寄存器陷入到EL2中

EL2 debug

 /* EL2 debug */                                                                                                                          mrs     x1, id_aa64dfr0_el1                                                                                                              sbfx    x0, x1, #ID_AA64DFR0_PMUVER_SHIFT, #4                                                                                            cmp     x0, #1                                                                                                                           b.lt    4f                              // Skip if no PMU present                                                                        mrs     x0, pmcr_el0                    // Disable debug access traps                                                                    ubfx    x0, x0, #11, #5                 // to EL2 and allow access to
4:                                                                                                                                               csel    x3, xzr, x0, lt                 // all PMU counters from EL1

通过id_aa64dfr0_el1寄存器的pmu version来判断是否支持pmu
如果pmu version小于1则不支持PMU,直接将x3清零;
否则表示支持pmu,则从pmcr_el0获取事件的数量赋值给x3,也就是说x3用于保存事件数量

Statistical profiling

     ubfx    x0, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4cbz     x0, 7f                          // Skip if SPE not presentcbnz    x2, 6f                          // VHE?mrs_s   x4, SYS_PMBIDR_EL1              // If SPE available at EL2,and     x4, x4, #(1 << SYS_PMBIDR_EL1_P_SHIFT)cbnz    x4, 5f                          // then permit sampling of physicalmov     x4, #(1 << SYS_PMSCR_EL2_PCT_SHIFT | \1 << SYS_PMSCR_EL2_PA_SHIFT)msr_s   SYS_PMSCR_EL2, x4               // addresses and physical counter
5:mov     x1, #(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT)orr     x3, x3, x1                      // If we don't have VHE, thenb       7f                              // use EL1&0 translation.
6:                                              // For VHE, use EL2 translationorr     x3, x3, #MDCR_EL2_TPMS          // and disable access from EL1
7:msr     mdcr_el2, x3                    // Configure debug traps

判断PMS是否支持

LORegions

mrs     x1, id_aa64mmfr1_el1
ubfx    x0, x1, #ID_AA64MMFR1_LOR_SHIFT, 4
cbz     x0, 1f
msr_s   SYS_LORC_EL1, xzr

TODO

Stage-2 translation

msr     vttbr_el2, xzrcbz     x2, install_el2_stubmov     w0, #BOOT_CPU_MODE_EL2          // This CPU booted in EL2
isb
ret

如上VHE和HYP模式将分别走不同的分支

如果是VHE模式,直接返回w0为BOOT_CPU_MODE_EL2。由于进入内核时,CPU处于EL2?,所以直接调用ret指令返回,CPU仍然是EL2
install_el2_stub是Hyp模式相关设置和返回代码

install_el2_stub


SYM_INNER_LABEL(install_el2_stub, SYM_L_LOCAL)                                                                                                   /** When VHE is not in use, early init of EL2 and EL1 needs to be                                                                         * done here.* When VHE _is_ in use, EL1 will not be used in the host and* requires no configuration, and all non-hyp-specific EL2 setup* will be done via the _EL1 system register aliases in __cpu_setup.                                                                     */mov_q   x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)                                                                                            msr     sctlr_el1, x0                                                                                                                    /* Coprocessor traps. */                                                                                                                 mov     x0, #0x33ffmsr     cptr_el2, x0                    // Disable copro. traps to EL2                                                                   /* SVE register access */mrs     x1, id_aa64pfr0_el1ubfx    x1, x1, #ID_AA64PFR0_SVE_SHIFT, #4                                                                                               cbz     x1, 7f                                                                                                                           bic     x0, x0, #CPTR_EL2_TZ            // Also disable SVE trapsmsr     cptr_el2, x0                    // Disable copro. traps to EL2                                                                   isb     mov     x1, #ZCR_ELx_LEN_MASK           // SVE: Enable full vector                                                                       msr_s   SYS_ZCR_EL2, x1                 // length for EL1.                                                                               /* Hypervisor stub */
7:      adr_l   x0, __hyp_stub_vectors                                                                                                           msr     vbar_el2, x0                                                                                                                     /* spsr */mov     x0, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\                                                                           PSR_MODE_EL1h)                                                                                                             msr     spsr_el2, x0                                                                                                                     msr     elr_el2, lrmov     w0, #BOOT_CPU_MODE_EL2          // This CPU booted in EL2                                                                        eret

当非VHE模式下,用于EL1和EL2的早期初始化

3. 总结

el2_setup根据当前CPU处于EL1还是EL2主要做了如下的工作:

  1. 设置当前异常级别的栈
  2. 判断当前的异常级别,并据此设置端模式;
  3. 如果支持VHE,设置VHE,否则设置传统HYP模式
  4. 启动定时器
  5. GIC设置
  6. 根据物理CPU的ID寄存器和亲合属性寄存器,来设置虚拟CPU对应的寄存器
  7. hstr_el2清零
  8. EL2 debug相关寄存器设置

参考文档

  1. https://blog.csdn.net/lsshao/article/details/108404486
    飞腾CPU虚拟化相关代码分析(一)
  2. http://www.wowotech.net/215.html
  3. https://blog.csdn.net/tiantao2012/article/details/82620014
    VHE

kernel启动流程-head.S的执行_4.el2_setup相关推荐

  1. kernel启动流程-head.S的执行_3.preserve_boot_args

    1.前言 kernel版本:5.10 平台:arm64 本专题主要基于<arm64_linux head.S的执行流程>系列文章,前者是基于3.18,本专题针对的是内核5.10.主要分析h ...

  2. kernel启动流程-start_kernel的执行_8.cpio initrd解包

    目录 1. 前言 2. rootfs挂载 3.populate_rootfs 4.GotName的处理 参考文档 1. 前言 本专题文章承接之前<kernel启动流程_head.S的执行> ...

  3. [kernel 启动流程] 前篇——vmlinux.lds分析

    https://blog.csdn.net/ooonebook/article/details/52690132 以下例子都以project X项目tiny210(s5pv210平台,armv7架构) ...

  4. 【SemiDrive源码分析】【X9芯片启动流程】30 - AP1 Android Kernel 启动流程 start_kernel 函数详细分析(一)

    [SemiDrive源码分析][X9芯片启动流程]30 - AP1 Android Kernel 启动流程 start_kernel 函数详细分析(一) 一.Android Kernel 启动流程分析 ...

  5. I.MX6ULL_Linux_系统篇(21) kernel启动流程

    链接脚本 vmlinux.lds 要分析 Linux 启动流程,同样需要先编译一下 Linux 源码,因为有很多文件是需要编译才会生成的.首先分析 Linux 内核的连接脚本文件 arch/arm/k ...

  6. Kernel 启动流程梳理

    内核生命周期 uboot 打印完 Starting kernel . . .,就完成了自己的使命,控制权便交给了 kernel 的第一条指令,也就是下面这个函数 init/main.c asmlink ...

  7. uboot流程——uboot启动流程

    [uboot] (第五章)uboot流程--uboot启动流程 2016年11月07日 20:12:07 阅读数:2230 以下例子都以project X项目tiny210(s5pv210平台,arm ...

  8. Linux Kernel系列一:开篇和Kernel启动概要

    前言 近期几个月将Linux Kernel的大概研究了一下,以下须要进行深入具体的分析.主要将以S3C2440的一块开发板为硬件实体.大概包含例如以下内容: 1 bootloader分析,以uboot ...

  9. [uboot] (第五章)uboot流程——uboot启动流程

    以下例子都以project X项目tiny210(s5pv210平台,armv7架构)为例 [uboot] uboot流程系列: [project X] tiny210(s5pv210)上电启动流程( ...

最新文章

  1. 【集合论】序关系 ( 偏序集元素之间的关系 | 可比 | 严格小于 | 覆盖 | 哈斯图 )
  2. 深入理解HTTP协议、HTTP协议原理分析
  3. 不愿意和别人打交道_不想麻烦别人,也不希望别人麻烦我,是什么心理?看完就明白...
  4. 【译】Three Security Trends Are Key to Decentralize Artificial Intelligence
  5. c++ 预处理命令 预定义变量用法
  6. BOM的window对象的属性及其方法
  7. React开发(106):getFieldDecorator不能包裹太多div
  8. cuSPARSE库:(十四)求解稀疏三角形线性系统(solution of sparse triangular linear systems)
  9. Hyper-V动态扩展或差异磁盘体积缩小技巧
  10. CPU 架构 —— ARM 架构
  11. 联通沃云服务器型号,云服务器
  12. Thinking in Java读书笔记
  13. 背景渐变/字体颜色渐变(可应用于银行卡背景框)
  14. laravel8+ 微信小程序生成二维码
  15. Win11磁盘被写保护怎么解除?
  16. ZPanel-开源免费的虚拟主机在线管理系统
  17. 借助小程序云开发实现小程序的登陆注册功能
  18. 实现太阳系行星公转动画实例(CSS+HTML5 源码)
  19. spring AOP中 aop:advisor 与 aop:aspect 的区别
  20. 等保三级认证备案证明是哪个机构颁发?一般要多久?

热门文章

  1. 只要7步,就能将任何魔方6面还原
  2. UPS及联邦快递获牌照
  3. 字节大量招聘芯片工程师,韦布首批5张照片全公开,京东快递北京总部被查处,今日更多大新闻在此...
  4. linux 发行版族谱
  5. Teamcenter每个月限制许可,模块许可限制,用户账号限制
  6. 视频教程-Markdown 标记语言-PHP
  7. android课程设计计步器,数字计步器课程设计.docx
  8. Halcon 一维条码识别
  9. 2021年数学建模B题分析--乙醇偶合制备乙烯
  10. 用python画耳朵_Python易学就会(四)turtle绘图入门--高级篇