今天小编给大家分享一下linux中arm64多核启动流程是怎样的的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Kernel
今天小编给大家分享一下linux中arm64多核启动流程是怎样的的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
Kernel :4.12.8
smp_init_cpus() //设置多核启动参数和动作
=>static int __init smp_cpu_setup(int cpu) //位于 arch/arm64/kenerl/smp.c
=> cpu_read_ops
=> cpu_get_ops
{ ops = acpi_disabled ? dt_supported_cpu_ops : acpi_supported_cpu_ops; }
.cpu_init = smp_spin_table_cpu_init,
//分析从dts获取启动多核的两种方式 spin_table 和 psci
static const struct cpu_operations *dt_supported_cpu_ops[] __initconst = {
&smp_spin_table_ops,
&cpu_psci_ops,
NULL,
};
// spin_table 方式的几个动作接口
const struct cpu_operations smp_spin_table_ops = {
.name = “spin-table”,
.cpu_init = smp_spin_table_cpu_init,
.cpu_prepare = smp_spin_table_cpu_prepare,
.cpu_boot = smp_spin_table_cpu_boot, //bring up实际动作
};
bringup_cpu
=>int __cpu_up(unsigned int cpu, struct task_struct *idle)
=>ret = boot_secondary(cpu, idle);
cpu_ops[cpu]->cpu_boot(cpu); //实际调用 smp_spin_table_cpu_boot 之类的启动
==============================
下面分析怎么执行cpu_boot的过程
==============================
static struct cpuhp_step cpuhp_bp_states[] =
[CPUHP_BRINGUP_CPU] = {
.name = “cpu:bringup”,
.startup.single = bringup_cpu,
.teardown.single = NULL,
.cant_stop = true,
},
cpuhp_get_step() //唤起一个核有多步,这个是根据state选择对应的状态动作
sp = cpuhp_is_ap_state(state) ? cpuhp_ap_states : cpuhp_bp_states;
return sp + state;
kernel_init() =>kernel_init_freeable()
|=>void __init smp_prepare_cpus(unsigned int max_cpus)
for_each_possible_cpu(cpu) {
err = cpu_ops[cpu]->cpu_prepare(cpu);
|=>smp_init => cpu_up=>do_cpu_up // 同样是从kernel_init_freeable()调用下来的
=>_cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
=>cpuhp_up_callbacks
=>cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
bool bringup, struct hlist_node *node)
{
if (!step->multi_instance) {
cb = bringup ? step->startup.single : step->teardown.single;
ret = cb(cpu);
//这里实际就是拿出了bringup_cpu,调用之
}
实际就是把地址写入spin table中,然后发出sev (send envent,是一个指令)从核就奔跑起来了。
在smp_prepare_cpus() 中调用了smp_spin_table_cpu_prepare() 从核就开始跑了,不过内核设置了wfe 等待真正任务才能真正执行任务。
smp_init()中调用了smp_spin_table_cpu_boot()就是真正的启动了一个idle任务了(待确认)
static int smp_spin_table_cpu_prepare(unsigned int cpu) { __le64 __iomem *release_addr; if (!cpu_release_addr[cpu]) return -ENODEV; release_addr = ioremap_cache(cpu_release_addr[cpu], sizeof(*release_addr)); if (!release_addr) return -ENOMEM; writeq_relaxed(__pa_symbol(secondary_holding_pen), release_addr); __flush_dcache_area((__force void *)release_addr, sizeof(*release_addr)); sev(); iounmap(release_addr); return 0; } static int smp_spin_table_cpu_boot(unsigned int cpu) { write_pen_release(cpu_logical_map(cpu)); sev(); return 0; }
以上就是“Linux中arm64多核启动流程是怎样的”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网操作系统频道。
--结束END--
本文标题: Linux中arm64多核启动流程是怎样的
本文链接: https://lsjlt.com/news/318646.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-03-01
2024-03-01
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0