uboot基础知识

Posted 阿C_C

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uboot基础知识相关的知识,希望对你有一定的参考价值。

uboot简介

uboot主要是用于启动操作系统内核,部署整个计算机系统,操作主板上的驱动,提供命令行界面供操作员操作等工作。

uboot启动过程

计算机系统通常有CPU,外部存储区,内部存储区三部分构成,典型的PC机在上电时先启动固化在主板上NorFlash的Bios程序,由BIOS程序初始化DDR内存,硬盘,从硬盘将操作系统镜像读取到DDR中,然后跳转到DDR中执行操作系统,直到操作系统启动完成,BIOS退出。

嵌入式系统的启动过程也是参考PC机的,上电后,由部署在能作为启动设备的Flash上的uboot程序首先启动,由于嵌入式系统没有硬盘,所以操作系统部署在充当硬盘的Flash(NandFlash | iNand)上,uboot负责启动和初始化DDR和Flash,然后将操作系统镜像读取到DDR中,再启动操作系统,操作系统启动后,uboot退出。

android启动过程

Android系统和典型的嵌入式linux系统的启动过程基本上是一样的,只是在内核启动后加载根文件系统后才会不同。可以分为两个阶段:

  1. 从uboot启动到操作系统
  2. 操作系统启动到根文件系统命令行执行

Android启动的差别主要在第二个阶段。

uboot基本简介

uboot来源

uboot期初是SourceForge上的开源项目,经过多年的发展,已经成为事实上的标准,大部分都会默认使用uboot作为bootloader。早期的uboot使用三位数作为版本号,在后来,版本号使用年份和月份来表示。但是核心部分没什么变化,越新版本支持的开发板越多。

uboot具有可移植性,具有在源代码级别的移植能力,可以针对开发板进行移植使用。

uboot的基本任务

  1. uboot必须实现开机可以自身启动,必须根据具体的Soc的启动来设计uboot,所以uboot必须进行和硬件对应的移植才能保证从对应的硬件介质进行开机启动,uboot中的第一阶段的start.S文件处理了这一块。
  2. uboot还可以引导操作系统内核并给内核传参,内核被设计为可以传参,内核解析到uboot传过来的参数,用于指导linux内核的启动过程。
  3. uboot还需要能够提供系统部署功能,可以被人借助完成整个系统在Flash上的烧录下载,包括uboot,内核以及根文件系统的镜像文件。
  4. uboot还要能够进行Soc和板级的管理,初始化一些基本硬件,来完成一些特定的任务。包含一些Soc的内部外设以及开发板上的硬件。

uboot本质上是一个裸机程序,一旦开始整个Soc就会单纯运行uboot,独占CPU,一旦结束后就无法再回到uboot,uboot在开机的时候自动启动,在启动内核之后就结束了。

uboot工作方式

uboot是一个裸机程序,一般的uboot.bin的文件大小在190K左右,这个镜像文件被烧录到启动介质中由Soc来执行,运行时候被加载到内存中执行每一条指令。

在一些需要和人进行交互的程序中,需要实现一个命令行的Shell界面,这个Shell和linux的终端Shell很类似,只不过可以执行的命令集不一样,例如运行fastboot可以进行系统部署。

uboot的环境变量和操作系统的环境变量的原理基本上完全相同,在设计之初就借鉴了操作系统的理念,环境变量可以认为是系统的全局变量,变量名都是系统内置的,在运行时通过配置环境变量,可以使程序更灵活。

uboot常用命令

  • 和LinuxShell类似的行缓冲命令:当我们在终端输入命令的时候,命令会被缓存在缓冲区,直到达到缓冲区大小或者按下回车键,系统才会认为命令输入完毕,将缓冲区的内容作为命令去执行,Linux终端有三种缓冲模式,无缓冲,行缓冲以及全缓冲。
  • 某些命令会有一些简单的缩写,为了提高在终端上操作的效率。
  • 大部分命令都会带有参数,参数可选或者是必须的,参数可以控制命令执行,得到不同的结果。
  • 命令中还可能包含一些特殊符号,特殊符合可能有特殊的作用。
  • 很多命令开头都是同一个命令关键字,但是参数不一样,功能和作用也不同,称为一个命令组,命令组中的所有的命令都有极大的关联。

print/printenv

打印当前系统中所有的环境变量,不需要参数,当前系统中的程序都可以根据需要去添加,删除,获取,修改环境变量。

setenv/set

