U-boot第二阶段概述(转)
一、U-boot第二阶段概述
上面有两篇文关于u-boot第一阶段的介绍,这两篇文章是从网上找到的,由于分析的很详细,看完这后觉得对这两篇文章u-boot第一阶段的介绍已经比较完美了,所以分享出来。从这篇文章开始分析u-boot的第二阶段。
如果你只把u-boot理解成引导kernel的一段代码的话,u-boot完全没有必要设计成现在这样的一种软件框架,直接写几个文件就能完成kernel的引导和启动。U-boot的功能很大一部还有起到调试的作用,也就是u-boot命令行的部分。所以它才有了现在这种相对比较复杂的框架。U-boot的第二阶段可以认为是初始化u-boot的软件框架,并实现引导kernel启动和命令行调试环境的过程
U-boot第二阶段总结来说主要可以概括为下面几点
1、硬件的初始化
2、运行环境的初始化
3、载入内核并启动内核
4、运行u-boot调试的命令机制
其中1和2阶段可以看成是u-boot软件框架的初始化过程,只不过包括了硬件设备的初始化和软件相关结构体的初始化。而3就是引导kernel启动过程,而4是调试的命令行环境运行过程。
本文首先沿着第一阶段调用_start_armboot函数开始第二阶段的分析。首先完成一个概述,之后会对一些关键的问题做专题分析。
二、硬件和软件框架的初始化
首先初始化一个全局性的数据结构gd_t
/* Pointer is writable since we allocated a register for it */ |
我们看到这里u-boot动态的分配了gd_t和bd_t这两个数据结构,只是比较疑惑的是这两个数据结构完全可以定义成全局的数据,何必这样动态的分配呢?由于这个时候完全没有malloc这样的环境,u-boot只好跑马圈地,很野蛮的在_armboot_start前面画出一块位置作为上面结构体区域。这里我们就两个疑问?1、u-boot到底被第一阶段的代码拷贝到什么地方去执行了?第二个疑问就是u-boot在内存区域中相关代码和数据区域是怎么分布的?
Question1:
Answer:
查看一下下面的配置文件就可以知道,mini2440开发板sdram的地址范围是3000’0000到3400’0000,一共是64M。U-boot首先把自己载入了最后的512K的地址空间中,坐在墙角的位置。
u-boot-1.1.6\board\open24x0\config.mk
#
# SMDK2410 has 1 bank of 64 MB DRAM
#
# 3000'0000 to 3400'0000
#
# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
# optionally with a ramdisk at 3080'0000
#
# we load ourself to 33F8'0000
#
# download area is 3300'0000
#
TEXT_BASE = 0x33F80000
Question2:
Answer:
U-boot被完全载入到内存后,各部分在内存中的位置如下图所示:
需要注意的是图中TEXT_BASE的地址在整个SDRAM空间的最后512K位置了。
初始化函数调用
接着u-boot对单板的硬件和软件框架做相应的初始化
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) |
U-boot软件框架定义了这样的一个初始化表,不同的单板具体实现下面的函数进行相应的初始化动作
init_fnc_t *init_sequence[] = |
后续的文章会将上面的初始化函数做逐一的分析,但是本篇本意是想对第二阶段的处理过程做一个提纲挈领的描述,所以暂时举一个例子分析如下:
int cpu_init (void) |
Cpu_init函数基本上就是初始化了一下栈区空间和软件中断的栈空间
在完成了单板相应硬件初始化之后,u-boot在后继的代码里可以自由的使用u-boot框架提供的一些服务接口,比如从串口获取输入,从nandflash读写数据,网络接口通信等等。然后u-boot进入了一个大的循环中
for (;;) |
在main_loop函数中,有两条比较关键的路径需要分析,一条路径就是引导内核启动,另外一条路径就是用户通过串口输入中断了u-boot启动内核过程而进入了u-boot的命令行调试运行环境中。
三、u-boot引导内核启动的过程。
首先我们来分析一下u-boot引导内核启动的过程
1、首先获取等待用户串口按键中断引导kernel的时间,一般为3秒
s = getenv ("bootdelay"); |
2、获取启动内核的命令,这个靠编译u-boot之前开发者的配置
s = getenv ("bootcmd"); |
而这条启动命令在mini2440的配置就是如下,其实是两条命令组成的
#define CONFIG_BOOTCOMMAND "nand read.jffs2 0x32000000 kernel; bootm 0x32000000"
3、调用abortboot函数检查在等待的3s中内是不是从串口有用户输入了空格,如果有就说明用户想进入命令行调试模式,如果没有就说明可以开始运行启动内核的命令。
if (bootdelay >= 0 && s && !abortboot (bootdelay)) |
4、abortboot中比较关键的代码就是在一个循环中不断检测是不是有用户的串口输入,使用了一个udelay函数,10000us等于10ms,循环100次就是1s
while ((bootdelay > 0) && (!abort)) |
5、用户不中断kernel引导过程的话,最后会调用到run_command函数,这个函数不需要怎么分析,它的作用就就是解析输入的命令,然后根据命令的名字查找相应的命令执行函数进行调用,上面我们看到,启动的时候需要调用两个命令,一个是nand命令一个bootm命令。
6、Nand命令完成将kernel载入到内存中指定的位置,而bootm则是最后调用固定位置的一个kernel启动函数进入kernel的代码中开始执行。
7、执行nand命令,u-boot在其软件框架中定义了一个命令nand如下所示,执行这个命令最后会调用到函数do_nand
U_BOOT_CMD(nand, 5, 1, do_nand, |
这里也没有必要去深入探究do_nand的作用,它完成的工作就是将kernel从nandflash中准确的载入到内存指定的位置。
当nand命令将kernel读入到内存后,接着执行bootm命令,最后执行linux内核的code
U_BOOT_CMD( |
这个命令的执行最后会调用到do_bootm函数
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
最后调用do_linux_bootm完成内核启动,这个函数主要做三个工作,首先是拷贝inird到确定位置,然后初始化内核参数到确定的位置,最后调用内核的启动函数,并传递两个参数给内核一个是cpu number,一个是内核参数位置。
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], |
四、U-boot命令行调试状态
上面是对u-boot载入引导kernel的分析。如果用户通过串口打断引导过程,或者引导过程失败了,就会进入u-boot命令行调试状态。U-boot进入一个无限的for循环等待用户从串口输入命令,找到匹配的命令后执行相应的操作。
for (;;) |
转载于:https://www.cnblogs.com/dayuhope/p/3283062.html
U-boot第二阶段概述(转)相关推荐
- 自学前后端分离1 Spring Boot+Vue概述
一,前后端分离. 前后端分离时将一个应用的前端代码和后端代码分开写,如果不用前后端分离传统的JavaWeb开发中前端使用JSP开发,JSP不是由后端开发者来独立完成的前端--〉html静态页面---- ...
- 高通8155/8295 boot分析
目录 前言 通用boot流程 8155/8295 boot流程概述 前言 本文将基于高通8155/8295 Q+A hypervisor平台分析整个boot的启动流程.高通其他SOC芯片的启动流程大致 ...
- Spring、Spring MVC、Spring Boot三者的关系还傻傻分不清楚?
点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 在本文中,你将获取到有关于Spring,Spring MVC和Spring Boot的概述, ...
- 让你的spring-boot应用日志随心所欲--spring boot日志深入分析
1.spring boot日志概述 spring boot使用Commons Logging作为内部的日志系统,并且给Java Util Logging,Log4J2以及Logback都提供了默认的配 ...
- Kafka 入门和 Spring Boot 集成
2019独角兽企业重金招聘Python工程师标准>>> Kafka 入门和 Spring Boot 集成 概述 kafka 是一个高性能的消息队列,也是一个分布式流处理平台(这里的流 ...
- Spring Boot基础学习笔记02:Spring Boot项目单元测试、热部署与原理分析
文章目录 零.学习目标 1.掌握Spring Boot单元测试实现 2.掌握Spring Boot热部署实现 3.熟悉Spring Boot基本原理 一.Spring Boot单元测试 (一)Spri ...
- Spring Boot基础学习笔记01:Spring Boot入门程序
文章目录 零.学习目标 1.了解Spring Boot框架的优点 2.掌握使用Maven方式构建Spring Boot项目 3.掌握使用Spring Initializr方式构建Spring Boot ...
- Spring Boot、Spring MVC、Spring:它们有什么区别?
在本文中,您将获得Spring,Spring MVC和Spring Boot的概述,了解它们可以解决什么问题以及在哪里最好地应用它们.您将学到的最重要的事情是,Spring,Spring MVC和Sp ...
- u-boot懂你并不难
转载:http://blog.chinaunix.net/uid-28236237-id-3865045.html u-boot第一阶段分析(一) u-boot 第一阶段分析(二) u-boot 第二 ...
- 第4章 JSP语法、内置对象
第4章 JSP语法.内置对象 关于Spring Boot+Vue全栈开发实战(三方面)前端 全栈 Spring Boot JSP概述 4.1.1 什么是JSP(Java Server Page) 4. ...
最新文章
- Repeater分页代码
- 高效排序算法(快排序)
- node.js require()缓存-可能无效?
- 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统(瘋耔修改篇二)...
- Matlab Robotic Toolbox V9.10工具箱(四):常用函数
- 派生类的构造【C++继承】
- Mars 如何分布式地执行
- 两台邮件服务器共用一个公网地址,两个不同域邮件服务器的互通
- php集中管理,PHPWind 7.5 SP2 公布 三大改良增强营运基本功能
- 大数据分析平台有哪些功能
- Programmer Competency Matrix
- 阿里UX矢量图标库–最强大的矢量图标库(Icon font制作力荐工具)
- 安装SQL Server2012
- 计算机专业术语大全(中~英文版)
- c语言补偿算法,C功能刀具半径补偿算法与实现.doc
- 简单总结协程Coroutine及Yield常见用法
- 【C语言基础练习】100匹马驮100担货,大马一匹驮3担,中马一匹驮2担,小马两匹驮1担。试编写程序计算大、中、小马的数目。
- goldendict使用 添加 .blg 添加字典
- VVIC api接口 Alex19970108016
- An internal routine has requested a dump of selected redo.This usually happens following a specific