SMP多核处理器omap4启动分析 笔记版 转载请注明出处---crosskernel@gmail.com

Android 筆記-Linux Kernel SMP (Symmetric Multi-Processors) 開機流程解析 Part(3) Linux 多核心啟動流程從rest_init到ker Android 筆記-Linux Kernel SMP  (Symmetric Multi-Processors) 開機流程解析 Part(3) Linux 多核心啟動流程從rest_init到kernel_init與CPU Idle/HotPlug機制     hlchou@mail2000.com.tw by loda. Loda's Blog App BizOrz 阅读详情


Omap4 是Ti在移动市场上的绝唱。在没有通信modem的支援下,依赖于omap4,Ti硬是在手机处理器市场赢得最后一站。

Omap4是双核Cortex A9架构的处理器,本文分析其启动表现。


代码执行顺序如黑体:
static int __init kernel_init(void * unused)
{
…
smp_prepare_cpus(setup_max_cpus);
…
}



void __init smp_prepare_cpus(unsigned int max_cpus)
{
…
scu_enable(scu_base);
wakeup_secondary();
}
}


static void __init wakeup_secondary(void)
{
//cpu0 将omap_secondary_startup的物理地址写入omap4的AuxCoreBoot 1寄存器
//这时cpu1执行rom指令WFE处在等待状态
omap_auxcoreboot_addr(virt_to_phys(omap_secondary_startup));
smp_wmb();


dsb();


//cpu0 发出sev指令,sev指令激活cpu1,使之推出的WFE状态,cpu1继续执行rom的指令,其启动顺寻是:1查看AuxCoreBoot 0寄存器的状态是否满足要求 2 若AuxCoreBoot 0寄存器状态满足要求,则取出AuxCoreBoot 1寄存器的地址,跳转之
set_event();
mb();
}


//在omap4的芯片内部存在着一个代码rom,其代码运行在arm架构monitor状态。这段代码只使用master cpu及cpu0里的资源。这样就可以避免寻址的问题,cpu可以不管mmu是否打开关闭,都能访问这个rom。




//cpu0 将物理地址写入omap4的AuxCoreBoot 1寄存器
ENTRY(omap_auxcoreboot_addr)
//这是在cpu0执行的代码,而rom代码也运行在cpu0上,所以要进行寄存器的保存。
stmfd   sp!, {r2-r12, lr}
//0x105是rom代码的调用代号,通过r12传递。
    ldr r12, =0x105
Dsb
//smc是进入monitor状态的专用指令,一旦执行这个指令cpu就像发生了一次异常一样,进入monitor状态
smc #0
//rom代码完成服务工作,cpu0被恢复原来状态,显然rom代码尽量精简,留下了寄存器恢复的工作。这里回复寄存器状态。
ldmfd   sp!, {r2-r12, pc}
END(omap_auxcoreboot_addr)




执行到这里,cpu1被激活了,但是他还不能往前跑,因为这个时候内核还没有为其准备好相关管理结构,这时cpu1检查AuxCoreBoot 0寄存器状态,如果还没有满足要求,cpu1执行WFE仍旧进入WFE状态。cpu0要在完成所有准备工作之后才会改写AuxCoreBoot 0寄存器,释放cpu1。


Cpu0在调用void __init smp_prepare_cpus(setup_max_cpus)叫醒cpu1之后,会继续执行一些内核初始化工作,以及smp相关的初始化工作,其中最重要的是通过调用static void __init smp_init(void)->...->int __cpuinit __cpu_up(unsigned int cpu)




int __cpuinit __cpu_up(unsigned int cpu)
{
...
//首先为cpu1 fork出一个idle线程
/*
* Spawn a new process manually, if not already done.
* Grab a pointer to its task struct so we can mess with it
*/
if (!idle) {
idle = fork_idle(cpu);
if (IS_ERR(idle)) {
printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
return PTR_ERR(idle);
}
ci->idle = idle;
} else {
/*
* Since this idle thread is being re-used, call
* init_idle() to reinitialize the thread structure.
*/
init_idle(idle, cpu);
}


/*
* Allocate initial page tables to allow the new CPU to
* enable the MMU safely.  This essentially means a set
* of our "standard" page tables, with the addition of
* a 1:1 mapping for the physical address of the kernel.
*/


//为cpu1创建一个struct mm_struct
pgd = pgd_alloc(&init_mm);
pmd = pmd_offset(pgd + pgd_index(PHYS_OFFSET), PHYS_OFFSET);
*pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) |
    PMD_TYPE_SECT | PMD_SECT_AP_WRITE);