设置系统中的环境变量,如果环境变量的value为空,则表示删除该环境变量

save/saveenv

将内存中的环境变量同步保存到flash中,内存中所有的环境变量将会覆盖flash中原来的环境变量,序列化后的环境变量在uboot重启之后仍然有效

ping

测试开发板和主机之间的网络连接,需要主机和开发板有电缆连接并配置正确的IP。

tftp

uboot通常需要将内核镜像从主机下载下来,并烧录到flash中,主流方式是fastboot和tftp,tftp通常将镜像下载到指定的内存地址上,然后就可以使用movi指令组进行镜像烧写。

movi

开发板如果用SD卡,EMMC,或者是iNand作为Flash的时候,则在uboot中操作flash的命令为movi或者mmc,movi有很多子命令,read和write组合成一组,用于在iNand和DDR之间数据的交互。

mm,mw,md

DDR是没有分区的,但是在使用的时候注意不能越界访问,尤其是uboot这种裸机程序,很有可能会把自己的数据覆盖掉:

  • md:用于显示内存中的内容
  • mw:用于将数据写到内存中去
  • mm:用于修改内存中数据

bootm,go

uboot的最终目标是用于启动内核,在命令行中执行该指令就可以启动内核,该命令会启动内核,并退出uboot,bootm启动内核同时给内核传递参数,go指令不传递参数,一般情况下都是用bootm。而go内部是一个函数指针,直接调用该函数,实际上是直接跳转到一个内存地址去运行,可以用来在uboot中执行裸机程序。

uboot环境变量

环境变量在uboot中是以字符串的形式存在的,所以uboot是以字符串匹配的方式寻找环境变量的。

bootcmd

自动运行命令的设置,uboot在启动后会开机自动倒数bootdelay秒,如果没有按下回车打断启动,则uboot会自动执行启动命令来启动内核,实际上就是执行了bootcmd环境变量的命令集, 该环境变量的值可以是索个命令组成的集合。

bootargs

Linux内核在启动的时候可以接受uboot给它传递的启动参数,这些参数是提前约定好的,Linux在这些启动参数的指导下完成启动过程,使得内核启动方式更加灵活,只要该环境变量有值,则bootm在启动时会自动将这些环境变量值传递给内核,举一个常见的bootargs命令来分析:console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3,意思是控制台使用的是ttySAC2(串口2),波特率为115200,root表示根文件系统,使用 MMCblock0(SD卡端口0的设备,也就是板载的iNand)其中的第二分区作为根文件系统路径,rw表示根文件系统可读写。init表示linux进程1的路径。rootfstype表示根文件系统的类型为ext3.

内核传参是非常重要的步骤,一定要保证给内核传正确的参数。

uboot对Flash和DDR的管理

uboot对Flash的分区管理

Flash中使用分区表对空间进行分区:

  • uboot
  • uboot环境变量
  • kernel
  • rootfs
  • 自由空间:一般挂载为文件系统使用

分区方式不是固定的,是可以变动的,但是必须在移植之前事先设计好并固定,一般在设计系统移植时的标准是:

  • uboot必须从Falsh的起始地址开始存放,取决于Soc的启动设计。分区大小必须保证能够保证放得下uboot,一般为512KB或者1MB,一般的uboot都可以放下了。
  • 环境变量的分区一般紧跟着uboot,大小一般为1个扇区,能够存储得下变量数据就可。
  • kernel一般紧跟环境变量,大小为3-5MB左右,
  • 根文件系统紧跟kernel,大小根据需求
  • kernel启动后将剩余的自由分区挂在到根文件系统下使用

每个分区收尾相连接,整个Flash可以被充分被利用,uboot一般必须在Flash的开头,其他分区原则上是可以变动的。分区大小一般根据需要来定。在系统移植前就需要确定分区表,在uboot和内核中都是用的是同一个分区表。在系统部署的运行的时候分区方式也必须一样。

DDR分区

DDR的分区和Flash不同,两者的存储原理不一样。uboot的内存管理任务主要在linux内核启动之前,Linux内核启动之后,整个DDR会被内核接管,就不需要uboot来管理了。uboot阶段DDR管理只需要避免内存被多个任务同时使用即可。

以上是关于uboot基础知识的主要内容,如果未能解决你的问题,请参考以下文章

Uboot基础

uboot图形化配置浅析

uboot移植——修改默认ip地址

uboot sf 指令详解

uboot sf 指令详解

uboot之位置无关代码解析