栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

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

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

设备模型初始化-(02)

文章目录

设备模型初始化-(02)一、platform_bus_init二、cpu_dev_init三、memory_dev_init四、container_dev_init五、of_core_init

一、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;

	
	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: %dn", __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: %dn", __func__, ret);
}
五、of_core_init

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

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

	
	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 nodesn");
		return;
	}
	for_each_of_allnodes(np)
		__of_attach_node_sysfs(np);
	mutex_unlock(&of_mutex);

	
	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)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/728810.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号