flush_pmd_entry(pmd);
outer_clean_range(__pa(pmd), __pa(pmd + 1));


/*
* We need to tell the secondary core where to find
* its stack and the page tables.
*/
secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
secondary_data.pgdir = virt_to_phys(pgd);
__cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));


/*
* Now bring the CPU into our world.
*/
//叫醒cpu1,这里cpu1会真正运行起来
ret = boot_secondary(cpu, idle);
//到了这里,完成了cpu1的激活工作,cpu1将执行自己相关到初始化工作,等到cpu1完成自己的工作,cpu1会在cpu_online_mask位图上将自己对应的标志位置位,而cpu0在这里等待那一刻的到来
if (ret == 0) {
unsigned long timeout;


/*
* CPU was successfully started, wait for it
* to come online or time out.
*/
timeout = jiffies + HZ;
while (time_before(jiffies, timeout)) {
//如果对应位有效,说明cpu1完成了初始化工作,真正成为了系统中的一颗对称多处理器
if (cpu_online(cpu))
break;


//代码跑到这里说明,cpu1工作还没完成,再等一会。
udelay(10);
barrier();
}


if (!cpu_online(cpu))
ret = -EIO;
}
    ......
}






int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
struct clockdomain *cpu1_clkdm;
static bool booted;
/*
* Set synchronisation state between this boot processor
* and the secondary one
*/
spin_lock(&boot_lock);


/*
* Update the AuxCoreBoot0 with boot state for secondary core.
* omap_secondary_startup() routine will hold the secondary core till
* the AuxCoreBoot1 register is updated with cpu state
* A barrier is added to ensure that write buffer is drained
*/
//这里cpu0改写AuxCoreBoot0的状态,告诉cpu1可以跑了
omap_modify_auxcoreboot0(0x200, 0xfffffdff);
flush_cache_all();
smp_wmb();


/*
* SGI isn't wakeup capable from low power states. This is
* known limitation and can be worked around by using software
* forced wake-up. After the wakeup, the CPU will restore it
* to hw_auto. This code also gets initialised but pm init code
* initialises the CPUx clockdomain to hw-auto mode
*/
if (booted) {
cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
omap2_clkdm_wakeup(cpu1_clkdm);
smp_cross_call(cpumask_of(cpu));
} else {
//第一次启动会跑到这里,因为上次wakeup_secondary函数虽然用SEV指令激活的cpu1,但是cpu1发现AuxCoreBoot0的状态不满足,又进入WFE状态了。所以这里要在捅一次cpu1。
set_event();
booted = true;
}


/*
* Now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
*/
spin_unlock(&boot_lock);


return 0;
}








//omap-headsmp.s


ENTRY(omap_secondary_startup)
//cpu1终于跑出了rom,第一件事是再检查一下AuxCoreBoot0,如果不满足要求就hold下来。在这之前rom里已经检查了AuxCoreBoot0,并且把ENTRY(omap_secondary_startup)地址从AuxCoreBoot0取出来。
hold: ldr r12,=0x103
dsb
smc #0@ read from AuxCoreBoot0
mov r0, r0, lsr #9
mrc p15, 0, r4, c0, c0, 5
and r4, r4, #0x0f
cmp r0, r4
bne hold


/*
* we've been released from the wait loop,secondary_stack
* should now contain the SVC stack for this core
*/
b secondary_startup
END(omap_secondary_startup)






ENTRY(omap_modify_auxcoreboot0)
stmfd   sp!, {r1-r12, lr}
ldr r12, =0x104
dsb
smc #0
ldmfd   sp!, {r1-r12, pc}
END(omap_modify_auxcoreboot0)








