欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Uboot4之什么是环境变量与存储分区?

程序员文章站 2022-07-14 12:25:25
...

时间:2018.3.17  作者:Tom   工作:HWE 说明:如需转载,请注明出处。

1.如何理解环境变量

uboot 环境变量实现原理:

首先我们先要搞清楚uboot中环境变量的作用,uboot中环境变量的作用就是在不改变源码、不用重新编译的情况下,可以使我们通过设置环境变量的值来改变uboot的一些设置,如bootdelay时间、机器码的值等等。

u-boot的缺省情况下会有一些基本的环境变量,当执行saveenv时,环境变量会保存到flash存储设备中。如果环境变量的值为空,则uboot会使用uboot代码中的值;如果环境变量不为空,则优先使用环境变量的值。默认环境变量在uboot源码中common/Env_common.c文件中。

环境变量就是操作系统的全局变量。每一个环境变量对操作系统来说都是唯一的,名字和所代表的意义都是唯一的。

2.环境变量如何参与程序运行

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

2)环境变量在uboot中是用字符串表示的也就是说uboot是按照字符匹配的方式来区分各个环境变量的。因此用的时候一定要注意不要打错字了。

3.网络设置:ipaddr serverip

1)ipaddr是开发板的本地IP地址

2)serverip是开发板通过tftp指令去tftp服务器下载东西时,tftp服务器的IP地址。

3)gatewayip是开发板的本地网关地址

5)ethaddr是开发板的本地网卡的MAC地址。

4.自动运行命令设置:bootcmd

1)uboot启动后会开机自动倒数bootdelay秒,如果没有人按下回车打断启动,则uboot会自动执行启动命令来启动内核。

2)uboot开机自动启动时实际就是在内部执行了bootcmd这个环境变量的值所对应的命令集。

3)bootcmd=movi read kernel 30008000; bootm 30008000 意思是:将iNand的kernel分区读取到DDR内存的0x30008000地址处,然后使用bootm启动命令从内存0x30008000处去启动内核。

4)set bootcmd printenv,然后saveenv;然后重启则会看到启动倒数后自动执行printenv命令打印出环境变量。这个小实验说明开机自动执行了bootcmd。

5)set bootcmd 'movi read kernel 30008000; bootm 30008000'    中间有分号,一定要加双引号

5.uboot给kernel传参:bootargs

1)linux内核启动时可以接收uboot给他传递的启动参数,这些启动参数是uboot和内核约定好的形式、内容,linux内核在这些启动参数的指导下完成启动过程。这样的设计是为了灵活,为了内核在不重新编译的情况下可以用不同的方式启动。

2)我们要做的事情就是:在uboot的环境变量中设置bootargs,然后bootm命令启动内核时会自动将bootargs传给内核。

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

意义解释:

console=ttySAC2,115200    控制台使用串口2,波特率115200.

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

Init=/linuxrc            linux的进程1(init进程)的路径

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

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

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

1)新建一个环境变量,使用set var value

2)更改一个环境变量,使用set var value

3)删除一个环境变量,使用set var

7.注意:环境变量更改后的保存

修改完成环境变量后一定要保存,否则下次开机更改就又没了。

8.uboot中对Flash和DDR的管理

8.1 uboot阶段Flash的分区

1)所谓分区,就是说对Flash进行分块管理。

2)PC机等产品中,因为大家都是在操作系统下使用硬盘的,整个硬盘由操作系统统一管理,操作系统会使用文件系统帮我们管理硬盘空间。(管理保证了文件之间不会互相堆叠),于是乎使用者不用自己太过在意分区问题。

3)在uboot中是没有操作系统的,因此我们对Flash(相当于硬盘)的管理必须事先使用分区界定(实际上在uboot中和kernel中都有个分区表,分区表就是我们在做系统移植时对Flash的整体管理分配方法)。有了这个界定后,我们在部署系统时按照分区界定方法来部署,uboot和kernel的软件中也是按照这个分区界定来工作,就不会错。

4)分区方法不是一定的,不是固定的,是可以变动的。但是在一个移植中必须事先设计好定死,一般在设计系统移植时就会定好,定的标准是:

uboot:uboot必须从Flash起始地址开始存放(也许是扇区0,也许是扇区1,也许是其他,取决于SoC的启动设计),uboot分区的大小必须保证uboot肯定能放下,一般设计为512KB或者1MB(因为一般uboot肯定不足512KB,给再大其实也可以工作,但是浪费);

环境变量:环境变量分区一般紧贴着uboot来存放,大小为32KB或者更多一点。

kernel:kernel可以紧贴环境变量存放,大小一般为3MB或5MB或其他。

rootfs:••••••

剩下的就是*分区,一般kernel启动后将*分区挂载到rootfs下使用

总结:一般规律如下:

1)各分区彼此相连,前面一个分区的结尾就是后一个分区的开头。

2)整个flash充分利用,从开头到结尾。

3)uboot必须在Flash开头,其他分区相对位置是可变的。

4)各分区的大小由系统移植工程师自己来定,一般定为合适大小(不能太小,太小了容易溢出;不能太大,太大了浪费空间)

5)分区在系统移植前确定好,在uboot中和kernel中使用同一个分区表。将来在系统部署时和系统代码中的分区方法也必须一样。

8.2 uboot阶段DDR的分区

1)DDR的分区和Flash的分区不同,主要是因为Flash是掉电存在的,而DDR是掉电消失,因此可以说DDR是每次系统运行时才开始部署使用的。

2)内存的分区主要是在linux内核启动起来之前,linux内核启动后内核的内存管理模块会接管整个内存空间,那时候就不用我们来管了。

3)注意内存分区关键就在于内存中哪一块用来干什么必须分配好,以避免各个不同功能使用了同一块内存造成的互相踩踏。譬如说我们tftp 0x23E00000 zImage去下载zImage到内存的0x23E00000处就会出错,因为这个内存处实际是uboot的镜像所在。这样下载会导致下载的zImage把内存中的uboot给冲掉。

上一篇: 队列实现

下一篇: 用队列实现队列