smp启动-smp_init
上一篇:smp_prepare_cpus
https://www.cnblogs.com/zhangzhiwei122/p/16093412.html
参考-总流程:https://www.cnblogs.com/pengdonglin137/p/11925299.html
参考:https://zhuanlan.zhihu.com/p/373964690
start_kernel -> rest_init-> kernel_thread(kernel_init) & kernel_init-> kernel_init_freeable->smp_init
start_kernel -> rest_init-> kernel_thread 函数创建新 task, 新task 执行 kernel_init 函数
kernel_init 调用 kernel_init_freeable
1497 - 等待 kthreadd_done , 这个在 rest_init 函数里面 713 complete(&kthreadd_done);
1518 - 调用 smp_init
1492static noinline void __init kernel_init_freeable(void) 1493{ 1494 /* 1495 * Wait until kthreadd is all set-up. 1496 */ 1497 wait_for_completion(&kthreadd_done); 1507 cad_pid = task_pid(current); 1508 1509 smp_prepare_cpus(setup_max_cpus); 1510 1511 workqueue_init(); 1512 1513 init_mm_internals(); 1514 1515 do_pre_smp_initcalls(); 1517 1518 smp_init();
smp_init
start_kernel ->arch_call_rest_init ->rest_init ->kernel_init, ->kernel_init_freeable ->smp_prepare_cpus //arch/arm64/kernel/smp.c ->smp_init //kernel/smp.c (这是从处理器启动的函数) ->cpu_up ->do_cpu_up ->_cpu_up ->cpuhp_up_callbacks ->cpuhp_invoke_callback ->cpuhp_hp_states[CPUHP_BRINGUP_CPU] ->bringup_cpu ->__cpu_up //arch/arm64/kernel/smp.c ->boot_secondary ->cpu_ops[cpu]->cpu_boot(cpu) ->cpu_psci_ops.cpu_boot ->cpu_psci_cpu_boot //arch/arm64/kernel/psci.c 46 static int cpu_psci_cpu_boot(unsigned int cpu) 47 { 48 int err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa_symbol(secondary_entry)); 49 if (err) 50 pr_err("failed to boot CPU%d (%d)\n", cpu, err); 51 52 return err; 53 }
psci_ops.cpu_on
在 drivers/firmware/psci/psci.c 中赋值,为psci_cpu_on
186static int psci_cpu_on(unsigned long cpuid, unsigned long entry_point) 187{ 188 int err; 189 u32 fn; 190 191 fn = psci_function_id[PSCI_FN_CPU_ON]; 192 err = invoke_psci_fn(fn, cpuid, entry_point, 0); 193 return psci_to_linux_errno(err); 194}
psci-执行 SMC 指令,cpu 陷入到 el3 中,执行el3 中断代码,完成开核动作
然后
1、新的核心执行 __pa_symbol(secondary_entry)
2、发出SMC 中断调用的核心,返回 ,到 psci_cpu_on 函数的 192 行,继续执行下面的 193 行
->psci_cpu_on() ->invoke_psci_fn() ->__invoke_psci_fn_smc() -> arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res) //这个时候x0=function_id x1=arg0, x2=arg1, x3arg2,...
->arm_smccc_smc // include/linux/arm-smccc.h ->__arm_smccc_smc() // arch/arm64/kernel/smccc-call.S ->SMCCC smc //arch/arm64/kernel/smccc-call.S -> 20 .macro SMCCC instr 21 .cfi_startproc 22 \instr #0 //即是smc #0 陷入到el3 23 ldr x4, [sp] 24 stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] 25 stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS] 26 ldr x4, [sp, #8] 27 cbz x4, 1f /* no quirk structure */ 28 ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS] 29 cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6 30 b.ne 1f 31 str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS] 32 1: ret 33 .cfi_endproc 34 .endm
下一篇: smp_init - idle threads init hotplug threads init
https://www.cnblogs.com/zhangzhiwei122/p/16095130.html