Linux驱动学习之---uboot编译
前言:为什么不自己构建uboot ?
- 太浪费时间了,虽然可以学习很多知识,但工作中实际去构建应该是比较少的,原厂会提供demo,在这个基础上去更改
- 想快速搭建好环境学习linux驱动,学习uboot会浮躁,打击学习积极性,把uboot放在后面学习比较好
bootloader简介
Linux 系统要启动就必须需要一个 bootloader 程序,也就说芯片上电以后先运行一段
bootloader 程序。这段bootloader程序会先初始化DDR等外设,然后将Linux内核从flash(NAND,
NOR FLASH,SD,MMC 等)拷贝到 DDR 中,最后启动 Linux 内核。当然了,bootloader 的实
际工作要复杂的多,但是它最主要的工作就是启动 Linux 内核,bootloader 和 Linux 内核的关系
就跟 PC 上的 BIOS 和 Windows 的关系一样,bootloader 就相当于 BIOS。

bootloader分为很多种,常用的应该是uboot了
U-Boot 初次编译
首先在 Ubuntu 中安装 ncurses 库,否则编译会报错,
在 U-Boot(一个常用的引导加载程序)的编译过程中,ncurses 库可能会被用到,特别是当您配置 U-Boot 时(例如运行 make menuconfig 命令)。menuconfig 会提供一个基于文本的菜单,让您可以选择和配置 U-Boot 的各种选项,而这正是通过 ncurses 库实现的。
安装命令如下:
sudo apt-get install libncurses5-dev将uboot源码拷贝到目录下,我的目录 :/root/uboot
这里我使用正点原子提供好的,因为已经做好了内存外存的适配

解压
tar -vxjf uboot-imx-2016.03-2.1.0-g0ae7e33-v1.7.tar.bz2解压完成之后删除压缩包
rm -rf uboot-imx-2016.03-2.1.0-g0ae7e33-v1.7.tar.bz2
安装交叉编译工具链,为了保证不出现各种奇葩的错误,还是用正点原子提供的吧,同时贴出直接安装步骤
创建文件夹,将交叉编译工具放在该目录
sudo mkdir /usr/local/arm并解压
sudo tar -vxf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz
修改环境变量,使用 vim 打开/etc/profile 文件,命令如下:
sudo vim /etc/profile打开/etc/profile 以后,在最后面输入如下所示内容:
export PATH=$PATH:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin
修改好以后就保存退出,重启 Ubuntu 系统
sudo reboot安装相关库
sudo apt-get install lsb-core lib32stdc++6交叉编译工具验证
arm-linux-gnueabihf-gcc -v或者
直接包管理器安装交叉编译工具链
通常工具链的二进制文件会被安装到系统的标准路径中,例如 /usr/bin,这意味着通常不需要修改 PATH 环境变量,因为这些路径通常已经包含在 PATH 中。(这个我没有装,没有验证,理论应该是这样的)
sudo apt-get install gcc-arm-linux-gnueabihf开始编译
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12当 V 设置为 1 时,make 会显示更多的输出,这对于调试编译问题很有帮助。
-j12 是一个选项,用于指定 make 应该同时运行多少个任务。12 表示 make 可以同时运行最多 12 个任务。这可以加快编译速度,特别是在多核心的计算机上。
如果您不指定 -j 后面的数字,make 将会尽可能地运行无限多的任务,这可能会导致系统资源的耗尽。通常,为了避免过度使用系统资源,建议总是为 -j 选项指定一个合适的数字
执行最后一步时编译错误

arm-linux-gnueabihf-gcc 不识别 -march=armv5 作为一个有效的目标架构。错误信息也列出了所有有效的 -march 目标参数,armv5 不在其中,但有 armv5t、armv5te 和 armv5tej。
更改makefile
cd ./arch/armpwd
vim Makefile将最后的armv5 更改为armv5te

- 保存文件并退出编辑器。
- 清理并重新编译项目:
make clean
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12编译完成


