转自: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. webrtc编译之libcommonaudio

    [170/1600] CXX obj/webrtc/common_audio/common_audio.audio_util.o[171/1600] CXX obj/webrtc/common_aud ...

  2. c 函数及指针学习 3

    strlen(x) 返回 size_t 类型,size_t是 unsigned int 类型,所以 strlen(x)-strlen(y) 返回 unsigned int 始终 >=0 1 2 ...

  3. JS初学之-for套for遍历二维数组

    <!doctype html><html><head><meta charset="utf-8"><title>无标题文 ...

  4. Blob 构造函数

    Blob 构造函数使 Web 开发人员可直接在客户端上创建或操作 Blob(经常等效于一个文件). 该构造函数在 W3C 的文件 API 规范中进行定义,该规范目前尚处于工作草案阶段.在较早版本的文件 ...

  5. UVa 400

    一开始没怎么看懂题目,原来就是M字符就是这一列的宽度为M个字符,包括空格. #include<iostream> #include<algorithm> #include< ...

  6. leetcode 138. Copy List with Random Pointer ----- java

    A linked list is given such that each node contains an additional random pointer which could point t ...

  7. JAVA常用系统函数

    1.System.out.println("显示信息"); // 显示内容,并自动换行 2.Syetem.out.print("显示信息"); // 显示内容, ...

  8. poj2762 强连通+拓扑序

    题意:有 n 个房间,不同房间之间有单向通道,问是否任意两个房间 A .B 都可以从 A 到 B 或从 B 到 A(有一条有就可以). 在这题中,如果一些点是在同一个强连通分量中,那么这些点肯定能够相 ...

  9. Java 性能优化

    http://eclipsesource.com/blogs/2013/01/21/10-tips-for-using-the-eclipse-memory-analyzer/ http://docs ...

  10. $.browser.msie 报错 null

    jQuery 1.9 移除了 $.browser 的替代方法 January 16th, 2013FwolfLeave a commentGo to comments 授权方式:署名,非商业用途,保持 ...