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指令,激活剩余处理器。

ARM多核处理器启动过程分析,布布扣,bubuko.com

时间: 2025-01-03 13:40:44

ARM多核处理器启动过程分析的相关文章

arm-linux kernel启动过程分析(1)-start_kernel之前第一步

前段时间移植uboot仔细研究过uboot启动过程,最近耐不住寂寞,又想对kernel下手. Uboot启动过程分析博文连接如下: http://blog.csdn.net/skyflying2012/article/details/25804209 kernel启动过程一般不需要我们修改,研究这个对于编写driver也没有多大帮助,但对了解整个linux架构,各种机制还是非常有用. 如一句心灵鸡汤所说,只有了解一个人如何成长,才能看清他是什么样的人(语文不好,大体意思如此..) 只有知道ker

S5PV210-kernel-内核启动过程分析

1.1.内核启动过程分析前的准备 1.拿到一个内核源码时,先目录下的无用文件删除 2.建立SI工程 3.makefile (1)makefile中不详细的去分析,几个关键的地方,makefile开始部分是kernel的版本号,这个版本号比较重要,因为在模块化驱动安装时会需要用到,要注意会查,会改,版本号在makefile中,改直接改的就行 (2)kernel顶层的makefile中定义的两个变量很重要,一个是ARCH,一个CROSS,ARCH表示我们当前的配置编译路径,如果我们的ARCH =AR

K60 启动过程分析

挺高兴的老师借了我一块K60的开发板,趁着暑假好好鼓捣鼓捣! 有了上图的过程分析我想心里大概有个低了吧! 下面看代码: /* CodeWarrior ARM Runtime Support Library * Copyright ?2012 Freescale Semiconductors. All rights reserved. * * $Date: 2013/02/08 07:14:44 $ * $Revision: 1.6 $ */ /* * __arm_start.c - entry-

ARM linux内核启动时几个关键地址【转】

转自:http://www.cnblogs.com/armlinux/archive/2011/11/06/2396787.html 1.       内核启动地址1.1.   名词解释ZTEXTADDR 解压代码运行的开始地址.没有物理地址和虚拟地址之分,因为此时MMU处于关闭状态.这个地址不一定时RAM的地址,可以是支持读写寻址的flash等存储中介. Start address of decompressor. here's no point in talking about virtua

关于ARM CM3的启动文件分析

下面以ARM Cortex_M3裸核的启动代码为例,做一下简单的分析.首先,在启动文件中完成了三项工作: 1.  堆栈以及堆的初始化 2.  定位中断向量表 3.  调用Reset Handler. 在介绍之前,我们先了解一下ARM芯片启动文件中涉及到的一些汇编指令的用法. 补充一下,其中DCD相当于C语言当中的&,定义地址. 1.堆栈以及堆的初始化 1.1 堆栈的初始化 Startup_xxx.s中的堆栈初始化代码 Stack_Size  EQU  0x00000400,这个语句相当于Stac

ActivityManagerService启动过程分析

ActivityManagerService启动过程 一 从Systemserver到AMS zygote-> systemserver:java入层口: /** * The main entry point from zygote. */ public static void main(String[] args) { new SystemServer().run(); } 接下来继续看SystemServer run函数执行过程: private void run() { // 准备Syst

Android4.0(Phone)拨号启动过程分析(二)

接上:Android4.0(Phone)拨号启动过程分析(一) InCallScreen处理来电和拨号的界面,接通电话也是这个界面,接下来分析InCallScreen类是如何处理拨号流程的: @Override protected void onCreate(Bundle icicle) { Log.i(LOG_TAG, "onCreate()... this = " + this); Profiler.callScreenOnCreate(); super.onCreate(icic

startActivity启动过程分析(转)

基于Android 6.0的源码剖析, 分析android Activity启动流程,相关源码: frameworks/base/services/core/java/com/android/server/am/ - ActivityManagerService.java - ActivityStackSupervisor.java - ActivityStack.java - ActivityRecord.java - ProcessRecord.java frameworks/base/co

OpenWrt启动过程分析+添加自启动脚本【转】

一.OpenWrt启动过程分析 转自: http://www.eehello.com/?post=107 总结一下OpenWrt的启动流程:1.CFE->2.linux->3./etc/preinit->4./sbin/init ->5./etc/inittab ->6./etc/init.d/rcS->7./etc/rc.d/S* ->8. OpenWrt是一个开放的linux平台,主要用于带wifi的无线路由上. 类似于Ubuntu.Red Hat.之类的li