0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

开核返回:EL1启动从处理器

麦辣鸡腿堡 来源:TrustZone 作者:Hcoco 2023-12-05 18:11 次阅读

init/main.c
start_kernel
- >boot_cpu_init   //引导cpu初始化  设置引导cpu的位掩码 online active present possible都为true
- >setup_arch   // arch/arm64/kernel/setup.c
- >  if (acpi_disabled)  //不支持acpi
                  psci_dt_init();     //drivers/firmware/psci.c(psci主要文件) psci初始化 解析设备树 寻找psci匹配的节点
          else
                  psci_acpi_init();   //acpi中允许使用psci情况
- >rest_init
- >kernel_init
- >kernel_init_freeable
- >smp_prepare_cpus  //准备cpu       对于每个可能的cpu 1. cpu_ops[cpu]- >cpu_prepare(cpu)    2.set_cpu_present(cpu, true) cpu处于present状态
- >do_pre_smp_initcalls   //多核启动之前的调用initcall回调
- >smp_init  //smp初始化  kernel/smp.c   会启动其他从处理器

我们主要关注两个函数:psci_dt_init和smp_init psci_dt_init是解析设备树,设置操作函数,smp_init用于启动从处理器。

- >psci_dt_init() //drivers/firmware/psci.c:
 - >init_fn()
  - >psci_0_1_init() //设备树中compatible = "arm,psci"为例
   - >get_set_conduit_method() //根据设备树method属性设置 invoke_psci_fn = __invoke_psci_fn_smc;  (method="smc")
       - > invoke_psci_fn = __invoke_psci_fn_smc
   - >   if (!of_property_read_u32(np, "cpu_on", &id)) {
       651                 psci_function_id[PSCI_FN_CPU_ON] = id;
       652                 psci_ops.cpu_on = psci_cpu_on;  //设置psci操作的开核接口
       653         }
    - >psci_cpu_on()
     - >invoke_psci_fn()
      - >__invoke_psci_fn_smc()
        - > arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res)  //这个时候x0=function_id  x1=arg0, x2=arg1, x3arg2,...
         - >__arm_smccc_smc()
          - >SMCCC   smc //arch/arm64/kernel/smccc-call.S
            - >    20         .macro SMCCC instr
                21         .cfi_startproc
                22         instr  #0   //即是smc #0  陷入到el3
                23         ldr     x4, [sp]
                24         stp     x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
                25         stp     x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
                26         ldr     x4, [sp, #8]
                27         cbz     x4, 1f /* no quirk structure */
                28         ldr     x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS]
                29         cmp     x9, #ARM_SMCCC_QUIRK_QCOM_A6
                30         b.ne    1f
                31         str     x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS]
                32 1:      ret
                33         .cfi_endproc
                34         .endm

最终通过22行 陷入了el3中。(这是因为安全所以还需要到ATF中启动)smp_init函数做从处理器启动:

start_kernel
- >arch_call_rest_init
 - >rest_init
  - >kernel_init,
   - >kernel_init_freeable
    - >smp_prepare_cpus  //arch/arm64/kernel/smp.c
     - >smp_init  //kernel/smp.c  (这是从处理器启动的函数)
      - >cpu_up
       - >do_cpu_up
        - >_cpu_up
         - >cpuhp_up_callbacks
          - >cpuhp_invoke_callback
          - >cpuhp_hp_states[CPUHP_BRINGUP_CPU]
           - >bringup_cpu
            - >__cpu_up  //arch/arm64/kernel/smp.c
             - >boot_secondary
              - >cpu_ops[cpu]- >cpu_boot(cpu)
               - >cpu_psci_ops.cpu_boot
                - >cpu_psci_cpu_boot   //arch/arm64/kernel/psci.c
                 46 static int cpu_psci_cpu_boot(unsigned int cpu)
                   47 { 
                   48         int err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa_symbol(secondary_entry));
                   49         if (err)
                   50                 pr_err("failed to boot CPU%d (%d)n", cpu, err);
                   51   
                   52         return err;
                   53 }

启动从处理的时候最终调用到psci的cpu操作集的cpu_psci_cpu_boot函数 ,会调用上面的psci_cpu_on,最终调用smc,传递第一个参数为cpu的id标识启动哪个cpu,第二个参数为从处理器启动后进入内核执行的地址secondary_entry(这是个物理地址)。

所以综上,最后smc调用时传递的参数为arm_smccc_smc(0xC4000003, cpuid, secondary_entry, arg2, 0, 0, 0, 0, &res)。这样陷入el3之后,就可以启动对应的从处理器, 最终从处理器回到内核(el3->el1),执行secondary_entry处指令 ,从处理器启动完成。

