Linux内核初始化步骤(五)


/*
 * Ok, the machine is now initialized. None of the devices
 * have been touched yet, but the CPU subsystem is up and
 * running, and memory and process management works.
 *
 * Now we can finally start doing some real work..
 */
static void __init do_basic_setup(void)
{
	/*针对SMP系统,初始化内核control group 的cpuset子系统,如果非SMP,此函数为空*/
	cpuset_init_smp();

	/*创建一个单线程工作队列khelper.运行的系统中只有一个,主要作用是指定用户空间的程序
	路径和环境变量,最终运行指定的user space的程序,属于关键线程,不能关闭*/
	usermodehelper_init();
	
	shmem_init();
	/*初始化驱动模型中的各子系统,可见的现象是在/sys中出现的目录和文件*/
	driver_init();

	/*在proc文件系统中创建irq目录,并在其中初始化系统中所有中断对应的目录*/
	init_irq_proc();

	/*调用链接到内核中的所有构造函数,也就是链接进.ctor段中的所有函数
	do_ctors();
	usermodehelper_enable();

	/*调用所有编译内核的驱动模块中的初始化函数*/
	do_initcalls();
}


下面对driver_init()作进一步的分析


/**
 * driver_init - initialize driver model.
 *
 * Call the driver model init functions to initialize their
 * subsystems. Called early from init/main.c.
 */
void __init driver_init(void)
{
	/* These are the core pieces */
	/*devtmpfs主要完成了对设备文件创建的管理工作*/
	devtmpfs_init();
	
	/*devices_init()就是调用kset_create_and_add和kobject_create_and_add函数
	来创建kset和kobject对象。
	devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
	建立/sys/devices顶级容器节点
	dev_kobj = kobject_create_and_add("dev", NULL);
	建立/sys/dev顶级容器节点
	sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);
	建立/sys/dev/block二级节点
	sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);
	建立/sys/dev/char二级节点
	*/
	devices_init(); //创建devices相关的设备模型	
	
	/*buses_init()就是调用kset_create_and_add和kobject_create_and_add函数
	来创建kset和kobject对象。
	bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
	建立/sys/bus这个顶级容器节点,该节点是Linux内核中所有总线类型的父节点
	system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
	*/
	buses_init();//	建立Linux设备模型总线部分的顶级节点		

	/*class_kset = kset_create_and_add("class", NULL, NULL);
	建立了/sys/class这个顶级容器节点,该节点是Linux内核中所有class类型的父节点
	*/
	classes_init();	//建立linux设备模型类部分的顶级容器节点

	/*firmware_kobj = kobject_create_and_add("firmware", NULL);
	建立了/sys/firmware这个顶级kobj节点
	*/
	firmware_init();//建立Linux设备模型中firmware部分的顶级节点

	/*hypervisor_kobj = kobject_create_and_add("hypervisor", NULL);
	建立了/sys/hypervisor这个顶级节点
	*/
	hypervisor_init();//建立hypervisor_kobj的顶级容器节点

	/* These are also core pieces, but must come after the
	 * core core pieces.
	 */
	 
	 /*
	 初始化Linux平台总线,平台总线是一种虚拟总线,主要用来管理CPU的片上资源,具有
	 较好的可移植性能,现在有很多驱动已经用platform改写了,主要生成了以下几个节点
	 /sys/bus/platform
	 /sys/bus/platform/devices
	 /sys/bus/platform/drivers
	 */
	platform_bus_init();

	/*在/sys/devices/system/节点下建立一个名为“cpu”的子节点/sys/devices/system/cpu/
	该节点包含cpu的相关属性
	*/
	cpu_dev_init();//建立一个名为“cpu”的类
	/*在/sys/devices/system/节点下建立一个名为“memory"的子节点/sys/devices/system/memory/
	该节点包含了内存相关的属性
	*/
	memory_dev_init();//建立memory设备在sysfs中的接口
}


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);
	return error;
}

platform_bus_init函数中引入两个变量,platform_bus,platform_bus_type,这两个变量
定义如下:


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

struct bus_type platform_bus_type = {
	.name		= "platform",
	.dev_attrs	= platform_dev_attrs,
	.match		= platform_match,
	.uevent		= platform_uevent,
	.pm		= &platform_dev_pm_ops,
};

该函数先调用device_register函数注册platform_bus这个设备,这会在/sys/devices/节点下创建platform节点/sys/devices/platform,此设备节点是所有platform设备的父节点,即所有platform_device设备都会在/sys/devices/platform下创建子节点。然后调用bus_register函数注册platform_bus_type这个总线类型,这会在/sys/bus目录下创建一个platform节点,这个节点是所有platform设备和驱动的总线类型,即所有的platform设备和驱动都会挂载到这个总线上;

猜你喜欢

转载自blog.csdn.net/qq_40788950/article/details/84569365