编译完成以后uboot源码多了一些文件,其中u-boot.bin就是编译出来的uboot二进制文件。uboot是个裸机程序,因此需要在其前面加上头部(IVT、DCD等数据)才能在I.MX6U上执行,图中的u-boot.imx文件就是添加头部以后的u-boot.bin,u-boot.imx就是我们最终要烧写到开发板EMMC中的uboot 镜像文件。
烧写uboot启动
挂载SD卡
在ubuntu上插入sd卡
lsblk 命令会列出所有可用的块设备,以及它们的挂载点(如果已挂载的话)。
lsblk
以上是我的SD卡,有一个分区(sda1)。然而,这个分区没有挂载点列出,这意味着它当前没有被挂,我们需要挂载sd卡
常见的挂载点:
- /mnt: 这个目录通常用作临时挂载点,例如手动挂载的设备。
- /media: 大多数现代Linux发行版会使用这个目录作为自动挂载的可移动设备的挂载点,例如USB驱动器、CD-ROM驱动器、SD卡等。
- /home: 用户的个人目录通常会挂载在这里,尤其是在
/home目录位于不同的分区或磁盘时。 - /boot: 在某些系统中,引导分区会被挂载到这个目录。
创建挂载点
sudo mkdir /media/sdcard将sd卡设备挂载上去
sudo mount /dev/sda1 /media/sdcard再次查看是否挂载,可以看到已经有挂载点了

格式化SD卡
这张卡已经格式化过了,不过了解下linux下SD卡的格式化还是有必要的
确定SD卡的设备路径
我的SD卡的设备路径是 /dev/sda。请再次确认这一点,以避免误操作其他设备。使用 lsblk
卸载SD卡
如果SD卡已经挂载,需要先卸载它。您可以使用 umount 命令来卸载所有与SD卡相关的分区。例如:
sudo umount /dev/sda1格式化SD卡
使用 mkfs 命令来格式化SD卡。mkfs.vfat 命令用于创建一个FAT文件系统,这通常是FAT32文件系统。
sudo mkfs.vfat /dev/sda1挂载SD卡
这里还是挂载到刚才的目录下
sudo mount /dev/sda1 /media/sdcard烧录uboot到sd卡
两种方式,使用nxp官方下载工具或者dd工具
imxdownload 是 NXP 提供的一个特定于 i.MX 处理器系列的烧录工具。这个工具是为了烧录 i.MX 处理器的 boot ROM 而设计的,通常用于烧录 U-Boot bootloader 到设备上。这个工具通常会与 i.MX 处理器的特定硬件接口一起使用,例如 USB 或 UART,来进行烧录。
imxdownload 与 dd 的区别:
特定性:
imxdownload是针对 NXP 的 i.MX 系列处理器设计的,而dd是一个通用的 UNIX 工具,可用于任何 UNIX 系统上,用于复制和转换文件。
接口:
imxdownload通常使用特定的硬件接口(例如 USB 或 UART)来烧录 i.MX 处理器,而dd则直接操作块设备,例如 SD 卡。
用途:
imxdownload主要用于烧录 bootloader 到 i.MX 处理器的内部存储或外部存储中,而dd可以用于复制任何文件和设备内容,包括制作和恢复磁盘映像。
操作层级:
imxdownload操作的是处理器级别,直接与处理器的 boot ROM 交互,而dd操作的是文件系统级别,与块设备交互。
选择工具:
- 如果您正在使用 NXP 的 i.MX 系列处理器,并且需要通过特定的硬件接口烧录 bootloader,那么
imxdownload可能是更合适的选择。 - 如果您只是需要将 bootloader 烧录到一个块设备(例如 SD 卡)上,并且不需要特定的硬件接口,那么
dd应该足够了。
举例说明:
使用特定硬件接口:
- 如果您使用的是 i.MX 处理器,并且需要通过 USB 接口来烧录 bootloader 到处理器的内部存储中,那么您可能需要使用
imxdownload这样的特定工具。
- 如果您使用的是 i.MX 处理器,并且需要通过 USB 接口来烧录 bootloader 到处理器的内部存储中,那么您可能需要使用
不需要特定硬件接口:
- 如果您只是需要将 bootloader 烧录到一个 SD 卡上,这个 SD 卡可以直接通过计算机的 SD 卡读卡器访问,那么您可以使用
dd命令,因为这种情况下不需要与特定的处理器或硬件接口进行直接通信。
- 如果您只是需要将 bootloader 烧录到一个 SD 卡上,这个 SD 卡可以直接通过计算机的 SD 卡读卡器访问,那么您可以使用
简而言之,如果您的烧录过程只涉及到标准的、通用的块设备接口,例如 SD 卡读卡器,那么 dd 命令应该是足够的。如果烧录过程需要与特定的处理器或硬件平台的特定接口进行通信,那么您可能需要使用特定于该硬件平台的烧录工具。
dd工具烧录
我们使用dd工具来烧录吧,毕竟具有通用性
要将U-Boot烧写到SD卡,您通常会使用dd命令。dd命令可以用于复制文件或设备内容,通常用于制作或复制磁盘映像。在这种情况下,您将使用dd命令将编译好的U-Boot二进制文件(通常是u-boot.bin或u-boot.imx)复制到SD卡。
步骤:
找到U-Boot二进制文件
- 确定U-Boot二进制文件的位置。这通常是
u-boot.bin或u-boot.imx。
- 确定U-Boot二进制文件的位置。这通常是
卸载SD卡
- 在写入之前,确保SD卡是卸载的。
sudo umount /dev/sda1使用dd命令烧写U-Boot
- 使用
dd命令将U-Boot烧写到SD卡。请替换<u-boot-file>为您的U-Boot二进制文件的路径。
sudo dd iflag=dsync oflag=dsync if=<u-boot-file> of=/dev/sda seek=2- 这里,
if是输入文件,of是输出文件(您的SD卡),bs是块大小,seek是跳过的块数。seek=2通常用于跳过SD卡的分区表。
- 使用
同步
iflag=dsync和oflag=dsync,这两个选项会确保每次读取和写入都是同步的,这意味着每次读取或 写入操作都会等待物理 I/O 操作完成。这可以确保数据的完整性
注意:
- 请小心使用
dd命令,因为它会覆盖目标设备(在这种情况下是SD卡)的内容。确保of参数是正确的,以避免覆盖系统的其他部分。 - 在执行
dd命令之前,确保没有挂载SD卡的任何分区。 - 请根据您的U-Boot版本和目标硬件,检查相关的文档以确定正确的
dd命令参数,特别是bs和seek参数。
了解以上内容以后,我的uboot 路径:/root/uboot

