历史上的今天
返回首页

历史上的今天

今天是:2025年02月23日(星期日)

正在发生

2021年02月23日 | cortex-a8 uboot系列:第十一章 uboot源码分析 uboot如何启动内核1

2021-02-23 来源:eefocus

一、Uboot和内核到底是什么(从系统启动角度看)

1.Uboot

Uboot的本质是一个复杂的裸机程序。


2.内核

操作系统内核本身也是一个裸机程序,和uboot、其他裸机程序并没有什么本质区别。

但是和其他裸机程序的区别:操作系统运行起来后在软件上分为内核层和应用层,分层后两层的权限不同,内核访问和设备操作的管理上更加精细(内核可以随意访问各种硬件,而应用程序只能被限制的访问硬件和内存地址)。


Uboot的镜像是u-boot.bin,linux系统镜像是zImage,这两个文件都是两个裸机程序bin文件镜像。


二、SD卡中的分区

一个完整的软件+硬件的嵌入式系统,未上电时,bootloader、kernel、rootfs等必须的软件都以镜像的形式(.bin的形式),存储在启动介质中(x210是iNand/SD卡)。运行时,都是在DDR内存中运行,与存储介质无关。这两个状态都是稳定状态。


还有一个状态是动态过程,从静止态到运行态的过程,也就是启动过程。


动态启动过程就是从启动介质(以下以SD卡为例)逐步搬移到DDR内存,并且运行启动代码进行相关的硬件初始化和软件结构的建立,最终达到运行时稳定状态。


静止时u-boot.bin,zImage,rootfs都在SD卡中,他们不能随意存放在SD卡的任意位置,因此需要对SD卡进行一个分区,然后将各种镜像各自存在各自的分区中,这样在启动过程中就知道去什么位置查找uboot、内核等。(uboot和kernel中的分区表必须一致,同时和SD卡的实际使用的分区要一致)。


三、运行时必须要先加载到DDR中链接地址处

Uboot在第一阶段中进行重定位时将第二阶段(整个uboot镜像)加载到DDR的0xc3e00000地址处,这个地址就是uboot的链接地址。


内核也有类似要求,uboot启动内核时要将内存从SD卡读取放到DDR中(其实就是重定位的过程),不能随意放置,必须放在内核的链接地址处,否则不能启动内核。如使用的内核链接地址是0x30008000,那么uboot拷贝kernel代码时,就要将kernel拷贝到地址0x30008000的DDR中去。


四、内核启动需要必要的启动参数

Uboot是无条件启动的,从零开始启动。


内核是不能开机自动完全从零开始启动的,内核启动要别人帮忙。Uboot要帮助内核实现重定位(从SD卡到DDR),以及给内核提供必要的启动参数。如dram的起始地址以及大小,所用串口以及波特率,根文件系统位置等等。


uboot启动kernel时,会调用kernel的入口函数,此时要给kernel传递三个参数。这三个参数是固定的:

r0: 固定为0

r1: 机器码

r2: 启动参数在ddr中的位置


五、启动内核

uboot要启动内核,分为两个步骤:第一步是将内核镜像从启动介质中加载到DDR中,第二步是去DDR中启动内核镜像。(内核代码没有考虑重定位,因为内核知道会有一个bootloader将内核代码加载到DDR链接地址处,所以内核直接从链接地址处运行)


1.加载内核到DDR

静态内核镜像放在哪里?

有两种情况:

第一种:SD卡/iNand/Nand/Norflash等:raw分区

常规启动时各种镜像都在SD卡中,因此uboot只需要从SD卡的kernel分区读取内核镜像到DDR即可。


读取要使用uboot的命令来读取(x210的iNand版本是movi命令,x210的Nand版本就是Nand命令)

clip_image002

如读取kernel到内存0x30008000。

movi read kernel 0x30008000

这里的kernel指的是uboot中的kernel分区(就是uboot中规定的SD卡中的一个区域范围,这个区域范围被设计来存放kernel镜像,就是所谓的kernel分区)

 

第二种:tftp、nfs等网络下载方式从远端服务器获取镜像

uboot还支持远程启动,也就是内核镜像不烧录到开发板的SD卡中,而是放在主机的服务器中,然后需要启动时uboot通过网络从服务器中下载镜像到开发板的DDR中。


首先在主机上搭建tftp服务器,然后将要下载的文件拷贝到tftp设置的传输目录中。

clip_image004

开发板的uboot中,使用tftp命令将远程的文件通过网络下载下来。

clip_image005

tftp命令格式

tftp     DDR地址  远程下载的文件名

 

不管哪种方式,最终结果要的是内核镜像到DDR中特定地址即可,不管内核镜像是怎么到DDR中的。以上2种方式各有优劣。产品出厂时会设置为从SD卡中启动;tftp下载远程启动这种方式一般用来开发。

 

