转自: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设备注册对比的更多相关文章

  1. Linux 内核 struct device 设备

    在最低层, Linux 系统中的每个设备由一个 struct device 代表: struct device { struct device *parent; struct kobject kobj ...

  2. 驱动开发学习笔记. 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 ...

  3. 驱动开发学习笔记. 0.04 linux 2.6 platform device register 平台设备注册 1/2 共2篇

    驱动开发读书笔记. 0.04  linux 2.6 platform device register 平台设备注册  1/2 共2篇下面这段摘自 linux源码里面的文档 : Documentatio ...

  4. 由MTK平台 mtkfb 设备注册疑问引发的知识延伸--ARM Device Tree

    问题: 在kernel-3.10\drivers\misc\mediatek\videox\mt6735\mtkfb.c里面int __init mtkfb_init(void) 有看到 platfo ...

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

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

  6. 深入理解linux网络技术内幕读书笔记(八)--设备注册与初始化

    Table of Contents 1 设备注册之时 2 设备除名之时 3 分配net_device结构 4 NIC注册和除名架构 4.1 注册 4.2 除名 5 设备初始化 6 设备类型初始化: x ...

  7. [11]Windows内核情景分析---设备驱动

    设备驱动 设备栈:从上层到下层的顺序依次是:过滤设备.类设备.过滤设备.小端口设备[过.类.过滤.小端口] 驱动栈:因设备堆栈原因而建立起来的一种堆栈 老式驱动:指不提供AddDevice的驱动,又叫 ...

  8. RT-thread内核之IO设备管理系统

    RT-Thread系统的IO设备管理模块为上层应用提供了一个对设备进行访问的通用抽象接口,而对于下层设备来说则提供了底层设备驱动框架,并通过定义的数据结构对设备信息和底层设备驱动进行管理.从系统整体位 ...

  9. 如何删除 Ubuntu 上不再使用的旧内核

    提问:过去我已经在我的Ubuntu上升级了几次内核.现在我想要删除这些旧的内核镜像来节省我的磁盘空间.如何用最简单的方法删除Ubuntu上先前版本的内核? 在Ubuntu上,有几个方法来升级内核.在U ...

随机推荐

  1. CentOS7上安装和使用Docker

    导读 Docker 是一个开源工具,它可以让创建和管理 Linux 容器变得简单,容器就像是轻量级的虚拟机,并且可以以毫秒级的速度来启动或停止.在本篇文章中我们将教你如何在 CentOS 7.x 中安 ...

  2. 转载:LBP的初步理解

    转自http://blog.csdn.net/ty101/article/details/8905394 本文的PDF版本,以及涉及到的所有文献和代码可以到下列地址下载: 1.PDF版本以及文献:ht ...

  3. 2015GitWebRTC编译实录3

    2015.05.17 librtprtcp 编译通过[702/1600 ] CXX obj /webrtc/modules/rtp_rtcp/source/rtp_rtcp.bitrate.o[703 ...

  4. hdu2546 饭卡    01背包

    link:http://acm.hdu.edu.cn/showproblem.php?pid=2546 也算一个贪心的想法吧. 先把总钱数减去5,再把价值最大的挑出来.然后用01背包.最终买下挑出来的 ...

  5. makefile--目录搜索(八)

    在一个较大的工程中,一般会将源代码和二进制文件(.o 文件和可执行文件)安排在不同的目录来进行区分管理.这种情况下,我们可以使用 make 提供的目录搜索依赖文件功能(在指定的若干个目录下自动搜索依赖 ...

  6. mysql之数据库连接的方法封装及防sql注入

    一.定义数据库和表 create database animal; CREATE TABLE `pet` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `name ...

  7. mysql启动错误与修复

    昨天想着备份数据库,但是没有成功,错误原因是#Got errno 28 on write 查到是因为磁盘空间不足或者mysql设置中max_allowed_packet变量设置过小 在mysql命令行 ...

  8. NOI 2004 郁闷的出纳员(平衡树)

    题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...

  9. 【NOI2015】软件包管理器

    NOI难得的水题,话说还是T2诶……又学到了线段树的一种新的魔性使用 看sxysxy大神的代码才写出来的,sxysxy_orz 原题: Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包 ...

  10. Linux驱动设计—— 驱动调试技术

    参考博客与书籍: <Linux设备驱动开发详解> <Linux设备驱动程序> http://blog.chinaunix.net/uid-24219701-id-2884942 ...