zoukankan      html  css  js  c++  java
  • ARM多核处理器启动过程分析【转】

    说明:

    该流程图按照代码执行时间顺序划分为4部分:

    1.     Bootloader在图片上半部,最先启动;

    2.     Kernel在图片下半部,由bootloader引导启动;

    3.CPU0执行流程在图片左半部,bootloader代码会进行判断,先行启动CPU0;

    4.  Secondary CPUs在图片右半部,由CPU唤醒

    具体启动流程如下:

    1.     在bootloader启动时,会判断执行代码的是否为CPU0,如果不是,则执行wfe等待CPU0发出sev指令唤醒。如果是CPU0,则继续进行初始化工作。

     

             mrs  x4,mpidr_el1

             tst    x4,#15             //testwether the current cpu is CPU0, ie. mpidr_el1=15

             b.eq 2f

    /*

     * Secondary CPUs

     */

    1: wfe

    ldr x4, mbox               

    cbz x4, 1b        //if x4==0(ie. The value in address of mbox is 0) dead loop,or jump to x4

    br x4 // branch to thegiven address

     

    2:……        //UART initialisation (38400 8N1)

    以上mbox的地址在Makefile中写定,是0x8000fff8,该地址处初始状态内容为全0。上面代码判断,若mbox地址处内容为0,则死循环;如果不为0则直接跳转到该地址所包含内容处执行。

    2.     在dts中,对cpu-release-addr进行赋值,将其地址设为0x8000fff8。即只要往该地址写入相应的值,例如地址A,并且发送sev指令,就能将次级CPU唤醒,并跳转到A地址处执行。

    cpu-release-addr = <0x0 0x8000fff8>; 

    3. 内核中smp_prepare_cpus 函数对0x8000fff8地址处内容进行了赋值,其值为函数secondary_holding_pen 的地址:

    release_addr = __va(cpu_release_addr[cpu]);

    release_addr[0] = (void*)__pa(secondary_holding_pen);//write function address to mbox

    以上代码执行完后发送sev指令,唤醒其他次级CPU执行secondary_holding_pen函数:

    /*

     * Send an event to wake up the secondaries.

     */

    sev();

    4. secondary cpu 执行secondary_holding_pen()函数时都会去判断当前CPU的ID,并与secondary_holding_pen_release变量做比对,如果相等,则执行进一步初始化,否则执行WFE等待;

    secondary_holding_pen_release变量的修改过程由CPU0调用smp_init()函数进行。该函数首先为相应CPU绑定一个idle线程,然后修改secondary_holding_pen_release的值(其值即CPU0欲唤醒的CPU的ID),最后发送sev指令,唤醒相应CPU执行idle线程。

    secondary_holding_pen()函数代码如下:

             /*

              * This provides a"holding pen" for platforms to hold all secondary

              * cores are helduntil we're ready for them to initialise.

              */

    ENTRY(secondary_holding_pen)

             bl      el2_setup                          // Drop to EL1

             mrs  x0, mpidr_el1

             and  x0, x0, #15                        // CPU number

             adr   x1, 1b

             ldp   x2, x3, [x1]

             sub   x1, x1, x2

             add  x3, x3, x1

    pen: ldr    x4, [x3]

             cmp x4,x0

             b.eq secondary_startup

             wfe

             b       pen

    ENDPROC(secondary_holding_pen)

    附录:

    内核中启动secondary cpus函数调用过程大致如下:

    start_kernel èrest_initèkernel_inièkernel_init_freeable èsmp_init()  kernel/smp.c line 649, 由CPU0激活剩余的处理器

    cpu_upè_cpu_up()è__cpu_up ()èboot_secondary ()èwrite_pen_release该函数中有一句:secondary_holding_pen_release = val; 然后发送sev指令,激活剩余处理器。
  • 相关阅读:
    ‘Host’ is not allowed to connect to this mysql server
    centos7安装mysql
    further configuration avilable 不见了
    Dynamic Web Module 3.0 requires Java 1.6 or newer
    hadoop启动 datanode的live node为0
    ssh远程访问失败 Centos7
    Linux 下的各种环境安装
    Centos7 安装 python2.7
    安装scala
    Centos7 安装 jdk 1.8
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/5775723.html
Copyright © 2011-2022 走看看