镜像要放在DDR的什么地址

内核一定要放在链接地址处。链接地址要去内核源代码的链接脚本或者makefile中去查找。X210中是0x30008000。


2.执行内核

uboot将kernel拷贝到DDR中kernel的链接地址处后,直接调用kernel的入口函数,即可启动内核。


uboot使用命令bootm来启动内核。


六、zImage和uImage的区别联系

1.bootm命令对应do_bootm函数(common/cmd_bootm.c)

clip_image007

CONFIG_SECURE_BOOT宏表示安全启动,对程序做了更安全的校验,对于一般应用,这个是不需要的。


CONFIG_ZIMAGE_BOOT宏很重要,这个宏控制条件编译支持zImage格式的内核启动的一段代码。


2.vmlinuz和zImage和uImage

uboot经过编译直接生成的elf格式的可执行程序是u-boot,这个程序是可执行,类似于windows下的exe格式,在linux下可直接执行。但是这种格式不能用来烧录下载。用来烧录下载的是u-boot.bin。这个是由u-boot使用arm-linux-objcopy工具来进行转化(主要是去掉无用的信息)。这个u-boot.bin就叫镜像(image),镜像就是用来烧录到启动介质中让CPU去取指执行的。


Linux内核经过编译后也会生成一个elf格式的可执行程序,叫vmlinux或vmlinuz,这个是原始的未经任何处理加工的原版内核elf文件。嵌入式系统部署时烧录的一般不是这个vmlinux/vmlinuz,而是要用objcopy工具去制作成烧录镜像格式(就是u-boot.bin这种,但是内核没有.bin后缀),制作出来的镜像文件就叫Image(这个镜像就比elf格式的文件要小很多)。


原则上Image就可以直接烧录到启动介质中,但是实际上linux的开发者认为Image的大小还是太大,所以对Image进行了压缩,并且在Image压缩后的文件的前端附加了一部分解压缩代码。构成了压缩格式的镜像就叫zImage。

clip_image009

Uboot为了启动linux内核,还发明了一种内核格式叫uImage,uImage是由zImag加工得到的,uboot中有一个工具,可以将zImage转换成uImage。注意:uImage不关linux内核的事,linux内核只管生成zImage即可,然后uboot中的mkimage工具再去由zImage转换成uImage来给uboot启动。这个转换过程其实就是在zImage的前面加上64字节的uImage的头信息即可。


原则上uboot启动时应该给他uImage格式的内核镜像,但是实际上uboot中也可以支持zImage启动,是否支持就看x210_sd.h中是否定义了CONFIG_ZIMAGE_BOOT这个宏。


这也就是,有些uboot支持zImage启动,有些则不支持。但是所有的uboot肯定都支持uImage启动。


对于mkimage工具,在uboot下的tools目录下,由clip_image011

上面这一段代码就是提供uboot的zImage启动。当判断镜像是zImage,对其进行校验,校验完后,直接跳转到after_header_check符号处,后面的其他镜像就不校验了。


LINUX_ZIMAGE_MAGIC是一个定义的魔数,这个数等于0x016f2818,表示这个镜像是一个zImage。也就是zImage格式的镜像中在头部的一个固定位置存放了这个数作为格式标记,如果有一个image,去这个位置读取4个字节的数据,判断是否为0x016f2818,是的话,说明是zImage,否则不是。


命令bootm 地址(0x30008000),所以do_bootm的argc=2,argv[0]=bootm,argv[1]=0x30008000。但是有argc小于2的情况,这个时候启动地址就是默认的地址,追寻,这个地址就是内存的基地址0x30000000。所以对于bootm命令,可以不带参数执行。不带参数,就默认为启动地址为0x30000000。


从镜像的37字节开始的4个字节数据读取出来,判断是否为0x016f2818,从而可以判断出这个镜像是不是zImage。

 

clip_image013

clip_image015

clip_image017

编译kernel时,


直接make, 生成zImage


make uImage, 生成uImage, 但是会用到mkimage工具,而这个工具在linux源码中是没有的,因此会直接报错。

clip_image019

需要将uboot的tools目录中的mkimage拷贝至$PATH的目录下,就可以了。

clip_image021

此时在make uImage,就会在arch/arm/boot目录下生成uImage文件了。

clip_image023

将该文件通过tftp下载带开发板的DDR,然后使用bootm命令运行。

clip_image025

黄色部分就是uboot解析uImage打印的信息。

推荐阅读

史海拾趣

Anytek Technology Corporation Ltd公司的发展小趣事

随着技术实力的不断提升和市场份额的稳步增长,Anytek在2009年获得了“中国国际高新技术企业”的认定。这一荣誉不仅是对公司技术实力和创新能力的肯定,也为公司的未来发展提供了更广阔的空间和机遇。同年,Anytek还成功进入了俄罗斯政府采购项目,进一步扩大了公司的国际影响力。