可以发现psci的方式启动从处理器的方式相当复杂,这里面涉及到了el1到安全的el3的跳转,而且涉及到大量的函数回调,很容易绕晕。

(其实为了安全,所以启动从核开核这个操作必须在EL3,开了以后,就可以会EL1,因为已经在EL3给你了准确安全的启动位置了。)

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 处理器
    +关注

    关注

    68

    文章

    18293

    浏览量

    222194
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10449

    浏览量

    206576
  • SMP
    SMP
    +关注

    关注

    0

    文章

    68

    浏览量

    19450
  • 函数
    +关注

    关注

    3

    文章

    3903

    浏览量

    61310
收藏 人收藏

    评论

    相关推荐

    国产兆芯全新四处理器现身:性能大增 #硬声创作季

    处理器
    jf_49750429
    发布于 :2022年11月02日 20:31:27

    处理器助Altera SOPC Builder扩展设计

    处理器上有更多的选择,Altera公司宣布,Freescale将为SOPC Builder工具推出32位V1 ColdFire软。为迅速方便的使用Altera? Cyclone? III FPGA建立
    发表于 06-17 11:40

    悬赏200元求DSP 多核处理器Flash 启动过程详解

    如题,本人在参与的一个项目,用到DSP TMS320C6472 六处理器。准备使用其中两个来相关处理。每个的代码我已经写好,但是本人是
    发表于 12-16 09:12

    ARM处理器异常返回地址

    处理器会将PC-4的值保存到对应模式的LR寄存中,但是该返回地址是否能够被使用还要看具体产生的异常的种类而定。FIQ与RIQ异常:FIQ与RIQ异常返回
    发表于 03-02 15:08

    ARM处理器异常返回地址

    处理器会将PC-4的值保存到对应模式的LR寄存中,但是该返回地址是否能够被使用还要看具体产生的异常的种类而定。FIQ与RIQ异常:FIQ与RIQ异常返回
    发表于 03-07 16:40

    ARM处理器简单介绍

    ARM公司开发了很多系列的ARM处理器,目前最新的系列已经是ARM11了,而ARM6及更早的系列已经很罕见了,ARM7以后的也不是都获得广泛应用。目前,应用比较多的是ARM7系列
    发表于 07-23 07:08

    求一种在多处理器系统中的Nios II软处理器启动方案

    本文设计了一种在多处理器系统中的Nios II软处理器启动方案,这个方案在外部处理器向Nios II的程序存储
    发表于 04-27 06:52

    探讨一下ARM处理器中的CPSR寄存

    ,不在使用单一的CPSR寄存,来保存当前处理器状态,而是用PSTATE来保存处理器状态。PSTATE,包括以下的一些系统寄存1. NZ
    发表于 04-01 15:17

    Arm处理器系统中的通用定时有何作用

    (Private Peripheral Interrupt)向通用中断控制发中断请求。按照不同的指令集扩展,每组都有最多7个定时,但无论如何最基本的都会提供4个,它们分别是:EL1 physical
    发表于 04-22 10:23

    分析ARMv8处理器产生异常的原因以及异常返回时的动作

    使用SVC调用内核,并允许内核代表它们调用更高的异常级别。操作系统内核(EL1),软件可以使用HVC指令调用虚拟机监控程序(EL2),或者使用SMC指令调用安全监视
    发表于 05-23 15:51

    多核处理器启动的基本原理是什么?如何实现呢

    了。单核处理器启动初始化过程也就结束了。对于多核处理器系统,情况复杂一些。一般是有一个主(有时叫core 0)先去完成上述的操作。主
    发表于 06-07 16:41

    看看一个多核处理器系统是如何启动

    了。单核处理器启动初始化过程也就结束了。对于多核处理器系统,情况复杂一些。一般是有一个主(有时叫core 0)先去完成上述的操作。主
    发表于 07-19 15:00

    newlib crt0.s的__start中的Cortex R52非法异常怎么办呢

    的模式位是非法的。甚至Cortex R52手册也建议EL2(Hyp。)更改为EL1(FIQ等)的方法稍有不同。根据R52手册,处理器处于Hypervisor模式且未重置。我的问题是这
    发表于 09-01 15:49

    Cortex-R52循环模型用户指南

    。 ·iCach和DCache大小可变。 ·ITCM和DCM的大小可变。 ·每16、20或24个EL1控制的MPU区域,可在构建时配置。 ·每0、16、20或24个EL2控制的MP
    发表于 08-18 06:27

    EL1882/EL1882C pdf datasheet (

    EL1882/EL1
    发表于 01-17 21:29 17次下载