//最开始的定义为
DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
.smp = smp_ops(imx_smp_ops),
.map_io = imx6q_map_io,
.init_irq = imx6q_init_irq, //中断的板级初始化
.init_machine = imx6q_init_machine, //
.init_late = imx6q_init_late,
.dt_compat = imx6q_dt_compat, //比较得到设备树
MACHINE_END //后面函数都是在start_kernel中
setup_arch
setup_machine_fdt
DT_MACHINE_START //在这里定义一个machine描述符,编译的时候会放入.arch.info.init段中
MACHINE_END
of_flat_dt_match_machine //找到最合适的machine描述符
early_init_dt_scan_nodes //找到几个比较重要的节点
early_init_dt_scan_chosen //找到 chosen 节点,并将值放入boot_command_line中
early_init_dt_scan_root //扫描根节点,获取 {size,address}-cells信息,并保存在dt_root_size_cells和dt_root_addr_cells全局变量中
early_init_dt_scan_memory //扫描DTB中的 memory node,并把相关信息保存在meminfo中,全局变量meminfo保存了系统内存相关的信息
paging_init(mdesc) //
devicemaps_init(mdesc)
mdesc->map_io //这里就是调用了DT_MACHINE_START中的imx6q_map_io unflatten_device_tree //需要将DTB转换成节点是 device_node 的树状结构,也就是把所有节点保存在C代码中的device_node中
__unflatten_device_tree
fdt_magic //检查设备树magic
fdt_totalsize //检测大小
fdt_version //检测版本
fdt_check_header //检测头
unflatten_dt_node //第一轮的scan,主要目的是为了获取设备树的大小
dt_alloc //将获取的大小在内存中申请一段内存(device_node数量的大小)
unflatten_dt_node //第二轮scan,将设备树中所有信息挂在上一步申请内存中(以结构体device_node为链表)
arm_dt_init_cpu_maps //获取cpu的节点 init_IRQ
machine_desc->init_irq() //这里也就是上面DT_MACHINE_START中的 imx6q_init_irq
imx_gpc_check_dt
irqchip_init
of_irq_init //遍历Device Tree,找到interrupt controller,并挂在intc_desc,然后系统开始匹配中断,一旦匹配上,进行中断初始化 time_init //时钟初始化,非常重要,在这里面对各种时钟倍频,分频操作
of_clk_init
matches = &__clk_of_table; //__clk_of_table就是保存clk结构体的内存,拿到后依次运行,我们在文件中定义了CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init); rest_init
kernel_init
kernel_init_freeable
do_basic_setup
driver_init
of_core_init
for_each_of_allnodes //从根节点轮训所有节点
__of_attach_node_sysfs //sys/firmware/devicetree/base目录下面为设备树展开成sysfs的目录和二进制属性文件,所有的node节点就是一个目录,所有的property属性就是一个二进制属性文件。 do_initcalls
while(~) //会依次初始化0~7,其中3是架构,6是设备
do_initcall_level() //在代码中有arch_initcall(customize_machine)
customize_machine
machine_desc->init_machine() //这里就是DT_MACHINE_START定义的imx6q_init_machine
of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); //加载platform设备
for_each_child_of_node //轮训根节点
of_platform_bus_create //创建platform总线, 这里会把i2c adapter之类的设备进行了初始化
imx6q_enet_init
imx_anatop_init
imx6q_csi_mux_init
imx6q_pm_init //电源管理初始化
imx6q_axi_init do_initcall_level() //在代码中的device_initcall/module_init/device_initcall都是这个等级的,为设备驱动
do_initcall_level() //最低优先级的,late_initcall为这个等级,其中有late_initcall(init_machine_late)
init_machine_late
machine_desc->init_late() //这里就是DT_MACHINE_START定义的 init_late
try_to_run_init_process("/sbin/init")//尝试运行sbin/init
try_to_run_init_process("/etc/init")
try_to_run_init_process("/bin/init")
try_to_run_init_process("/bin/sh")
kthreadd 从上面流程可以看出chosen、memory、cpus节点未挂在device_node上

