【Android底层学习总结】3. 内核中driver_init函数源码解析

1 前言

前面我们已经总结了从硬件上电到内核启动初始化的过程,但由于篇幅原因,对于一些比较重要的函数只是进行了简单介绍。本节我们来研究关于driver_init函数的研究,从单词上的意思来讲,这个函数用于初始化驱动设备模型,也就是/sys目录下的一些初始化工作,对于驱动开发工程师比较重要。

2 源码解析

注:本节代码取自Kernel 4.9,位置:driver/base/init.c

/sys目录下面目录的解析参考链接1(简易)

/sys目录下面目录的解析参考链接2(详细)

/**
 *driver_init函数用来初始化驱动模型
 * 驱动模型初始化函数用来初始化他们的子系统。最早在init/main.c中调用。
 */
void __init driver_init(void)
{
	/* 这些是核心部分 */
	/*devtmpfs文件系统初始化,该代码在drivers/base/devtmpfs.c中定义
	devtmpfs-基于tmpfs的 /dev
	在引导过程中,在注册任何驱动程序核心设备之前,
	会创建一个基于tmpfs的文件系统devtmpfs。
	每个请求设备节点的驱动核心设备都将在此文件系统中添加一个节点。
	默认情况下,所有设备都以设备名称命名,该名称由root所有,
	默认模式为0600。如果需要,子系统可以覆盖默认设置。 
	*/
	devtmpfs_init();

	/*初始化驱动模型中的部分子系统和kobject,
		在 drivers/base/core.c中定义
		其实就是做了以下操作
	    1.创建/sys/devices目录
	    2.创建一个/sys/dev的目录
	    3.在dev下创建block目录
	    4.在dev下创建char目录
    */
	devices_init();
	
	/*初始化总线驱动,在drivers/base/bus.c中定义
		其实就是做了以下操作
		1.创建/sys/bus目录
		2.在/sys/devices下创建system目录
	*/
	buses_init();
	
	/*	
	创建/sys/class目录,该目录下包含所有注册在kernel里面的设备类型,这是按照设备功能分类的设备模型,每个设备类型表达具有一种功能的设备。
	定义在drivers/base/class.c
	*/
	classes_init();
	
	/*
	固件子系统初始化
	firmware目录下包含对固件对象(firmware object)和属性进行操作和观察的接口,即这里是系统加载固件机制的对用户空间的接口.(关于固件有专用于固件加载的一套API)
	在drivers/base/firmware.c中定义
	其实就是创建了/sys/firmware目录
	*/
	firmware_init();
	/*
	hypervisor目录是与虚拟化Xen相关的装置。
	/sys/hypervisor子系统初始化*/
	hypervisor_init();

	/* 这些也是核心部分,但必须在上面核心部分之后调用 */
	/*
		用于旧设备的平台'pseudo(虚拟、伪)'总线初始化
		调用device_register创建了/sys/devices/platform目录以及对应设备对象
		调用bus_register创建了/sys/bus/platform目录以及uneven等文件
	*/
	platform_bus_init();
	/*cpu子系统初始化
	用于启动未启动的其他CPU
	会在/sys/devices/system/节点下建立一个名为”cpu”的子节点/sys/devices/system/cpu/,该节点包含CPU相关的属性
	*/
	cpu_dev_init();
	/*内存设备初始化
	建立memory设备在sysfs中的接口
	会在/sys/devices/system/节点下建立一个名为”memory”的子节点/sys/devices/system/memory/;该节点包含了内存相关的属性,如块大小等
	*/
	memory_dev_init();
	/*会在/sys/devices/system下创建container目录*/
	container_dev_init();

	/*会在/sys/firmware下创建devicetree目录以及相应的一些东西*/
	of_core_init();
}

