转自: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的调用是这么定义的

1 static int __init customize_machine(void)2 {3     /*
4 * customizes platform devices, or adds new ones5 * On DT based machines, we fall back to populating the6 * machine from the device tree, if no callback is provided,7 * otherwise we would always need an init_machine callback.8      */
9     if (machine_desc->init_machine)10         machine_desc->init_machine();11 #ifdef CONFIG_OF12     else
13 of_platform_populate(NULL, of_default_bus_match_table,14 NULL, NULL);15 #endif
16     return 0;17 }

关于init_machine到底会不会被执行,在Documentation/Devicetree/usage-model.txt中有这么一段话

The most interesting hook in the DT context is.init_machine() whichis primarily responsible forpopulating the Linux device model with
data about the platform.  Historicallythishas been implemented on
embedded platforms by defining aset of staticclock structures,
platform_devices, and other datainthe board support .c file, and
registering it en-masse in .init_machine().  When DT isused, then
instead of hard codingstatic devices foreach platform, the list of
devices can be obtained by parsing the DT, and allocating device
structures dynamically.The simplestcase is when .init_machine() is only responsible forregistering a block of platform_devices.  A platform_deviceisa concept
used by Linuxfor memory or I/O mapped devices which cannot be detected
by hardware, andfor 'composite' or 'virtual'devices (more on those
later).  While thereis no 'platform device' terminology forthe DT,
platform devices roughly correspond to device nodes at the root of the
tree and children of simple memory mapped bus nodes.

转载于:https://www.cnblogs.com/aaronLinux/p/5559721.html

[platform]新旧内核的device设备注册对比相关推荐

  1. reactjs组件生命周期:componentWillReceiveProps及新旧版本生命周期钩子函数对比

    reactjs组件生命周期:componentWillReceiveProps及新旧版本生命周期钩子函数对比

  2. 内存条上面参数详解_「内存」新旧光威16GB内存条参数对比,发现镁光颗粒

    我第一次买了两条,一条当场翻车了,就换了一条,当时没有发现有任何颗粒上的变化,新旧内存都是南亚颗粒的. 这次我当时同批次的第二条内存翻车了,换来的内存我看了一眼,居然是镁光颗粒的,看来是这批产品有所更 ...

  3. 【咕嘎文本对比助手】如何两份手机号或文本对比去重,新旧两批号码如何快速的对比重复,找出重复和不重复的部分,单个文件如何找出重复,单个文件如何找出不重复下面关于五种逻辑做详细解答

    在手机号码整理过程中,群发短信还有大数据分析等整理文件的过程中经常有号码重复 有人说excel有两列数据,怎么用vlookup查找两列数据是否有重复值?在SQL语句中就很好处理了not in 就完事了 ...

  4. linux升级到指定内核版本,如何在CentOS/RHEL上安装或升级新的内核版本

    Linux内核是一个整体的类Unix计算机操作系统内核.通常我们使用的Linux发行版,如Red Hat.Debian.SUSE等,这些都称为Linux的分发版.一个典型的分发版,是由Linux内核, ...

  5. 新旧政府采购评审办法差异点汇总

    财库(2016)198号的<政府采购评审专家管理办法>已于11月18日发布,2017年1月1日起实施,同时2003年第119号的管理办法予以废止. 小编对新旧两版管理办法做了对比分析,从中 ...

  6. 新字符设备驱动实验(自动分配设备号、自动创建应用层设备节点、新字符设备注册到内核的结构体)

    目录 自动分配和释放设备号 示例代码 新的字符设备注册到内核方法 字符设备结构体(前面的设备号也放进来) cdev_init结构体初始化函数 cdev_add 添加到linux内核 cdev_del内 ...

  7. android 设备注册,Android平台上PMEM的使用及Platform设备注册(二)

    三.注册PMEM设备 这里我们除了描述PMEM设备,还将注册一个拥有memory空间和IRQ资源的示例设备example_device. 对于example_device,定义如下结构体: stati ...

  8. linux 内核 工作队列,Linux内核新旧工作队列机制的剖析和比较

    摘要:在中断驱动的程序设计中,工作队列是一种强有力的工具.但是在Linux2.6.35及其以前的内核版本中,每创建一个工作队列就创建与CPU数目相同的内核线程,耗费大量的内核资源:工作只能严格串行的处 ...

  9. 六、linux虚拟平台设备注册

    一.使用到的设备结构体 注册设备使用结构体platform_device,该结构体在头文件"viminclude/linux/platform_device.h"中.头文件中也有注 ...

最新文章

  1. MySQL解压版配置
  2. Redis 常用操作命令
  3. 公司要禁止QQ?【我们从协议开始分析】
  4. MDT部署中命令行脚本的使用。
  5. linux 硬盘转换gpt分区格式化吗,Linux下使用gpt给磁盘分区、格式化、挂载
  6. android 开源 数据库,Android开源数据库框架-LitePal的使用
  7. Solaris 中的环境变量
  8. 数据驱动测试之——CSV+TestNG
  9. expect脚本同步文件,expect脚本指定host和要同步的文件,构建文件分发系统,批量远程执行命令...
  10. 从Docker在Linux和Windows下的区别简单理解Docker的层次结构
  11. datagridview合并表头
  12. 安卓开关Switch使用的小细节
  13. VEH与SetUnhandledExceptionFilter
  14. osgearth加载倾斜摄影数据
  15. 2017-910-十一
  16. 计算机网络 5 - 链路层
  17. tf.unstack() 详解 —》理解为主
  18. 【综合练习1】彩虹枚举(红橙黄绿青蓝紫的英文)(>Red:红 >Orange:橙 >Yellow:黄 >Green:绿 >Blue:青 >Indigo:蓝 >Purple:紫)
  19. 程序员兼职接私活平台大全,兼职也能月薪上万
  20. 【学习日记】接口安全

热门文章

  1. 不带头节点的单链表如何头插(多图易懂)
  2. 替换空格---剑指Offer
  3. LC_ALL=C表示什么?
  4. 图论—割点zcmu2095
  5. 《微服务:从设计到部署》中文版
  6. 【译】Privacy and machine learning: two unexpected allies
  7. 用 Go 构建一个区块链 -- Part 3: 持久化和命令行接口
  8. Yum database disk image is malformed 错误
  9. 在数据库技术中脏数据是指_数据库安全关键技术之数据库加密技术
  10. JZOJ 5463. 【NOIP2017提高A组冲刺11.8】证书