查看挂在设备并卸载
lsblk
sudo umount /dev/sda1
烧写U-Boot
注意:是sda,不是sda1分区
我当前是在uboot目录下
sudo dd iflag=dsync oflag=dsync if=u-boot.imx of=/dev/sda seek=2
0.07S,一个字-->快, 不过看到这种一般是没烧写上去
查看所有sd
ls /dev/sd*
这里有一个虚拟的sdb ,删掉
sudo rm -rf /dev/sdb再次查看

再次烧写,烧写成功一般是这样

BOOT 设置从 SD 卡启
动,使用 USB 线将 USB_TTL 和电脑连接,也就是将开发板的串口 1 连接到电脑上。打开
MobaXterm,设置好串口参数并打开,最后复位开发板。在 MobaXterm 上出现“Hit any key to
stop autoboot: ”倒计时的时候按下键盘上的回车键,默认是 3 秒倒计时,在 3 秒倒计时结束以
后如果没有按下回车键的话 uboot 就会使用默认参数来启动 Linux 内核了。如果在 3 秒倒计时
结束之前按下回车键,那么就会进入 uboot 的命令行模式,否则会引导进入linux内核
可以理解为windows开机时的bios,开机狂按某个按键会进入bios,不按正常启动系统

NXP官方工具imxdownload烧录
https://newbie-typora.oss-cn-shenzhen.aliyuncs.com/tools/imxdownload
将该工具放在uboot目录下,给予执行权限

chmod 777 imxdownload烧写命令 //烧写到SD卡中
./imxdownload u-boot.bin /dev/sda 
再次将SD插入开发板启动看一下没问题的(115200)

总结:
编译uboot 依赖于交叉编译工具链以及一些必须库,烧写uboot到SD卡时候使用dd工具,具有通用性。