初识嵌入式系列之uboot(六)

姓名:张硕 学院:电子工程学院 学号:19020100006

转自:https://blog.csdn.net/qq_38612145/article/details/107497384

嵌牛导读:本文主要介绍了uboot基础以及uboot的工作方式以及常见命令

嵌牛鼻子:嵌入式,uboot

嵌牛提问:uboot有哪些常用命令

嵌牛正文:

uboot基础

1.为什么要有uboot?

预备知识

计算机系统运行时的主要核心部件包含3个东西:CPU+外部存储器+内部存储器

PC机启动过程为:PC上电后先执行BIOS程序(实际上PC 的BIOS就是NorFlash),BIOS负责初始化DDR内存和硬盘,然后从硬盘上将OS镜像读取到DDR中,然后跳转到DDR中去执行OS直到启动(OS启动后BIOS就无用了)

uboot主要作用是用来启动操作系统内核,部署整个计算机系统,有操作Flash等板子上硬件的驱动,提供一个命令行界面供人操作

uboot程序部署在能作为启动设备的Flash做上,OS部署在Flash上,内存在掉电时无作用,CPU在掉电时不工作

嵌入式系统上电后先执行uboot、然后uboot负责初始化DDR,初始化Flash,然后将OS从Flash中读取到DDR中,然后启动OS(OS启动后uboot就无用了)

2. uboot必须解决的问题

自身可开机直接启动

必须根据具体的SoC的启动方式来设计uboot

uboot必须进行和硬件相对应的代码级别的更改和移植,才能保证响应启动介质的启动,uboot中第一阶段的start.S文件中处理了这一块

能够引导操作系统内核启动并给内核传参

我们可以在uboot中事先给Linux内核准备一些启动参数放在内存中特定位置然后传给内核,内核启动后会到这个特定位置去取uboot传给他的参数,然后内核解析这些参数

能提供系统部署功能

uboot必须能够被人借助而完成整个系统在Flash上的烧录下载工作(裸机在刷机时就是利用uboot中的fastboot功能将各种镜像烧录到iNand中,然后从iNand启动)

能进行SoC级和板级硬件管理

uboot中实现了一部分硬件的控制能力,因为uboot为了完成一些任务必须让一些硬件工作。譬如uboot要在刷机时LCD上显示进度条就必须驱动LCD。

SoC级就是SoC内部外设,板级就是SoC外面开发板上面的硬件

uboot存在生命周期

uboot本质上是一个裸机程序,一旦uboot开始SoC就会单纯运行uboot,一旦uboot结束运行就无法再回到uboot

uboot入口为开机自动启动;出口为启动内核

3. uboot的工作方式

从裸机程序镜像uboot.bin说起

uboot的本质就是一个裸机程序,和裸机教程中的裸机程序xx.bin没有本质区别,区别主要在于文件大小,uboot在180k-400k之间

uboot本身为一个开源项目,由若干个.c文件和.h文件组成,配置编译之后会生成一个uboot.bin,这就是uboot这个裸机的镜像文件。然后镜像文件被合理的烧录到启动介质中拿去给SoC启动,即uboot在没有运行时表现为uboot.bin

uboot运行时会被加载到内存中,然后逐次拿给CPU去运行

uboot的命令式shell界面

有些程序需要人机交互,于是程序中就实现了一个shell

shell并不是操作系统,和操作系统一点关系都没有,裸机也可以有shell

uboot使用的关键点:命令和环境变量

uboot启动后大部分时间和工作都是在shell下完成的。uboot部署系统要在shell下输入命令、要设置环境变量也需要在命令行下,要启动内核也要在命令行下输入命令

uboot中有几十个命令,其中一些常用,还可以自己给uboot添加命令

uboot的环境变量和操作系统的环境变量工作原理和方式几乎完全相同,uboot的驱动管理完全照抄了linux的驱动框架。系统或者程序在运行时可以通过读取环境变量来指导程序的运行。环境变量就是运行时的配置属性。

4. uboot常用命令

命令特点

有些命令有简化的别名

printenv -> print

setenv -> set

有些命令会带参数

每个命令都有事先规定好的格式,可以通过help命令查看

命令中的特殊符号(譬如单引号)

uboot有些命令带的参数非常长,为了告诉uboot这个非常长且中间有好多空格的语句为一整个参数,使用单引号将这个语句引起来

有些命令是一个命令族(譬如movi)

命令族的意思就是好多个命令开头都是用同一个命令关键字的,但是后面的参数不一样,这些命令的功能和作用也不同

同一个命令族中所有的命令都有极大的关联,譬如movi开头的命令族都和moviNand(EMMC、iNand)操作有关。

常见命令

打印环境变量:printenv/print

命令不用带参数,打印出系统中所有的环境变量。环境变量被存储在Flash的一块专门区域,一旦程序中保存了该环境变量,下次开机时该环境变量的值将维持上一次更改保存后的值

设置(添加/更改)环境变量:setenv/set

set name value

保存环境变量的更改:saveenv/save

不带参数,直接执行。是对整体环境变量的保存

网络测试指令:ping

步骤

用网线将电脑和开发板连接

设置电脑本地连接IPV4地址为192.168.1.10

确认开发板中uboot里几个与网络相关的环境变量的值对不对。最重要的是ipaddr的地址必须与主机的IP地址在同一个网段内。(set ipaddr 192.168.1.xx)

tftp下载命令:tftp

uboot主要目标是启动内核,为了完成启动内核必须要能够部署内核,而内核镜像需要从主机中下载烧录到开发板的Flash中,下载镜像的主流方式为fastboot和tftp。fastboot的方式是通过usb线进行数据传输;tftp是通过网络传输的

