BootLoader基础详解
PC机的启动流程:上电——>BIOS——>引导操作系统——>识别盘符(C、D盘)——>运行应用程序。同样在嵌入式系统中,启动流程也是类似的:上电——>bootloader——>运行内核——>挂载根文件系统——>运行运用程序。PC机上引导的操作系统是Windows,而嵌入式中基本上是Linux内核、VxWorks、ucOS、wince等。
BootLoader最终的目的:引导内核。嵌入式中内核基本上是存放在flash中的,所以要运行内核就需要从flash中读取内核,然后放到SDRAM中运行。这样BootLoader最基本的能力需要能读取flash、写SDRAM以及执行内核。BootLoader流程:
硬件相关的初始化:
- 设置模式(进入SVC)
- 初始化时钟(芯片刚上电的时候时钟都很低)
- 关闭中断(记住终极目的是引导内核、引导内核、引导内核。用不上的东西都需要关闭,别影响内核的引导)。
- 关闭看门狗(有些芯片看门狗默认是开启的,不喂狗隔一段时间芯片就会重启。而此时的任务是引导内核,重启要不得。)
- 初始化SDRAM,初始化flash(让flash可以读取数据)。
- 初始化串口(方便观察打印信息)、初始化网卡、USB等方便调试(可以通过USB来烧写内核、文件系统之类的)
- 设置栈(C运行必备的)
- 加载内核到SDRAM
- 运行内核
多阶段BootLoader的原因?
BootLoader终极目的是引导内核,加载内核到内存中然后再执行。具备更复杂的功能以及更好的可移植性的多阶段BootLoader。存在两个阶段:第一个阶段使用汇编来实现,它完成一些依赖于CPU体系结构的初始化,并调用第二阶段的代码(硬件设备串口、时钟、看门狗、中断、RAM等的初始化、进入管理模式、复制BootLoader的第二段代码到RAM空间中、设置栈、清除BSS段{主要初始化值为0的全局变量和静态变量,不放入程序中占用额外的内存}、运行第二阶段的代码start_armboot);第二阶段则是使用C语言来实现,目的是可以实现更为复杂的功能以及提高可读性、移植性(本阶段使用到的硬件设备如网卡、nand、USB等硬件设备的初始化、检测系统内存映射以确定内存大小以及地址空间、将内核映像和根文件系统映像从flash中读到RAM中间中、为内核设置启动参数、执行内核)。
对于第二阶段中的读取flash上的镜像放到内存空间上,从什么地址读取,放到内核的什么地方,以及如何调用内核、内核执行需要满足什么条件?
由于内核镜像是烧写在flash中的固定位置,所以读取的时候也是从烧写进去的位置开始读取。通常的做法是给flash划分分区,存在在分区中,然后再从分区中读取出来。而要放入的地址,如果镜像是uImage原则上是除了不破坏u-boot的内存分布是可以随意放置的。因为uImage包含64字节的头部和Image,头部信息中会存有内核的加载地址以及入口地址(加载地址是:把Image放到内存中的地址,而入口地址是内核的执行起始地址。这两个地址都是在编译内核的时候确定的),如果u-boot发现了内核放在内存中的地址和uImage头部中的加载地址不一致的话,就会把Image移动到加载地址的地方。最后再调用Image的执行地址执行内核。要是镜像是Image,也可以加载到不破坏u-boot内存分布的内存中,然后在执行加载地址处的程序。
内核执行要满足的条件:由于BootLoader加载内核后,就进入了内核程序,BootLoader里面的程序再也看不到了,所有需要把内核需要的参数(比如根文件系统存放在什么地方,是什么格式的以及内核起来后执行的第一个程序)传递给内核。通常的方法是在内存中指定一块空间,然后按照一定的格式把参数保存在里面,最后把参数的地址告诉内核。内核运行时需要访问些硬件资源,需要进入特权模式(SVC)。内核支持众多的CPU以及ARCH,所以还需要把机器ID告诉内核。最后还需要把第一个传给内核的参数设置为0。
这里分析下第二个阶段的流程。第二阶段是从start_armboot()开始,里面主要是初始化flash,和各种初始化(CPU、board、中断、环境变量等)———>然后调用main_loop(此函数里面主要执行getenv()获取环境变量,在调用run_command()执行相应的函数。在获取bootcmd环境变量后,里面有内核程序的执行地址)。———>最后执行getenv(bootcmd),然后调用run_conmand()执行获取到的bootcmd环境变量值,执行do_bootm()函数里面的在这个函数里面有把从uImage头部中解析出来的内核入口地址转化为函数指针,调用一些列的宏把bootargs里面的参数保存在内存中,最后调用函数指针执行内核(由于BootLoader是单机,执行这个之后再也不会回来了,所以需要把内核启动时的一些参数传递给内核。参数R0:0,R1:设置为机器码,R2:设置为BootLoader给内核传递参数的内存地址)。
u-boot中执行指令时,是根据name来匹配找到相应的函数,所有的指令都是通过下面的封装来实现的。
这个 U_BOOT_CMD的宏定义了一个cmd_tbl_t带有属性的变量,里面存放有指令的名字,指令的最大参数个数以及是否可以重复执行、还有处理函数以及帮助信息等。
在开发时,通常需要使用各种命令操作BootLoader,一般是通过串口连接PC和开发板。可以在串口上输入各种命令以及观察运行结果等。这个对开发人员有帮助。而平常客户使用时压根不需要操作BootLoader。所以从这个观点来看,bootloader分为以下两种模式:启动加载模式(客户使用)和下载模式(开发人员使用)。下载模式中主要有串口协议xmodem/ymodem/zmodem、网络协议TFTP以及nsf。
BootLoader中常用的有u-boot、vivi、redboot等。u-boot源码获取:http://sourceforge.net/projects/U-Boot。
u-boot(universal boot loader)中代码的结构主要有:
平台相关:cpu/ lib_arm/ 里面存放这各种架构的CPU代码以及lib库。
开发板相关:board/ 里面存放着各种板级相关的代码。
通用函数:include、lib_generic、common。include中存放头文件以及开发板的配置文件。开发板的配置文件都存放在include/configs中。需要手动修改配置文件中的宏定义。
其它通用部分:disk(硬盘接口程序)、drivers(各类具体设备的驱动程序)、dtt(数字温度测量器驱动)、fs(文件系统)、net(各种网络协议)、post(上电自检程序)、RTC(实时时钟驱动)、nand_spl(nand启动)
工具、示例、文档:tools(mkimage制作镜像的工具)、doc(文档)、example(示例程序)。
u-boot操作流程:
在u-boot1.1.6版本中,需要先配置u-boot,使用make xxx_config进行配置,配置好了再make进行编译。配置的时候执行Makefile文件中的:。,$0 -$6 分别是配置目标名、arm arm920t smdk2400 null s3c24x0。这个文件的主要目的是根据传进来的参数在include文件夹中建立asm、asm-$2/arch、asm-$2/proc连接,以及生成config.mk(里面存在着ARCH(arm) CPU(arm920t) BOARD(smdk2400) VENDOR(null) SOC(s3c24x0)等)和config.h文件。
编译时会使用配置生成的文件来选择CROSS_COMPILE,然后把相关的库文件都加入到LIBS中,链接标志为,链接脚本为(顶级config.mk中的指定)u-boot.lds。链接地址为:是在相关的板子里面的config.mk中定义的。
u-boot1.1.6中没有类似内核的图形化界面配置,所以配置u-boot的时候是通过make <board_name>_config命令来配置的,<board_name>是在目录board/中定义的,里面存放有编译链接脚本以及链接时正文段的地址(保存在config.mk中)。然后在执行make 或者是make all来编译生成u-boot.bin、u-boot等文件,在编译成功后会在tools目录中生成一些工具如(mkimage,编译内核是可以使用上,用mkimage来生成u-boot格式的内核镜像文件uImage)。
配置u-boot的时候首先调会用顶层目录下的mkconfig文件,mkconfig的作用是:①:确定开发板名称BOARD_NAME②:创建到平台/开发板相关的头文件的链接。③:创建include/config.mk文件,这个文件里面主要包含开发板所使用的ARCH CPU BOARD SOC。make编译的时候会根据这个来确定编译链以及库文件等。④创建开发板的头文件include/config.h,里面的内容是#include<configs/$1.h>,这里选择编译开发板的配置文件。里面存放开发板的一些配置,如CONFG_前缀是选择项,即是否使用,还有CFG_的前缀是参数的设置,编译的时候几乎所有的文件都会被编译和链接,但是文件是否包含有效的代码则有这些宏开关来设置。
配置完成后,执行make all进行编译。此过程如下:首先把配置生成的include/config.mk文件包含进来(即使用的ARCH CPU BOARD SOC)——>再包含顶层目录中的config.mk文件,此文件会根据配置生成的config.mk文件的值确定编译器、编译选项以及BOARDDIR等。
BootLoader基础详解相关推荐
- 主线剧情03-NXP-i.MX系列的u-boot移植基础详解
u-boot 移植基础详解 本文系广泛撷取.借鉴和整理(相关的内容在网络上有很多,但很多相互抄,或者是版本太老,或者就是不通用的非常有平台针对性的步骤,碎片化泛滥,甚至就是有待分拣的垃圾厂,当然也有一 ...
- c 语言中 %是什么运算符,C 语言基础----详解C中的运算符
C语言中又有哪些运算符呢? 如下所示: ※ 算术运算符 ※ 赋值运算符 ※ 关系运算符 ※ 逻辑运算符 ※ 三目运算符 C语言基本算术运算符如下表: 除法运算中注意: 如果相除的两个数都是整数的话,则 ...
- Python学习二:词典基础详解
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...
- 【云原生之k8s】k8s基础详解
[云原生之k8s]k8s基础详解 前言 一.kubernetes介绍 (1)kubernetes简介 (2)应用部署方式的演变 二.kubernetes组件 (1)kubernetes架构 (2)ma ...
- 微信小程序详解 php,微信小程序canvas基础详解
canvas 元素用于在网页上绘制图形.HTML5 的 canvas 元素使用 JavaScript 在网页上绘制2D图像.本文主要和大家分享微信小程序canvas基础详解,希望能帮助到大家. 一.了 ...
- 线程状态,优先级,守护线程基础详解
线程状态,优先级,守护线程基础详解 线程状态 停止线程 线程休眠 线程礼让 线程强制执行 线程状态检测 线程的优先级 守护线程 线程同步 线程状态 创建状态(new 之后就是创建状态 就绪状态(调用s ...
- 03 html基础详解
02html基础详解 文章目录 02html基础详解 1.HTML编辑器 2.标签 html常用标签 3.元素 4.属性 常用属性 5.标题 水平线 注释 6.段落 折行 7.格式化标签 属性dir ...
- 视频教程-FPS游戏逆向与安全+UE4引擎基础详解-其他
FPS游戏逆向与安全+UE4引擎基础详解 想把自己的知识传播出去,让更多人学习到 苏瑞兵 ¥188.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅课程,领取 ...
- linux网络服务详解,Linux网络服务器配置基础详解 (3)
Linux网络服务器配置基础详解 (3) Linux网络服务器配置基础详解 (3) 第三步:编辑"inetd.conf"文件(vi /etc/inetd.conf),禁止所有不需要 ...
最新文章
- 微信小程序把繁琐的判断用Js简单的解决
- Silverlight 2 Beta 1, IE 8 Beta 1, ASP.NET MVC 预览版2 可以下载了 - 思归呓语 - 博客堂
- COM中的IDL语言的难点之接口指针
- 问题和任务包003.使用报告.数据可视化.PowerBI.微软的新武器
- jvm性能调优实战 - 39一次大促导致的内存泄漏和Full GC优化
- sql like 多条件
- Linux ln指令
- 使用批处理查看.class文件内容--javap指令
- pythonplc曲线_PLC的编程策略:面向对象编程和梯形图逻辑之比较
- mysql group set,Mysql--group_concat()、group by、find_in_set()使用笔记
- html 空行_一篇文章学习html「经典案例」
- C# 在PowerPoint中给图片添加超链接和获取图片的超链接
- 同程容器云平台网络方案演进
- IT大学生成长周报 | 第 8 期
- 酸性溶液中HER动力学分析
- Micheal Nielsen's神经网络学习之二
- 淘管家一键铺货怎么弄?和分销下单有什么区别?
- 如何理解工程测量中的各种误差
- linux C -- ftok函数
- JavaScript高级编程设计(第三版)——第四章:变量作用域和内存问题
热门文章
- 用NI的数据采集卡实现简单电子测试之6——数字I/O及测试平台
- 数据库系列之SequoiaDB高可用集群部署(二)
- html字体兼容ie8,IE8 CSS 样式兼容性清单
- Meshgrid函数的基本用法
- layui表单验证不生效
- android动态主题下载,安卓动态壁纸(com.androidesk.livewallpaper) - 4.2.3 - 应用 - 酷安
- 我与机器斗争过但失败了:与深蓝“人机大战”20年,卡斯帕罗夫TED演讲
- 斥资16亿,湖北襄阳华侨城奇幻度假区“奇妙镇”正式迎客
- python 数据可视化- 地图
- 【Kevin Learn 小程序】--> dialog