Head.s
#if defined(CONFIG_SMP)
ENTRY(secondary_startup)
/*
* Common entry point for secondary CPUs.
*
* Ensure that we're in SVC mode, and IRQs are disabled.  Lookup
* the processor type - there is no need to check the machine type
* as it has already been validated by the primary processor.
*/
setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
mrc p15, 0, r9, c0, c0@ get processor id
bl __lookup_processor_type
movs r10, r5@ invalid processor?
moveq r0, #'p'@ yes, error 'p'
beq __error


/*
* Use the page tables supplied from  __cpu_up.
*/
adr r4, __secondary_data
ldmia r4, {r5, r7, r12}@ address to jump to after
sub r4, r4, r5@ mmu has been enabled
ldr r4, [r7, r4]@ get secondary_data.pgdir
adr lr, BSYM(__enable_mmu)@ return address
mov r13, r12@ __secondary_switched address
 ARM( add pc, r10, #PROCINFO_INITFUNC ) @ initialise processor
 @ (return control reg)
 THUMB( add r12, r10, #PROCINFO_INITFUNC )
 THUMB( mov pc, r12 )
ENDPROC(secondary_startup)




ENTRY(__secondary_switched)
ldr sp, [r7, #4]@ get secondary_data.stack
mov fp, #0
b secondary_start_kernel
ENDPROC(__secondary_switched)




asmlinkage void __cpuinit secondary_start_kernel(void)
{
struct mm_struct *mm = &init_mm;
unsigned int cpu = smp_processor_id();


printk("CPU%u: Booted secondary processor\n", cpu);


/*
* All kernel threads share the same mm context; grab a
* reference and switch to it.
*/
atomic_inc(&mm->mm_users);
atomic_inc(&mm->mm_count);
current->active_mm = mm;
cpumask_set_cpu(cpu, mm_cpumask(mm));
cpu_switch_mm(mm->pgd, mm);
enter_lazy_tlb(mm, current);
local_flush_tlb_all();


cpu_init();
preempt_disable();


/*
* Give the platform a chance to do its own initialisation.
*/
platform_secondary_init(cpu);


/*
* Enable local interrupts.
*/
notify_cpu_starting(cpu);
local_irq_enable();
local_fiq_enable();


/*
* Setup the percpu timer for this CPU.
*/
percpu_timer_setup();


calibrate_delay();


smp_store_cpu_info(cpu);


/*
* OK, now it's safe to let the boot CPU continue
*/
set_cpu_online(cpu, true);


/*
* OK, it's off to the idle thread for us
*/
cpu_idle();
}
Linux进程管理之CPU启动相关的四大状态 前言 在讲调度域的初始化之前我们不得不先说一下多CPU启动的一些基本知识点,不过我们的目的是聚焦于调度域,所以只会讲与调度相关的内容。 possible,present,online和active四大状态分别记录在__cpu_possible_mask,set_cpu_present,__cpu_online_mask和__cpu_active_mask这几个变量中。下面四个函数用于设置这四个状... 阅读详情

相关推荐

ANSA二次开发在线帮助:ANSA和μETA API文档

  为了方便大家学习ANSA二次开发,我将ANSA和μETA二次开发的官方文档整合到了我的个人网站CAECoder中,大家点击ANSA和μETA API官方帮助文档进行访问即可查看。   本站也将开展对ANSA和μETA API文档的翻译工作,请大家持续关注! ANSA和μETA API文档   ANSA和μETA脚本接口是一个应用程序编程接口(API),允许开发人员访问ANSA和μETA核心功能和数据。   ANSA和μETAAPI是Python编程语言的扩展。 Python Python简.

CAECoder 4323

SMP多核启动(二):PSCI

前面我们知道了SMP多核启动有两种方式,上一篇讲了spin-table。但是因为这个玩意只能启动从核,功能太单一了。现在社区几乎很少使用spin-table这种方式,取而代之的是psci,他不仅可以启动从处理器,还可以关闭,挂起等其他核操作,现在基本上arm64平台上使用多核启动方式都是psci。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 6413

Oracle登录报错ORA-12560?5分钟搞定TNS协议适配器错误的完整修复指南

本文详细解析了Oracle登录报错ORA-12560(TNS协议适配器错误)的成因与解决方案。从基础服务检查到高级网络配置排查,提供了一套完整的修复流程,帮助数据库管理员快速解决连接问题,确保Oracle数据库的稳定运行。

weixin_29278805的博客 524

linux core image,Linux内核源码分析--内核启动之(2)Image内核启动(汇编部分)(Linux-3.0 ARMv7)...

/** linux/arch/arm/kernel/head.S** Copyright (C) 1994-2002 Russell King* Copyright (c) 2003 ARM Limited* All Rights Reserved** This program is free software; you can redistribute it and/or modify*...

weixin_39714191的博客 217

避坑指南:ROS2 Humble摄像头标定常见错误排查(从‘CALIBRATE’按钮不变绿到保存文件找不到)

本文详细解析了ROS2 Humble环境下摄像头标定的常见问题及解决方案,从CALIBRATE按钮不变绿到标定文件保存失败等疑难杂症。提供硬件准备、参数设置、实时诊断到结果验证的全流程指导,特别针对Ubuntu2204系统和usb_cam驱动的兼容性问题给出实用建议,帮助开发者高效完成内参标定。

weixin_29193359的博客 398

基于Vivado MIG IP核的DDR3读写实验(top_rom_ddr/ddr_top)

一、前言 关于Vivado MIG IP核详细配置可以参考我之前的文章:基于Vivado MIG IP核的DDR3控制器(DDR3_CONTROL) 关于MIG IP核的用户端的接口时序可以参考这篇文章:XILINX 的 MIG IP(非AXI4)接口时序以及控制 二、实验内容 本次实验的内容主要是通过MIG IP核向DDR3读写数据,DDR3的接口时序由ddr_top模块提供: ddr_top模块的数据来源是wr_fifo,wr_fifo的数据实际来自top_sd_photo模块(本实验仿真

耐心的小黑的博客 3027

linux 0号进程如何创建

linux 0号进程创建流程分析

OS Developer的博客 566

杰理-tone

低音质格式切换高音质格式:切换提示音格式,未导出,编译下载没有提示音;提示音导出,再次编译下载,提示音正常高音质格式切换低音质格式:不需要导出,直接编译下载,提示音正常。

m0_67447112的博客 955

kernel启动流程第二阶段

kernel启动第二阶段: 本部分与第一阶段类似,均为网上资料节选,主要用于对kernel启动流程有个基础概念。

liangzaiEvil的博客 1426

【stata基础代码大全 】 可独立完成一篇实证

用stata打开,直接替换自己需要的变量就行,小白友好❗️❗️❗️。八、八.中介效应检验:路径分析(三种方法)第二种方法即Sobel-Goodman检验。*(7)Winsor处理,剔除异常值。六、内生性问题解决方法(附具体模型)其三,工具变量:两阶段最小二乘。第三种方法即Bootstrap检验。二、Stata中数据的基本处理。*(5)生成行业、年度虚拟变量。PSM1————近邻匹配。七、调节效应检验:机制分析。*(2)剔除数据中的样本。*(4)给变量添加标签。*(3)生成新的变量。*(6)基本数据匹配。

J_Giser的博客 8025

【数据集】全球湿度数据集总结

【数据集】全球湿度数据集总结

WW、forever的博客 1662

QCOM 从CPU 启动地址

1. QCOM 多核起机流程 根据

firefox_1980的专栏 2507

解决 maven编译项目-Fatal error compiling: 无效的目标发行版: 21 -> [Help 1]

惊奇的发现,maven没有用环境变量中设置好的JAVA_HOME目录,至此发现错误原因,原来执行java -version默认使用系统环境变量JAVA_HOME,而maven优先使用了windows的用户变量JAVA_HOME(这里之前忘记修改,仍然指向java8路径),修改用户变量JAVA_HOME指向java21或删除该用户变量JAVA_HOME(如无它用)后即可。打开maven包所在的目录,在maven的配置文件 mvn.cmd 文件中,设置java_home的目录。

litlit023的专栏 1801

SMP多核启动(一):spin-table

aarch64架构实现了两种不同的启动方式,**spin-table和psci。** 其中spin-table方式非常简单,但其只能被用于secondary cpu启动,功能比较单一。 随着aarch64架构电源管理需求的增加(如cpu热插拔、cpu idle等),arm设计了一套标准的电源管理接口协议psci。该协议可以支持所有cpu相关的电源管理接口,而且由于电源相关操作是系统的关键功能,为了防止其被攻击,该协议将底层相关的实现都放到了secure空间,从而可提高系统的安全性。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 3616

贝叶斯统计 [韦来生编]

贝叶斯(Bayes)统计是近几十年来迅速发展起来的数理统计的一个重要分支。贝叶斯方法与经典统计方法的主要不同之处是进行统计推断时除了利用样本信息外,还要利用参数的先验信息,因此可以提高统计推断或统计决策的效果。它在经济、金融、生物、医学、自然科学和社会科学等许多领域具有广泛的应用。贝叶斯方法的研究已渗透到了统计学的几乎所有领域。作者在给中国科学技术大学概率论与数理统计专业本科生开设的“数理统计”课程中有一章专门讲授“贝叶斯方法和统计决策理论”,近十年来也给中国科学技术大学概率统计专业研究生开设过几次“贝叶斯分析”课。本书是在对过去讲稿的内容作了适当的增减和调整的基础上完成的。  本书共分六章。第1章是绪论,介绍了贝叶斯统计的若干基本概念,同时对必要的数理统计的基础知识有重点地作了回顾。第二章介绍了确定先验分布的若干可供选择的方法。第三章介绍了几类常见统计模型参数的后验分布的主要结果和计算方法。第四章和第五章分别介绍了“贝叶斯统计推断”和“贝叶斯统计决策”的内容。第六章介绍了贝叶斯统计计算的若干方法,包括蒙特卡洛方法和马尔可夫链蒙特卡洛(MCMC)方法以及相关统计软件的简介。本书的每一章附右大量的例题和习题,书末附有常用的几个表格和部分习题解答供读者查用。  大约可在54学时内讲授本书的第1章至第六章的主要内容,教师可根据学时需要选讲本书第1章至第六章的部分内容。书中标“*”号的章节可略去不讲,留给读者作为阅读材料。第六章例题中的R代码和部分例题的数据文件等可从作者个人主页下载。  作者在编写本书的过程中参考了J.O.Berger教授的《统计决策论及贝叶斯分析》和茆诗松教授编写的《贝叶斯统计》等书中的一些内容,以及《贝叶斯分析》一书中由张伟平博士编写的有关贝叶斯统计计算的一些内容。在此表示衷心感谢。  本书编写准备过程中,中国科学技术大学统计与金融系的几个研究生帮助完成了本书部分中文的录入和排版,作者对他们的辛勤工作表示真诚的感谢。高等教育出版社为本书的出版给予了大力支持。在此一并致谢。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

linux SMP 启动过程学习笔记

1.       SMP硬件体系结构: 对于SMP最简单可以理解为系统存在多个完全相同的CPU,所有CPU共享总线,拥有自己的寄存器。对于内存和外部设备访问,由于共享总线,所以是共享的。Linux操作系统多个CPU共享在系统空间上映射相同,是完全对等的。   由于系统中存在

yarsen的专栏 2067

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

设置每CPU环境

5.3 设置每CPU环境<br />回到start_kernel,563行调用mm_init_owner函数,将init_mm的owner字段指回init_task。这个函数可以说进入start_kernel以来最简单的函数了。继续走,setup_command_line也很简单:<br /> <br />static void __init setup_command_line(char *command_line)<br />{<br />       saved_command_line = allo

云(存储),松(耦合) 6413

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

smp boot

kernel 提供了smp boot 实现的架构,要实现smp boot 先要实现smp_operations  这个结构体 http://lxr.free-electrons.com/source/arch/arm/mach-prima2/platsmp.c?v=3.18#L140 140 struct smp_operations sirfsoc_smp_ops __initdat

jason的笔记 2885

AliOS Things SMP系统及其在esp32上实现示例

AliOS Things实现了基本的SMP调度框架,支持多CPU体系的系统运行和调度机制。多CPU之间对用户系统运行无区别,能平等访问共享内存、外设等共享资源;任务可以动态在多核间进行切换或者绑定运行;高优先级任务可以最大化利用空闲资源核运行。基于此框架,可以快速实现AliOS Things在各种不同多核CPU架构下的移植;对于上层应用,可以不需要关注任...

weixin_33948416的博客 479

linux smp 引导多核源码分析

1 SMP cpu map和操作函数集初始化 1.1 初步初始化cpu map start_kernel ---------->smp_setup_processor_id linux 从第一个cpu上面启动以后,先利用smp_setup_processor_id设置cpu index void __init smp_setup_processor_id(void) { ...

oqqYuJi12345678的博客 2193

Linux芯片级移植与底层驱动(基于3.7.4内核) --SMP多核启动以及CPU热插拔驱动

出处:http://21cnbao.blog.51cto.com/109393/1143518 在Linux系统中,对于多核的ARM芯片而言,Bootrom代码中,CPU0会率先起来,引导Bootloader和Linux内核执行,而其他的核则在上电时Bootrom一般将自身置于WFI或者WFE状态,并等待CPU0给其发CPU核间中断(IPI)或事件(一般透过SEV指令)唤醒之。一个典

1088

ARM多核处理器启动过程分析

你想知道多核处理器是否如何启动的?一张图就够了

Heron——Linux & ARM 2万+

SMP多核启动

在 Linux系统中,对于多核的ARM芯片而言,在Biotron代码中,每个CPU都会识别自身ID,如果ID是0,则引导Bootloader和 Linux内核执行,如果ID不是0,则Biotron一般在上电时将自身置于WFI或者WFE状态,并等待CPU0给其发CPU核间中断或事件(一般通过SEV指令)以唤醒它。一个典型的多核 Linux启动过程如图20.6所示。 被CPU0唤醒的CPUn可以在运行...

weixin_30396699的博客 598

第20章 Linux芯片级移植及底层驱动之SMP多核启动以及CPU热插拔驱动

20.4 SMP多核启动以及CPU热插拔驱动    在Linux系统中,对于多核的ARM芯片,在Bootrom代码中,每个CPU都会识别自身ID,如果ID是0,则引导Bootloader和Linux内核执行,如果ID不是0,则Bootrom一般在上电时将自身置于WFI(WaitFortInerrupt)或者WFE(WaitForEvent)状态,并等待CPU0给其发CPU核间中断或事件(一般通过S...

xiezhi123456的博客 1811

读核笔记-内核初始化-从start_kernel到init

  如图所示,内核的初始化过程由start_kernel函数开始,至第一个用户进程init结束,调用了一系列的初始化函数对所有的内核组件进行初始化。其中,start_kernel、rest_init、kernel_init、init_post等4个函数构成了整个初始化过程的主线。   图  内核初始化   本节接下来的内容会结合内核代码,对内核初始化过程主线上的几个...

weixin_33674437的博客 251

Linux内核中的prefetch,读《ARM Linux 内核源代码剖析》.......第11、12章 setup_arch()  (unwind_...

setup_arch函数用于处理与架构相关的一系列事物。它调用了很多函数,先贴一张其调用的函数关系图。这些函数部分在本文介绍,部分会在后面几篇介绍。setup_archvoid __init setup_arch(char **cmdline_p){struct tag *tags = (struct tag *)&init_tags;struct machine_desc *mdesc;...

weixin_35743031的博客 990

ThreadX学习(7)——多核SMP

ThreadX学习(7)——多核SMP学习参考多核SMP初始化调度执行中断 学习参考 ThreadX SMP user guide 官方 多核SMP SMP指对称多处理器,与AMP非对称多处理器并列。两者区别这里不详述,大概是前者一般只跑一个系统,而后者一般跑多个系统。 初始化 这是ThreadX SMP应用程序中的第一种程序执行类型。初始化包括处理器重置和线程调度循环进入点之间的所有程序执行。 初始化由核心0执行或启动,这是重置后默认运行的核心。 调度执行 初始化完成后,每个运行ThreadX SMP

weixin_43739110的博客 2749
上一篇: s5pv210 uboot 源码分析 笔记版 转载请注明出处---crosskernel@gmail.com
下一篇: linux的板级支持以I.mx5为例 笔记版 转载请注明出处---crosskernel@gmail.com
crosskernel
博客等级 码龄18年 14粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值