【linux kernel】linux 内核设备模型的初始化(02)

设备模型初始化-(02)

一、platform_bus_init

linux内核启动过程中使用platform_bus_init()初始化platform总线(/drivers/base/platform.c),定义如下:

int __init platform_bus_init(void)
{
	int error;

	early_platform_cleanup();

	error = device_register(&platform_bus);
	if (error)
		return error;
	error =  bus_register(&platform_bus_type);
	if (error)
		device_unregister(&platform_bus);
	of_platform_register_reconfig_notifier();
	return error;
}

第5行代码,使用early_platform_cleanup()清除早期的platform设备相关的内存。

第7行代码,使用device_register()注册platform_bus设备,platform_bus定义如下:

struct device platform_bus = {
	.init_name	= "platform",
};
EXPORT_SYMBOL_GPL(platform_bus);

第10行代码,使用bus_register()注册platform_bus总线。platform_bus_type定义如下:

struct bus_type platform_bus_type = {
	.name		= "platform",
	.dev_groups	= platform_dev_groups,
	.match		= platform_match,
	.uevent		= platform_uevent,
	.pm		= &platform_dev_pm_ops,
};
二、cpu_dev_init

linux内核启动过程中使用cpu_dev_init()初始化cpu设备,定义如下(/drivers/base/cpu.c):

void __init cpu_dev_init(void)
{
	if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups))
		panic("Failed to register CPU subsystem");

	cpu_dev_register_generic();
}

上述代码调用subsys_system_register()将cpu注册到/sys/devices/system/子系统。cpu_subsys如下定义:

struct bus_type cpu_subsys = {
	.name = "cpu",
	.dev_name = "cpu",
	.match = cpu_subsys_match,
#ifdef CONFIG_HOTPLUG_CPU
	.online = cpu_subsys_online,
	.offline = cpu_subsys_offline,
#endif
};
三、memory_dev_init

linux内核中使用memory_dev_init()初始化内存设备,定义如下(/drivers/base/memory.c):

int __init memory_dev_init(void)
{
	unsigned int i;
	int ret;
	int err;
	unsigned long block_sz;

	ret = subsys_system_register(&memory_subsys, memory_root_attr_groups);
	if (ret)
		goto out;

	block_sz = get_memory_block_size();
	sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;

	/*
	 * Create entries for memory sections that were found
	 * during boot and have been initialized
	 */
	mutex_lock(&mem_sysfs_mutex);
	for (i = 0; i < NR_MEM_SECTIONS; i += sections_per_block) {
		err = add_memory_block(i);
		if (!ret)
			ret = err;
	}
	mutex_unlock(&mem_sysfs_mutex);

out:
	if (ret)
		printk(KERN_ERR "%s() failed: %d\n", __func__, ret);
	return ret;
}

上述第8行代码,使用subsys_system_register()向sysfs注册memory总线。

第12行使用get_memory_block_size()获取内存的block大小,MIN_MEMORY_BLOCK_SIZE定义如下:

#define MIN_MEMORY_BLOCK_SIZE     (1UL << SECTION_SIZE_BITS)

上述宏定义中SECTION_SIZE_BITS与具体架构相关。在arm架构下,定义如下(/arch/arm/include/asm/sparsemem.h):

#define SECTION_SIZE_BITS	28
四、container_dev_init

内核中使用container_dev_init()函数,同样的,调用subsys_system_register()将container注册到sysfs中,定义如下(/drivers/base/container.c):

void __init container_dev_init(void)
{
	int ret;

	ret = subsys_system_register(&container_subsys, NULL);
	if (ret)
		pr_err("%s() failed: %d\n", __func__, ret);
}
五、of_core_init

linux内核中使用of_core_init(()函数,进行设备树相关的核心注册,如下定义(/drivers/of/base.c):

void __init of_core_init(void)
{
	struct device_node *np;

	/* Create the kset, and register existing nodes */
	mutex_lock(&of_mutex);
	of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj);
	if (!of_kset) {
		mutex_unlock(&of_mutex);
		pr_err("devicetree: failed to register existing nodes\n");
		return;
	}
	for_each_of_allnodes(np)
		__of_attach_node_sysfs(np);
	mutex_unlock(&of_mutex);

	/* Symlink in /proc as required by userspace ABI */
	if (of_root)
		proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
}

第7行代码调用kset_create_and_add()函数创建devicetree对象集,并将其添加到sysfs中。

第13~14行代码,是对设备树文件进行解析,并将解析出的设备节点逐一添加到sysfs中。 for_each_of_allnodes宏定义如下(/include/linux/of.h):

#define for_each_of_allnodes_from(from, dn) \
	for (dn = __of_find_all_nodes(from); dn; dn = __of_find_all_nodes(dn))
#define for_each_of_allnodes(dn) for_each_of_allnodes_from(NULL, dn)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iriczhao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值