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。

image-20230929001850801

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

这里我使用正点原子提供好的,因为已经做好了内存外存的适配

image-20230929002353667

解压

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

image-20230929002658168

安装交叉编译工具链,为了保证不出现各种奇葩的错误,还是用正点原子提供的吧,同时贴出直接安装步骤

创建文件夹,将交叉编译工具放在该目录

https://newbie-typora.oss-cn-shenzhen.aliyuncs.com/tools/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz

sudo mkdir /usr/local/arm

并解压

sudo tar -vxf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz

image-20230929010309584

修改环境变量,使用 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

image-20230929010716649

修改好以后就保存退出,重启 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 选项指定一个合适的数字

执行最后一步时编译错误

image-20230929004332724

arm-linux-gnueabihf-gcc 不识别 -march=armv5 作为一个有效的目标架构。错误信息也列出了所有有效的 -march 目标参数,armv5 不在其中,但有 armv5tarmv5tearmv5tej

更改makefile

cd ./arch/armpwd
vim Makefile

将最后的armv5 更改为armv5te

image-20230929095236135

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

编译完成

image-20230929095443809

image-20230929103518594

编译完成以后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

image-20230929101205135

以上是我的SD卡,有一个分区(sda1)。然而,这个分区没有挂载点列出,这意味着它当前没有被挂,我们需要挂载sd卡

常见的挂载点:

  1. /mnt: 这个目录通常用作临时挂载点,例如手动挂载的设备。
  2. /media: 大多数现代Linux发行版会使用这个目录作为自动挂载的可移动设备的挂载点,例如USB驱动器、CD-ROM驱动器、SD卡等。
  3. /home: 用户的个人目录通常会挂载在这里,尤其是在/home目录位于不同的分区或磁盘时。
  4. /boot: 在某些系统中,引导分区会被挂载到这个目录。

创建挂载点

sudo mkdir /media/sdcard

将sd卡设备挂载上去

sudo mount /dev/sda1 /media/sdcard

再次查看是否挂载,可以看到已经有挂载点了

image-20230929101709108

格式化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,来进行烧录。

imxdownloaddd 的区别:

  1. 特定性

    • imxdownload 是针对 NXP 的 i.MX 系列处理器设计的,而 dd 是一个通用的 UNIX 工具,可用于任何 UNIX 系统上,用于复制和转换文件。
  2. 接口

    • imxdownload 通常使用特定的硬件接口(例如 USB 或 UART)来烧录 i.MX 处理器,而 dd 则直接操作块设备,例如 SD 卡。
  3. 用途

    • imxdownload 主要用于烧录 bootloader 到 i.MX 处理器的内部存储或外部存储中,而 dd 可以用于复制任何文件和设备内容,包括制作和恢复磁盘映像。
  4. 操作层级

    • imxdownload 操作的是处理器级别,直接与处理器的 boot ROM 交互,而 dd 操作的是文件系统级别,与块设备交互。

选择工具:

  • 如果您正在使用 NXP 的 i.MX 系列处理器,并且需要通过特定的硬件接口烧录 bootloader,那么 imxdownload 可能是更合适的选择。
  • 如果您只是需要将 bootloader 烧录到一个块设备(例如 SD 卡)上,并且不需要特定的硬件接口,那么 dd 应该足够了。

举例说明:

  1. 使用特定硬件接口

    • 如果您使用的是 i.MX 处理器,并且需要通过 USB 接口来烧录 bootloader 到处理器的内部存储中,那么您可能需要使用 imxdownload 这样的特定工具。
  2. 不需要特定硬件接口

    • 如果您只是需要将 bootloader 烧录到一个 SD 卡上,这个 SD 卡可以直接通过计算机的 SD 卡读卡器访问,那么您可以使用 dd 命令,因为这种情况下不需要与特定的处理器或硬件接口进行直接通信。

简而言之,如果您的烧录过程只涉及到标准的、通用的块设备接口,例如 SD 卡读卡器,那么 dd 命令应该是足够的。如果烧录过程需要与特定的处理器或硬件平台的特定接口进行通信,那么您可能需要使用特定于该硬件平台的烧录工具。

dd工具烧录

我们使用dd工具来烧录吧,毕竟具有通用性

要将U-Boot烧写到SD卡,您通常会使用dd命令。dd命令可以用于复制文件或设备内容,通常用于制作或复制磁盘映像。在这种情况下,您将使用dd命令将编译好的U-Boot二进制文件(通常是u-boot.binu-boot.imx)复制到SD卡。

步骤:

  1. 找到U-Boot二进制文件

    • 确定U-Boot二进制文件的位置。这通常是u-boot.binu-boot.imx
  2. 卸载SD卡

    • 在写入之前,确保SD卡是卸载的。
    sudo umount /dev/sda1
  3. 使用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卡的分区表。
  4. 同步

    iflag=dsyncoflag=dsync,这两个选项会确保每次读取和写入都是同步的,这意味着每次读取或 写入操作都会等待物理 I/O 操作完成。这可以确保数据的完整性

注意:

  • 请小心使用dd命令,因为它会覆盖目标设备(在这种情况下是SD卡)的内容。确保of参数是正确的,以避免覆盖系统的其他部分。
  • 在执行dd命令之前,确保没有挂载SD卡的任何分区。
  • 请根据您的U-Boot版本和目标硬件,检查相关的文档以确定正确的dd命令参数,特别是bsseek参数。

了解以上内容以后,我的uboot 路径:/root/uboot

image-20230929105840414

查看挂在设备并卸载

lsblk
sudo umount /dev/sda1

image-20230929110000451

烧写U-Boot

注意:是sda,不是sda1分区

我当前是在uboot目录下

sudo dd iflag=dsync oflag=dsync if=u-boot.imx of=/dev/sda seek=2

image-20230929110521672

0.07S,一个字-->快, 不过看到这种一般是没烧写上去

查看所有sd

 ls /dev/sd*

image-20230929124421313

这里有一个虚拟的sdb ,删掉

sudo rm -rf /dev/sdb

再次查看

image-20230929124518698

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

image-20230929125820303

BOOT 设置从 SD 卡启

动,使用 USB 线将 USB_TTL 和电脑连接,也就是将开发板的串口 1 连接到电脑上。打开

MobaXterm,设置好串口参数并打开,最后复位开发板。在 MobaXterm 上出现“Hit any key to

stop autoboot: ”倒计时的时候按下键盘上的回车键,默认是 3 秒倒计时,在 3 秒倒计时结束以

后如果没有按下回车键的话 uboot 就会使用默认参数来启动 Linux 内核了。如果在 3 秒倒计时

结束之前按下回车键,那么就会进入 uboot 的命令行模式,否则会引导进入linux内核

可以理解为windows开机时的bios,开机狂按某个按键会进入bios,不按正常启动系统

image-20230929130009431

NXP官方工具imxdownload烧录

https://newbie-typora.oss-cn-shenzhen.aliyuncs.com/tools/imxdownload

将该工具放在uboot目录下,给予执行权限

image-20230929130624272

chmod 777 imxdownload

烧写命令 //烧写到SD卡中

./imxdownload u-boot.bin /dev/sda 

image-20230929130742589

再次将SD插入开发板启动看一下没问题的(115200)

image-20230929130852681

总结:

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

如果觉得我的文章对你有用,请随意赞赏