tftp方式下载时uboot扮演的是tftp客户端程序角色,主机中必须有一个tftp服务器,然后将要下载的镜像文件放在服务器的下载目录中,然后在开发板中使用uboot的tftp命令去下载

虚拟机和开发板ping通的步骤

虚拟机处选择桥接方式

在虚拟网络编辑器中设置为桥接到有线网卡

在虚拟机中设置IP静态地址为192.168.1.102(修改/etc/network/interfaces文件中的内容)

重启网络

sudo ifconfig eth0 down

sudo ifconfig eth0 up

在虚拟机上搭建tftp的下载目录/tftpboot,将要被下载的镜像复制到这个目录下

检查开发板uboot的环境变量,注意serverip必须设置与虚拟机Ubuntu的ip静态地址相同

在开发板uboot中使用tftp命令下载虚拟机中的镜像

tftp 0x30000000 zImage-qt

意思为将服务器上名为zImage-qt的文件下载到开发板内存的0x30000000地址处

镜像下载到开发板DDR中后,uboot就可以用movi指令进行镜像的烧写了

SD卡/iNand操作指令:movi

开发板如果用SD卡/EMMC/iNand等作为Flash,则在uboot中操作Flash用指令movi

movi指令是一个命令集,在uboot中可通过help movi查看

movi 的指令都是movi read和movi write一组的,movi read用来读取iNand到DDR上,movi write用来将DDR中的内容写入iNand中。

NandFlash操作指令:nand

操作方法完全类似于movi指令

内存操作指令:mm、mw、md

DDR中是没有分区的,但是内存使用时千万不能越界,因为uboot是一个裸机程序,不像操作系统会由系统整体管理所有内存,则可能会出现程序的覆盖

md:memory display,显示内存中的内容

mw:memory write,将内容写到内存中

mm:memory modify,修改内存中的一块,会批量逐个修改

启动内核指令:bootm、go

bootm启动内核同时给内核传参,而go命令启动内核不传参。

bootm是正宗的启动内核的命令,go命令本来不是专为启动内核设计的,go命令的实质是PC直接跳转到一个内存地址去运行而已。go命令可以用来在uboot中执行任何的裸机程序

5. uboot环境变量

如何理解环境变量

环境变量有2份,一份在Flash中,一份在DDR中。uboot开机时一次性从Flash中读取全部环境变量到DDR中作为环境变量的初始化值,然后使用过程中都是用DDR中这一份,用户可以通过saveenv指令将DDR中的环境变量重新写入Flash中去更新Flash中环境变量。下次开机时又会从Flash中再读一次

环境变量在uboot中是用字符串表示的,注意不要错别字,出现保存错误环境变量后set xxx消除并保存

自动运行命令设置:bootcmd

uboot在启动后会开机自动倒数bootdelay秒,如果没有打断则会自动启动内核

uboot中打印环境变量可以看到

bootcmd=movi read kernel 30008000

上述语句意思为将iNand的kernel分区读取到DDR内存的0x30008000地址处,然后使用bootm启动命令从内存0x30008000处去启东内核

uboot给kernel传参:bootargs

Linux内核启动时可以接收uboot给他传递的启动参数,这些参数使uboot和内核约定好的形式、内容,为了内核在不重新编译的情况下可以用不同的方式启动

在uboot的环境变量中设置bootargs,然后bootm命令启动内核时会自动将bootargs传给内核

bootargs=console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3

意义解释:控制台使用串口2,波特率为115200

root=… 根文件系统在SD卡端口0设备(iNand)第2分区,根文件系统是可读可写的

init=… Linux的进程1(init进程)的路径

rootfstype=… 根文件系统的类型是ext3

内核传参非常重要。在内核移植的时候,新手经常忘记给内核传参,或者给内核传递的参数不对,造成内核无法启动

新建、更改、删除一个环境变量的方法

新建和更改

set var value

删除

set var

修改完环境变量后一定要保存

6. uboot对Flash和DDR的管理

uboot阶段的Flash分区

所谓分区,就是对Flash进行分块管理

PC机等产品,都是在操作系统下使用硬盘的,整个硬盘由操作系统统一管理,使用者不用自己太在意分区问题

在uboot中没有操作系统,对Flash的管理必须事先使用分区界定,在部署系统时按照分区界定方法来部署,uboot和kernel的软件中也是按照这个分区界定来工作就不会出错

分区不是固定的,在一个移植中必须事先设计好定死。一般在设计系统移植时就会定好,定的标准是:uboot必须从Flash起始地址开始存放,uboot分区大小必须保证uboot肯定能放下,一般设计为512kb或者1MB;环境变量分区一般紧贴着uboot来存放,大小为32KB或多一点;kernel可以紧贴环境变量存放,大小一般为3MB或5MB或其他;rootfs紧贴着kernel;剩下的就是自动分区,一般kernel启动后将自由分区挂载到rootfs下使用

总结

各分区彼此相连

整个Flash充分利用,从开头到结尾

uboot必须在Flash开头,其他分区相对位置可变

各分区的大小由系统移植工程师来定

分区在系统移植前确定好,在uboot中和kernel中使用同一个分区表

uboot阶段DDR的分区

因为Flash是掉电存在的,而DDR是掉电消失,因此可以说DDR是每次系统运行时才开始部署使用的

内存的分区主要是在Linux内核启动之前,Linux内核启动后内核的内存管理模块会接管整个内存空间

内存分区关键就在于内存中哪一块用来干什么必须分配好,以避免各个不同功能使用了同一块内存造成覆盖。

你可能感兴趣的:(初识嵌入式系列之uboot(六))