linux ARM多处理器的启动过程

本文的假设前提: 单CPU(同一个package/socket), 多核multi-core, smp。

在smp系统中,primary cpu进入start_kernel()执行。

init/main.c

boot_cpu_init()将primary cpu设置为active, present, possible, online。

setup_arch()将构建machine_desc(单板硬件描述),设置secondary cpu引导方式psci。

arch/arm/kernel/setup.c

setup_arch()调用setup_machine_fdt()的参数__atags_pointer为生成的dtb文件(device tree binary)的加载地址。device tree文件在arch/arm/boot/dts/目录下,它用于描述单板硬件信息,比如cpu,memory等。有关这个文件的知识,请参考《linux ARM device tree.docx》。

arch/arm/kernel/devicetree.c

setup_machine_fdt()就是扫描dtb中所有的板子描述信息,找出自己的板子描述数据(machine_desc)。

在获取板子的machine_desc后,调用psci_init(),查找psci node信息并设置psci的fn, cpu_on, cpu_off等函数指针。

arch/arm/kernel/psci.c

setup_arch()之后设置smp_ops为psci_smp_ops。

 

primary cpu在start_kernel最后,进入了rest_init.

rest_init创建一个内核线程kernel_init()来继续跑初始化的工作。

kernel_init()调用kernel_init_freeable()。

kernel_init_freeable()调用smp_init()来初始化smp系统。

init/smp.c

smp_init调用idle_threads_init()给所有的secondary cpu初始化好第一个idle task。

kernel/smpboot.c

然后循环检查secondary cpu是否online,没有online的调用cpu_up()去online.

cpu_up() -> _cpu_up() -> __cpu_up()

kernel/cpu.c

arch/arm/kernel/smp.c

__cpu_up()设置secondary cpu的stack为它的idle tsk的stack,mmu页目录使用和primary cpu相同的pgd。最后进入boot_secondary()。

boot_secondary()调用之前setup_arch时注册的smp ops的smp_boot_secondary,即psci_smp_ops. smp_boot_secondary()

arch/arm/kernel/psci_smp.c

即boot_secondary()调用了psci_boot_secondary()。

psci_boot_secondary()调用了psci_ops.cpu_on(),该函数参数1为target secondary cpu逻辑号,参数2为secondary cpu的执行的代码入口。

psci_ops.cpu_on()在psci_init的时候就设置过了,为psci_cpu_on().

kernel/psci.c

psci_cpu_on()调用invoke_psci_fn(),即__invoke_psci_fn_smc或__invoke_psci_fn_hvc

__invoke_psci_fn_smc()使用指令”smc”触发异常exception.

这个smc指令异常处理就是设置指定的secondary cpu的entry_point,然后发送event给secondary cpu去唤醒这个cpu, 至此primary cpu的任务结束,去跑剩下的任务了。

被唤醒的secondary cpu就去执行primary cpu给它设置的entry_point的代码.

 即secondary cpu将从secondary_startup处开始执行。

arch/arm/kernel/head.S

secondary_startup在386行设置pc为__secondary_switched,即会跳转到__secondary_switched处执行。

arch/arm/kernel/head.S

secondary_start_kernel()定义如下:

arch/arm/kernel/smp.c

secondary_start_kernel()将自己设置为online状态后,调用cpu_startup_entry().

cpu_startup_entry()就等着中断发生,中断发生后,将触发schedule()程序的调用,然后从这个secondary cpu的running queue上选出一个task来run.

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值