1. cpu虚拟总线的创建
cpu_subsys
的定义和初始化代码位于 Linux 内核的 drivers/base/cpu.c
文件中。以下是关键代码节选:
// drivers/base/cpu.c
struct bus_type cpu_subsys = {
.name = "cpu",
.dev_name = "cpu",
.match = cpu_subsys_match,
.offline = cpu_subsys_offline,
.online = cpu_subsys_online,
};
EXPORT_SYMBOL_GPL(cpu_subsys);
static int __init cpu_dev_init(void)
{
int err;
// 注册 cpu_subsys 总线
err = subsys_system_register(&cpu_subsys, NULL);
if (err)
return err;
// 其他初始化...
}
core_initcall(cpu_dev_init);
2. CPU 注册并挂载到 cpu_subsys
int register_cpu(struct cpu *cpu, int num)
{
int error;
cpu->node_id = cpu_to_node(num);
memset(&cpu->dev, 0x00, sizeof(struct device));
cpu->dev.id = num;
cpu->dev.bus = &cpu_subsys;
cpu->dev.release = cpu_device_release;
cpu->dev.offline_disabled = !cpu->hotpluggable;
cpu->dev.offline = !cpu_online(num);
cpu->dev.of_node = of_get_cpu_node(num, NULL);
#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
cpu->dev.bus->uevent = cpu_uevent;
#endif
cpu->dev.groups = common_cpu_attr_groups;
if (cpu->hotpluggable)
cpu->dev.groups = hotplugable_cpu_attr_groups;
error = device_register(&cpu->dev);
if (error)
return error;
per_cpu(cpu_sys_devices, num) = &cpu->dev;
register_cpu_under_node(num, cpu_to_node(num));
dev_pm_qos_expose_latency_limit(&cpu->dev, 0);
return 0;
}
挂载关键点:cpu->dev.bus = &cpu_subsys 明确将该 CPU 设备挂载到 cpu_subsys 总线。
调用路径:
start_kernel() → arch_call_rest_init() → rest_init() → kernel_init() → kernel_init_freeable() → smp_init() → cpu_up() → _cpu_up() → cpuhp_up_callbacks() → cpuhp_invoke_callback() → bringup_cpu() → __cpu_up() → ... → register_cpu()