imx6的kernel3.4.15启动流程的更多相关文章

  1. Linux启动流程与模块管理(15)

    系统的启动其实是一项非常复杂的过程,因为内核得要检测硬件并加载适当的驱动程序,接下来则必须要调用程序来准备好系统运行的环境,以让用户能够顺利的操作整台主机系统,如果你能够理解系统启动的原理,那么将有助 ...

  2. imx6 uboot启动流程分析

    参考http://blog.csdn.net/skyflying2012/article/details/25804209 这里以imx6平台为例,分析uboot启动流程对于任何程序,入口函数是在链接 ...

  3. CentOS6 启动流程图文解剖

    我们在使用Linux操作系统的时候,我们只需按下电源键,等待,然后输入账户和密码就可以使用Linux操作系统了.那么在按下电源到输入账号和密码之前,操作系统都做了些什么?下面就来讲述在这段时间发生的动 ...

  4. u-boot启动流程分析(2)_板级(board)部分

    转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global dat ...

  5. 第二十章、启动流程、模块管理与 Loader grub

    Boot Loader: Grub 『 boot loader 是加载核心的重要工具』!没有 boot loader 的话,那么 kernel 根本就没有办法被系统加载! boot loader 的两 ...

  6. 转:AM335x启动流程(BootRom->MLO->Uboot)

    http://blog.chinaunix.net/uid-28458801-id-3486399.html 参考文件: 1,AM335x ARM Cortex-A8 Microprocessors ...

  7. Linux的启动流程以及GRUB详解

     一.Linux引导和启动流程       概述,计算机电源接通后通过BISO之后,没有问题,就会去硬盘上找到MBR(Main Boot Record 主引导记录区)位于整个硬盘的0磁道0柱面1扇区, ...

  8. Android系统开机启动流程及init进程浅析

    Android系统启动概述 Android系统开机流程基于Linux系统,总体可分为三个阶段: Boot Loader引导程序启动Linux内核启动Android系统启动,Launcher/app启动 ...

  9. 【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42462795 转载请著名出处 相关资源下载 :  -- u-boo ...

随机推荐

  1. [LeetCode 题解] Search in Rotated Sorted Array

    前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 题目描述 Suppose an array ...

  2. netcore配置文件与发布

    这段时间好几次想写博客,但是却发现无法编辑,至今都不行 CuteEditor TinyMCE(推荐) 以上两种都不行,只好更改默认编辑器为textbox. 一直以为被封了还是怎么滴,原来是突然不支持c ...

  3. windows服务器让WEB通过防火墙的问题

    服务器环境:windows server 2012 X64WEB服务器:IIS开放8080,PHPSduty开放80 如果关闭防火墙的情况下,不论是IIS还是安装的其他的WEB服务器,都可以正常访问. ...

  4. C#使用MongoDb来存储文件

    近期在写一个小玩意,需要保存一些图片,以前我采用的是FTP或者直接数据库保存文件,用FTP来保存文件感觉比较麻烦,用数据库吧,还要改字段类型,修改代码,修改查询语句,懒得改. 以前看过mongonDb ...

  5. mysql恢复备份错误:Got a packet bigger than 'max_allowed_packet' bytes

    最近恢复mysql数据库备份时,出现了一个错误:Got a packet bigger than 'max_allowed_packet' bytes 该问题主要是由于mysql的my.ini文件中设 ...

  6. js form 表单 重置 清空

    清空 和 重置的差异是 清空是彻底清空input内容即便初始值value有值,重置是将input内容重置为value初始状态 很简单记录下 方便之后使用 //重置 //document.getElem ...

  7. C++中将二维数组(静态的和动态的)作为函数的参数传递

    在C++编程中,我们经常将数组作为参数传递到另一个函数,数组的维数不同,传递方式也不同,此处将作一个总结,包括一维静态.动态数组,二维静态.动态数组. 一,一维数组(静态.动态一维数组) 1, 一维数 ...

  8. Flask从入门到精通之Flask表单

    Flask请求对象包含客户端发出的所有请求信息.其中,request.form 能获取POST 请求中提交的表单数据.尽管Flask 的请求对象提供的信息足够用于处理Web 表单,但有些任务很单调,而 ...

  9. 【wepy实战】wepy搭建完整项目

    使用小程序框架wepy,搭建完整实战项目.文章将从项目结构.配置.模块等进行逐步分析和学习. 文章适合小程序开发新手以及有经验的小程序developer,不喜勿喷,不吝赐教! 本文为作者原创,转发请标 ...

  10. Alamofire源码导读三:返回的处理逻辑

     以DataRequest 为例子. 最简单的返回 URLSession 有一个方法,可以构建 URLSessionDataTask func dataTask(with url: URL, com ...