Comax Industrial Co Ltd公司的发展小趣事

为了不断提升自身的技术创新能力,Comax Industrial Co Ltd公司积极与高校、科研机构等开展产学研合作。通过与这些机构的紧密合作,公司不仅获得了前沿的技术支持,还培养了一批高素质的技术人才。这种合作模式使得公司的技术创新能力得到了显著提升,为公司的长期发展提供了有力的支撑。

Enterpoint公司的发展小趣事

作为一家有社会责任感的企业,Enterpoint公司始终关注可持续发展问题。他们积极推广绿色、环保的生产方式,减少对环境的影响。同时,公司还积极参与社会公益活动,通过捐赠物资、支持教育等方式回馈社会。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实的基础。

Caddock公司的发展小趣事

在追求经济效益的同时,Caddock公司也注重环保和可持续发展。公司积极推行绿色制造理念,通过优化生产工艺、降低能耗和减少废弃物排放等措施,实现了环保与经济效益的双赢。此外,公司还致力于研发环保型电阻材料和技术,为推动电子行业的绿色发展做出了积极贡献。

这些故事展示了Caddock公司在电子行业发展的不同阶段所取得的成就和面临的挑战。通过不断创新、拓展市场和注重可持续发展,Caddock公司逐渐成为了电子行业中的佼佼者。然而,这些故事仅为虚构创作,实际发展情况可能有所不同。如需了解更多关于Caddock公司的真实发展历程和故事,建议查阅相关官方资料或行业报告。

冠西电子(COSMO)公司的发展小趣事

冠西电子一直重视产品质量和客户服务,通过了国际标准化组织的ISO9001质量管理标准认证,以及各国的安规认证,如UL、TUV等。这些认证不仅证明了冠西电子产品的品质卓越,也为其赢得了更多国际客户的认可。此外,冠西电子还积极与国际知名企业开展合作,共同推动电子行业的发展。

Eurosil Electronics Ltd公司的发展小趣事

Eurosil Electronics Ltd公司成立于XXXX年,由一群热衷于电子科技研发的工程师创立。在成立初期,公司专注于半导体材料的研究与开发,致力于提高半导体的性能与稳定性。经过数年的努力,Eurosil成功研发出一种新型半导体材料,具有更低的能耗和更高的可靠性,这一技术突破为公司赢得了业界的广泛认可,也奠定了其在电子材料领域的重要地位。

问答坊 | AI 解惑

lpc1343的USB源码问题

在中断函数里面有一段 if (USB_P_EP[0]) {         USB_P_EP[0](USB_EVT_SETUP);         continue; } 原型在下面: #define P_EP(n) ((USB_EP_EV ...…

查看全部问答>

wince ADO数据连接问题

请问__Connection的Open函数参数怎么写? 数据库是SQL Server ce2.0 ,数据库名:test.sdf …

查看全部问答>

[急]再求推荐jtag接口的51单片机,谢谢

C8051F应该是可以,还有没有其它常用的?…

查看全部问答>

高压MOS/IGBT的短路保护电路

高压MOS/IGBT的短路保护电路     电源网讯 个人多年来从事高压脉冲电源的工作的一点经验总结   电路如上: 带短路保护锁定的驱动的3脚为短路信号检测入端;2脚为驱动地;1脚为驱动输出。 当电路存在短 ...…

查看全部问答>

关于单级PFC变压器的设计

单级PFC也分DCM和CCM两种,而且拓朴不同 1、频率是自己预设的,考虑到倍频,一般都是66k、132k等; 2、具体案例设计我传一个资料 内容如下 …

查看全部问答>

超炫的一款车视频哈哈哈简直牛到了极点

$(\'swf_k67\').innerHTML=AC_FL_RunContent(\'width\', \'550\', \'height\', \'400\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\', encodeURI(\'http://player.youku.com/player.php/sid/XMjIxMTE2MzMy/v.sw ...…

查看全部问答>

倒立摆电机都坏好几个了?

本帖最后由 paulhyde 于 2014-9-15 03:30 编辑 尼玛!什么情况》》?搞个倒立摆,电机实在是不堪重负,屡屡陨落呀,这事要闹那样呀???    …

查看全部问答>

MSP430F5529学习笔记1-I/O端口

开发版型号:SEED—MSP430F5529A 开发工具   :CCS 5.4v 以下内容是CCS中I/O端口操作的一些简单的demo,现整理如下: 有关MSP430F5529芯片I/O口相关资料,可参考《MSP430x5xx and MSP430x6xx Family User\'s Guide (Rev. M)——Chapte ...…

查看全部问答>

原理图和原理图库背景看不清的问题

我用的是AD14;现在原理图和原理图库背景的方格都看不清楚;请高手指点一下该怎么解决。 …

查看全部问答>