uboot简介
uboot 的全称是 Universal Boot Loader,uboot 是一个遵循 GPL 协议的开源软件,uboot是一个裸机代码,可以看作是一个裸机综合例程。现在的 uboot 已经支持液晶屏、网络、USB 等高级功能。
也就是说,可以在没有系统的情况下做一些事情,而这不就是裸机干的活嘛。
UBOOT其实就包含了裸机的内容。
UBOOT应该是属于板级的内容,就像在电脑上装系统,不管是装什么系统,都是一开始按某个键进入BIOS,然后决定从哪启动,装windows或者装linux都用的是同一个BIOS。
在移植 Linux之前我们需要先移植一个 bootloader 代码,这个 bootloader 代码用于启动 Linux 内核,bootloader有很多,常用的就是 U-Boot。移植好 U-Boot 以后再移植 Linux 内核,移植完 Linux 内核以后Linux 还不能正常启动,还需要再移植一个根文件系统(rootfs),根文件系统里面包含了一些最常用的命令和文件。所以 U-Boot、Linux kernel 和 rootfs 这三者一起构成了一个完整的 Linux 系统,一个可以正常使用、功能完善的 Linux 系统。在本篇我们就来讲解 U-Boot、Linux Kernel 和rootfs 的移植,与其说是“移植”,倒不如说是“适配”,因为大部分的移植工作都由NXP厂家完成了,我们这里所谓的“移植”主要是使其能够在 I.MX6U-ALPHA 开发板上跑起来。
uboot启动说明
系统通过UBOOT来启动,那么UBOOT自己怎么启动呢?
具体内容参考正点原子《I.MX6U 嵌入式 Linux 驱动开发指南》
uboot 是 bootloader 的一种,可以用来引导Linux,但是 uboot 除了引导 Linux 以外还可以引导其它的系统,而且 uboot 还支持其它的架构和外设,比如 USB、网络、SD 卡等。这些都是可以配置的,需要什么功能就使能什么功能。所以在编译 uboot 之前,一定要根据自己的需求配置 uboot。mx6ull_14x14_ddr512_emmc_defconfig就是正点原子针对 I.MX6U-ALPHA 的 EMMC 核心板编写的配置文件,这个配置文件在 uboot源码的 configs 目录中。在 uboot 中,通过“make xxx_defconfig”来配置 uboot,xxx_defconfig就是不同板子的配置文件,这些配置文件都在 uboot/configs 目录中。
看来一般各个模块都有自己的配置文件,也就是defconfig,既然用的是defconfig文件,那么.config文件啥时候用?暂时想不明白,那就待补充吧。
uboot 是可配置的,但是你要是自己从头开始一个一个项目的配置,那就太麻烦了,因此一般半导体或者开发板厂商都会制作好一个配置文件。我们可以在这个做好的配置文件基础上来添加自己想要的功能,这些半导体厂商或者开发板厂商制作好的配置文件统一命名为“xxx_defconfig”,xxx 表示开发板名字,这些 defconfig 文件都存放在 configs文件夹。
使用 “make xxx_defconfig”命令即可配置 uboot,比如:
make mx6ull_14x14_ddr512_emmc_defconfig
上述命令就是配置正点原子的 I.MX6ULL EMMC 核心板所使用的 uboot。
在编译 uboot 之前一定要使用 defconfig 来配置 uboot!
倒计时结束之前按下回车键就会进入 Linux 命令行模式。如果在倒计时结束以后没有按下回车键,那么 Linux 内核就会启动,Linux 内核一旦启动,uboot 就会寿终正寝。
uboot常用命令
uboot 是来干活的,我们现在已经进入 uboot 的命令行模式了,进入命令行模式以后就可以给 uboot 发号施令了。当然了,不能随便发号施令,得看看 uboot 支持哪些命令,然后使用这些uboot 所支持的命令来做一些工作。
进入 uboot 的命令行模式以后输入“help”或者“?”,然后按下回车即可查看当前 uboot 所支持的命令。有的可能设置得不一样,根据实际情况而定。uboot 是可配置的,需要什么命令就使能什么命令,uboot 支持的命令还有很多,而且也可以在 uboot 中自定义命令。
uboot 是支持网络的,我们在移植 uboot 的时候一般都要调通网络功能,因为在移植 linux
kernel 的时候需要使用到 uboot 的网络功能做调试。uboot 支持大量的网络相关命令,比如 dhcp、ping、nfs 和 tftpboot等等。
我们最常用的就是 ping、nfs 和 tftp 这三个命令。使用 ping 命令来查看网络的连接状态,使用 nfs 和 tftp 命令来从 Ubuntu 主机中下载文件。
nfs(Network File System)网络文件系统,通过 nfs 可以在计算机之间通过网络来分享资源,
比如我们将 linux 镜像和设备树文件放到 Ubuntu 中,然后在 uboot 中使用 nfs 命令将 Ubuntu 中的 linux 镜像和设备树下载到开发板的 DRAM 中。这样做的目的是为了方便调试 linux 镜像和设备树,也就是网络调试,通过网络调试是 Linux 开发中最常用的调试方法。原因是嵌入式 linux开发不像单片机开发,可以直接通过 JLINK 或 STLink 等仿真器将代码直接烧写到单片机内部的 flash 中,嵌入式 Linux 通常是烧写到 EMMC、NAND Flash、SPI Flash 等外置 flash 中,但是嵌入式 Linux 开发也没有 MDK,IAR 这样的 IDE,更没有烧写算法,因此不可能通过点击一个“download”按钮就将固件烧写到外部 flash 中。虽然半导体厂商一般都会提供一个烧写固件的软件,但是这个软件使用起来比较复杂,这个烧写软件一般用于量产的。其远没有 MDK、IAR的一键下载方便,在 Linux 内核调试阶段,如果用这个烧写软件的话将会非常浪费时间,而这个时候网络调试的优势就显现出来了,可以通过网络将编译好的 linux 镜像和设备树文件下载到 DRAM 中,然后就可以直接运行。
具体参看正点原子手册。
uboot 的本质工作是引导 Linux,所以 uboot 肯定有相关的 boot(引导)命令来启动 Linux。常用的跟 boot 有关的命令有:bootz、bootm 和 boot。
bootm 和 bootz 功能类似,但是 bootm 用于启动 uImage 镜像文件。
boot 命令
boot 命令也是用来启动 Linux 系统的,只是 boot 会读取环境变量 bootcmd 来启动 Linux 系统,bootcmd 是一个很重要的环境变量!其名字分为“boot”和“cmd”,也就是“引导”和“命令”,说明这个环境变量保存着引导命令,其实就是启动的命令集合,具体的引导命令内容是可以修改的。比如我们要想使用 tftp 命令从网络启动 Linux 那么就可以设置 bootcmd 为“tftp 80800000 zImage; tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb; bootz 80800000 - 83000000”,然后使用 saveenv 将 bootcmd 保存起来。然后直接输入 boot 命令即可从网络启动Linux 系统。
uboot启动流程
uboot 整个源码非常大,我们只看跟我们关心的部分即可,重点是分析 uboot 启动流程,否则移植的时候都不知道该修改那些文件。
具体参看正点原子手册。
我们在分析 uboot 源码之前一定要先在 Ubuntu 中编译一下 uboot 源码,因为编译过程会生成一些文件,而生成的这些恰恰是分析uboot 源码不可或缺的文件。
在阅读 uboot 源码之前,肯定是要先看一下顶层 Makefile,分析 gcc 版本代码的时候一定是先从顶层 Makefile 开始的,然后再是子 Makefile,这样通过层层分析 Makefile 即可了解整个工程的组织结构。顶层 Makefile 也就是 uboot 根目录下的 Makefile 文件。
我们来详细的分析一下 uboot 的启动流程,理清 uboot 是如何启动的。通过对 uboot 启动流程的梳理,我们就可以掌握一些外设是在哪里被初始化的,这样当我们需要修改这些外设驱动的时候就会心里有数。另外,通过分析 uboot 的启动流程可以了解 Linux 内核是如何被启动的。从这里我们可以知道,有些外设是可以在bootloader里初始化的。链接脚本 u-boot.lds 详解要分析 uboot 的启动流程,首先要找到“入口”,找到第一行程序在哪里。程序的链接是由链接脚本来决定的,所以通过链接脚本可以找到程序的入口。如果没有编译过 uboot 的话链接脚本为 arch/arm/cpu/u-boot.lds 。但是这个不是最终使用的链接脚本,最终的链接脚本是在这个链接脚本的基础上生成的。编译一下 uboot ,编译完成以后就会在 uboot 根目录下生成 u-boot.lds文件,如图 32.1.1 所示:
只有编译 u-boot 以后才会在根目录下出现 u-boot.lds 文件!打开 u-boot.lds ,部分内容如下:
第 3 行为代码当前入口点: _start , _start 在文件 arch/arm/lib/vectors.S 中有定义…………具体查看正点原子的开发手册。看得脑壳子疼。。。。。。
uboot移植
不管是购买的开发板还是自己做的开发板,基本都是参考半导体厂商的 dmeo 板,而半导体厂商会在他们自己的开发板上移植好 uboot 、 linux kernel 和 rootfs 等,最终制作好 BSP包提供给用户。我们可以在官方提供的 BSP 包的基础上添加我们的板子,也就是俗称的移植。我们购买的开发板或者自己做的板子一般都不会原封不动的照抄半导体厂商的 demo板,都会根据实际的情况来做修改,既然有修改就必然涉及到 uboot 下驱动的移植。一般 uboot 中需要解决串口、 NAND 、 EMMC 或 SD 卡、网络和 LCD 驱动,因为 uboot的主要目的就是启动 Linux 内核,所以不需要考虑太多的外设驱动。在 uboot 中添加自己的板子信息,根据自己板子的实际情况来修改 uboot 中的驱动。
U-Boot图形化配置
uboot 或 Linux 内核可以通过输入“ make menuconfig ”来打开图形化配置界面, menuconfig是一套图形化的配置工具,需要 ncurses 库支持。 ncurses 库提供了一系列的 API 函数供调用者生成基于文本的图形界面,因此需要先在 Ubuntu 中安装 ncurses 库,命令如下:sudo apt-get install build-essentialsudo apt-get install libncurses5-devmenuconfig 重点会用到两个文件: .config 和 Kconfig , .config 文件前面已经说了,这个文件保存着 uboot 的配置项,使用 menuconfig 配置完 uboot 以后肯定要更新 .config 文件。 Kconfig文件是图形界面的描述文件,也就是描述界面应该有什么内容,很多目录下都会有 Kconfig 文件。在打开图形化配置界面之前,要先使用“ make xxx_defconfig ”对 uboot 进行一次默认配置,只需要一次即可。如果使用“make clean ”清理了工程的话就那就需要重新使用“ make xxx_defconfig”再对 uboot 进行一次配置。
补充
zImage
zImage是ARM Linux常用的一种压缩映像文件,uImage是U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的“头”,说明这个映像文件的类型、加载位置、生成时间、大小等信息。换句话说,如果直接从uImage的0x40位置开始执行,zImage和uImage没有任何区别。另外,Linux2.4内核不支持uImage,Linux2.6内核加入了很多对嵌入式系统的支持,但是uImage的生成也需要设置。
几种linux内核文件的区别(vmlinux、zImage、bzImage、uImage、vmlinuz、initrd )_zimage是什么-CSDN博客
那什么是映像文件?
操作系统的镜像文件和映像文件有什么区别?_虚拟机下的win10 和映像文件的win10哪个好-CSDN博客
Linux下的常见映像文件格式
核心转储文件
核心转储(core dump),在汉语中有时戏称为吐核,是操作系统在进程收到某些信号而终止运行时,将此时进程地址空间的内容以及有关进程状态的其他信息写出的一个磁盘文件。这种信息往往用于调试。
设置编译结果输出目录
uboot 可以将编译出来的目标文件输出到单独的目录中,在 make 的时候使用“ O ”来指定输出目录,比如“make O=out ”就是设置目标文件输出到 out 目录中。这么做是为了将源文件和编译产生的文件分开,当然也可以不指定 O 参数,不指定的话源文件和编译产生的文件都在同一个目录内,具体根据实际情况而定。
其他
在 uboot 中允许单独编译某个模块,使用命令“ make M=dir ”即可,旧语法“ make SUBDIRS=dir”也是支持的。