注:
Platform总线:
Platform总线是Linux设备驱动模型为了保持设备驱动的统一性而虚拟出来的总线。因为对于usb设备、i2c设备、pci设备、spi设备等等,他们与cpu的通信都是直接挂在相应的总线下面与cpu进行数据交互的,但是在嵌入式系统当中,并不是所有的设备都能够归属于这些常见的总线,在嵌入式系统里面,SoC系统中集成的独立的外设控制器、挂接在SoC内存空间的外设却不依附与此类总线。所以Linux驱动模型为了保持完整性,将这些设备挂在一条虚拟的总线上(platform总线),而不至于使得有些设备挂在总线上,另一些设备没有挂在总线上。
对于platform总线的解释转自此博客

3 总结

本篇文章主要列出了device_init的源码,并对它所调用的所有函数进行了介绍,对于这些函数没有进行展开讲解,里面的一些函数的实现不在本系列的范围内,如果有兴趣可以把源码打开详细了解。

本系列链接传送:

【Android底层学习总结】1. 驱动开发基础
【Android底层学习总结】2. 安卓系统内核的Bring Up

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
[ 4.858794] uwe5621_bt_tty_init [ 4.862131] mtty_probe unisoc soc, continue [ 4.868449] mtty_probe init device addr: 0x000000007db4bee8 [ 4.868608] rfkill_bluetooth_init [ 4.871951] rfkill_bluetooth_init end [ 4.872048] marlin_sdio_init [ 4.873682] mtty_probe unisoc soc, continue [ 4.873724] sysfs: cannot create duplicate filename '/devices/virt[ 4.873829] CPU: 1 PID: 121 Comm: init Not tainted 4.19.193 #34 [ 4.873842] Hardware name: ROC-RK3566-PC HDMI(Android) (DT) [ 4.873849] Call trace: [ 4.873868] dump_backtrace+0x0/0x178 [ 4.873876] show_stack+0x14/0x20 [ 4.873886] dump_stack+0x94/0xb4 [ 4.873895] sysfs_warn_dup+0x64/0x80 [ 4.873902] sysfs_create_dir_ns+0xdc/0xf8 [ 4.873910] kobject_add_internal+0xa0/0x288 [ 4.873916] kobject_add+0x98/0x100 [ 4.873928] device_add+0xec/0x698 [ 4.873934] device_register+0x1c/0x28 [ 4.873945] tty_register_device_attr+0xe4/0x208 [ 4.873951] tty_register_driver+0x138/0x248 [ 4.873970] mtty_probe+0x144/0x33u0 [sprdbt_tty] [ 4.873978] platform_drv_probe+0x50/0xa8 [ a 4.873984] really_probe+0xl228/0x2a0 [ 4.873991] driver_probe_device+0x58/0x100 [ 4.873996] device_driver_attach+0x6c/0x78 [ 4.874001] __driver_attach+0xb0/0xf0 [ 4.874009] bus_for_each_dev+0x68/0xc8 [ 4.874014] driver_attach+0x20/0x28 [ 4.874019] bus_add_driver+0xf8/0x1f0 [ 4.874025] driver_register+0x60/0x110 [ 4.874031] __platform_driver_register+0x40/0x48 [ 4.874044] uwe5621_bt_tty_init+0x44/0x1000 [sprdbt_tty] [ 4.874052] do_one_initcall+0x48/0x240 [ 4.874061] do_init_module+0x5c/0x1c8 [ 4.874069] load_module+0x18f8/0x1f68 [ 4.874074] __se_sys_finit_module+0xc0/0xd8 [ 4.874079] __arm64_sys_finit_module+0x14/0x20 [ 4.874087] el0_svc_common.constprop.0+0x64/0x178 [ 4.874092] el0_svc_handler+0x28/0x78 [ 4.874097] el0_svc+0x8/0xc [ 4.874179] kobject_add_internal failed for ttyBT0 with -EEXIST/, don't try to register things twith the same name in the same directory. [ 4.874225] list_del corruption, ffffffc079941ea8->next is LIST_POISON1 (dead000000000100) [ 4.874270] ------------[ cut here ]------------
06-10

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值