[platform]新旧内核的device设备注册对比
转自:http://blog.chinaunix.net/uid-7332782-id-3268801.html
1. Version2.6内核启动过程
start_kernel( ) //板子上电启动后进入start_kernel( ),相当于程序的main入口
-->setup_arch(&command_line) //command_line由内核传入
-->mdesc = setup_machine(machine_arch_type);
-->list = lookup_machine_type(nr); //汇编实现查找机器码所定义的平台,找到后返回mdesc结构
-->init_machine = mdesc->init_machine; //struct machine_desc *mdesc;machine_desc结构很重要,
-->rest_init()
-->kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); //定义进程kernel_init,pid=1,在kthreadd进程创建好后调度运行
-->kernel_init()
-->do_basic_setup()
-->driver_init()
-->devices_init()
-->buses_init()
-->classes_init()
-->platform_bus_init()
-->do_initcalls() //此函数很重要,执行了initcall表中所有的函数,包含了init_machine(saar_init())函数
-->saar_init()
-->init_post() //调度用户空间程序,比如bash,在用户空间死循环执行程序
-->pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); //定义进程kthreadd
2. Version3.x内核启动过程和2.6版本在init_machine加载设备资源的差异对比
- 在2.6内核中, 在setup_arch()中,举个例子imx5,
-->init_machine=mdesc->init_machine; //init/main.c->start_kernel()->setup_arch(), 将init_machine指向mdesc结构体重的init_machine指针,而mdesc中该指针指向具体芯片对应的设备资源函数mxc_board_init.
-->.init_machine=mxc_board_init; //arch/arm/mach-mx5/mx50_arm2.c->MACHINE_START() ,宏即时初始化machine_desc结构体
-->mxc_register_device(&mxc_dma_device); //arch/arm/mach-mx5/mx50_arm2.c->mxc_board_init(), 在mxc_board_init完成这些设备注册
-->mxc_register_device(&mxc_wdt_device); //mxc_wdt_device这些设备资源也都申明在mach-mx50下面
-->mxc_register_device(&mxci2c_devices[0]);
-->..........
当然在setup_arch()中对init_machine进行初始化,这个时候并没有调用init_machine函数,init_machine是在代码中被定义为arch_initcall属性(arch/arm/kernel/setup.c), 然后在do_initcalls()中进行遍历调用,具体见上述的启动过程。
由上述可以看出,在系统启动时,device设备就已经register到总线上了,而3.x以后已经不在mach-**中申明设备资源了,那启动流程如何呢,见下一节。
- 在3.x内核中,在setup_arch()是这么处理的, 首先解析dtb
-->setup_arch() //init/main.c->start_kernel()->setup_arch()
-->mdesc=setup_machine_fdt();
-->unflatten_device_tree() //和2.6内核不同,在setup_arch()中并没有init_machine = mdesc->init_machine.那init_machine如何执行呢?
-->__unflatten_device_tree()
-->unflatten_dt_node() //到此基本完成dts中node到链表的操作
节点中的设备注册
-->DT_MACHINE_START //machine_desc结构体赋值,在2.6内核中宏伟MACHINE_START,文件位置:arch/arm/mach-***
-->.init_machine=imx6sx_init_machine
-->of_platform_populate(); //imx6sx_init_machine()调用,在setup_arch()中解析设备数,构造设备节点链表,然后在这里进行设备的注册,而init_machine为arch_initcall属性,当在setup_arch()后面代码调用到do_initcalls()函数时调用init_machine()函数完成设备注册。
-->of_platform_bus_create(); //由for_each_child_of_node()调用,遍历device tree中每个节点
-->of_platform_device_create_pdata()
-->of_device_alloc() //为每个device申请空间
-->platform_device_put()
-->of_platform_bus_create()
到此完成设备的注册。
在3.x的setup.c中关于init_machine的调用是这么定义的
static int __init customize_machine(void)
{
/*
* customizes platform devices, or adds new ones
* On DT based machines, we fall back to populating the
* machine from the device tree, if no callback is provided,
* otherwise we would always need an init_machine callback.
*/
if (machine_desc->init_machine)
machine_desc->init_machine();
#ifdef CONFIG_OF
else
of_platform_populate(NULL, of_default_bus_match_table,
NULL, NULL);
#endif
return ;
}
关于init_machine到底会不会被执行,在Documentation/Devicetree/usage-model.txt中有这么一段话
The most interesting hook in the DT context is .init_machine() which
is primarily responsible for populating the Linux device model with
data about the platform. Historically this has been implemented on
embedded platforms by defining a set of static clock structures,
platform_devices, and other data in the board support .c file, and
registering it en-masse in .init_machine(). When DT is used, then
instead of hard coding static devices for each platform, the list of
devices can be obtained by parsing the DT, and allocating device
structures dynamically. The simplest case is when .init_machine() is only responsible for
registering a block of platform_devices. A platform_device is a concept
used by Linux for memory or I/O mapped devices which cannot be detected
by hardware, and for 'composite' or 'virtual' devices (more on those
later). While there is no 'platform device' terminology for the DT,
platform devices roughly correspond to device nodes at the root of the
tree and children of simple memory mapped bus nodes.
[platform]新旧内核的device设备注册对比的更多相关文章
- Linux 内核 struct device 设备
在最低层, Linux 系统中的每个设备由一个 struct device 代表: struct device { struct device *parent; struct kobject kobj ...
- 驱动开发学习笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇
驱动开发读书笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇 下面这段摘自 linux源码里面的文档 : 内核版本2.6.22Doc ...
- 驱动开发学习笔记. 0.04 linux 2.6 platform device register 平台设备注册 1/2 共2篇
驱动开发读书笔记. 0.04 linux 2.6 platform device register 平台设备注册 1/2 共2篇下面这段摘自 linux源码里面的文档 : Documentatio ...
- 由MTK平台 mtkfb 设备注册疑问引发的知识延伸--ARM Device Tree
问题: 在kernel-3.10\drivers\misc\mediatek\videox\mt6735\mtkfb.c里面int __init mtkfb_init(void) 有看到 platfo ...
- Android平台上PMEM的使用及Platform设备注册(二)
三.注册PMEM设备 这里我们除了描述PMEM设备,还将注册一个拥有memory空间和IRQ资源的示例设备example_device. 对于example_device,定义如下结构体: stati ...
- 深入理解linux网络技术内幕读书笔记(八)--设备注册与初始化
Table of Contents 1 设备注册之时 2 设备除名之时 3 分配net_device结构 4 NIC注册和除名架构 4.1 注册 4.2 除名 5 设备初始化 6 设备类型初始化: x ...
- [11]Windows内核情景分析---设备驱动
设备驱动 设备栈:从上层到下层的顺序依次是:过滤设备.类设备.过滤设备.小端口设备[过.类.过滤.小端口] 驱动栈:因设备堆栈原因而建立起来的一种堆栈 老式驱动:指不提供AddDevice的驱动,又叫 ...
- RT-thread内核之IO设备管理系统
RT-Thread系统的IO设备管理模块为上层应用提供了一个对设备进行访问的通用抽象接口,而对于下层设备来说则提供了底层设备驱动框架,并通过定义的数据结构对设备信息和底层设备驱动进行管理.从系统整体位 ...
- 如何删除 Ubuntu 上不再使用的旧内核
提问:过去我已经在我的Ubuntu上升级了几次内核.现在我想要删除这些旧的内核镜像来节省我的磁盘空间.如何用最简单的方法删除Ubuntu上先前版本的内核? 在Ubuntu上,有几个方法来升级内核.在U ...
随机推荐
- Matlab位运算笔记
本文为转载其他地方的文章; MATLAB函数 1.matlab函数bitset 设置数的某一位二进制位为1. <Simulink与信号处理> 使用方法 C = bitset(A,bit) ...
- ZOJ 1041 Transmitters
原题链接 题目大意:有一个发射站,覆盖范围是半径一定的一个半圆.在一个1000*1000平方米的地盘里有很多接收站.给定发射站的圆心,求最佳角度时能覆盖接收站的个数. 解法:本质上就是给一个原点和其他 ...
- Spring+SpringMVC+Mybatis+ehcache
http://www.tuicool.com/articles/myeANv http://www.mamicode.com/info-detail-1151624.html
- c 深度剖析 1
1.register register 变量必须是能被CPU寄存器所接受的类型(32 位机器 寄存器为32位),必须是单个的值,长度小于或等于整形的长度 不能用&来获取register 变量的 ...
- c#部分---结构体;
结构体:自定义类型 值类型一组变量的组合需要定义的位置 class里面 main函数外面里面包含的变量可以是多种数据类型的 例如学生信息的结构体:学号,姓名,性别,分数 struct Student ...
- URAL 1137 Bus Routes(欧拉回路路径)
1137. Bus Routes Time limit: 1.0 secondMemory limit: 64 MB Several bus routes were in the city of Fi ...
- Python实现ORM
ORM即把数据库中的一个数据表给映射到代码里的一个类上,表的字段对应着类的属性.将增删改查等基本操作封装为类对应的方法,从而写出更干净和更富有层次性的代码. 以查询数据为例,原始的写法要Python代 ...
- 黑马程序员——JAVA基础之包,权限
------- android培训.java培训.期待与您交流! ---------- 包(package) 对类文件进行分类管理. 给类提供多层命名空间. 写在程序文件的第一行. 类名的全称的是:包 ...
- JSBinding + SharpKit / Important Notes
Serialization of List<T> is not supported. 1 public int v; // SUPPORTED 2 public GameObject go ...
- 套接字I/O模型-完成端口IOCP
“完成端口”模型是迄今为止最为复杂的一种I/O模型.然而,假若一个应用程序同时需要管理为数众多的套接字,那么采用这种模型,往往可以达到最佳的系统性能!但不幸的是,该模型只适用于Windows NT和W ...