U-Boot的基本使用

直接参考【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.81

本文仅作为个人笔记使用,方便进一步记录自己的实践总结。

在上一篇中我们学习了如何进行 I.MX6U 的裸机开发,通过 21 个裸机例程我们掌握了I.MX6U 的常用外设。通过裸机的学习我们掌握了外设的底层原理,这样在以后进行 Linux 驱动开发的时候就只需要将精力放到 Linux 驱动框架上,在进行 Linux 驱动开发之前肯定需要先将Linux 系统移植到开发板上去。如果学习过 UCOS/FreeRTOS 应该知道,UCOS/FreeRTOS 移植就是在官方的 SDK 包里面找一个和自己所使用的芯片一样的工程编译一下,然后下载到开发板就可以了。那么 Linux 的移植是不是也是这样的,下载 Linux 源码,然后找个和我们所使用的芯片一样的工程编译一下就可以了?很明显不是的!Linux 的移植要复杂的多,在移植 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 开发板上跑起来。

首先,讲解U-Boot.

在移植 U-Boot 之前,我们肯定要先使用一下 U-Boot,得先体验一下 U-Boot 是个什么东西。I.MX6U-ALPHA 开发板光盘资料里面已经提供了一个正点原子团队已经移植好的 U-Boot,本章我们就直接编译这个移植好的 U-Boot,然后烧写到 SD 卡里面启动,启动 U-Boot 以后就可以学习使用 U-Boot 的命令。

U-Boot 简介

Linux 系统要启动就必须需要一个 bootloader 程序,也就说芯片上电以后先运行一段bootloader 程序。这段bootloader程序会先初始化DDR等外设,然后将Linux内核从flash(NAND,NOR FLASH,SD,MMC 等)拷贝到 DDR 中,最后启动 Linux 内核。当然了,bootloader 的实际工作要复杂的多,但是它最主要的工作就是启动 Linux 内核,bootloader 和 Linux 内核的关系就跟 PC 上的 BIOS 和 Windows 的关系一样,bootloader 就相当于 BIOS。所以我们要先搞定bootloader,很庆幸,有很多现成的 bootloader 软件可以使用,比如 U-Boot、vivi、RedBoot 等等,其中以 U-Boot 使用最为广泛,为了方便书写,本书会将 U-Boot 写为 uboot。uboot 的全称是 Universal Boot Loader,uboot 是一个遵循 GPL 协议的开源软件,uboot 是一个裸机代码,可以看作是一个裸机综合例程。现在的 uboot 已经支持液晶屏、网络、USB 等高级功能。uboot 官网为 The U-Boot Documentation — Das U-Boot unknown version documentation,如图 30.1.1 所示:

我们可以在 uboot 官网下载 uboot 源码,点击图 30.1.1 中左侧 Topics 中的“Source Code”,打开如图 30.1.2 所示界面:

点击图 30.1.2 中的“FTP Server”,进入其 FTP 服务器即可看到 uboot 源码,如图 30.1.3 所示:

图 30.1.3 中就是 uboot 原汁原味的源码文件,目前最新的版本是 2019.04。但是我们一般不会直接用 uboot 官方的 U-Boot 源码的。uboot 官方的 uboot 源码是给半导体厂商准备的,半导体厂商会下载 uboot 官方的 uboot 源码,然后将自家相应的芯片移植进去。也就是说半导体厂商会自己维护一个版本的 uboot,这个版本的 uboot 相当于是他们定制的。既然是定制的,那么肯定对自家的芯片支持会很全,虽然 uboot 官网的源码中一般也会支持他们的芯片,但是绝对是没有半导体厂商自己维护的 uboot 全面。

NXP就维护 的2016.03这 个 版 本 的uboot , 下 载 地 址 为 :

GitHub - nxp-imx/uboot-imx: i.MX U-Boot

下载界面如图 30.1.4 所示:

图 30.1.4 中的 uboot-imx_rel_imx4.1.15_2.1.0_ga.xx(xx 为 zip、tar.gz 或 tar.bz2)就是 NXP 官方维护的 uboot,后面我们学习 uboot 移植的时候就是使用的图 30.1.4 中的 uboot,下载 uboot imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2。我们已经放到了开发板光盘中,路径为:开发板光盘->1、程序源码->4、NXP官方原版Uboot和Linux->uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2。图30.1.4中的 uboot 基本支持了 NXP 当前所有可以跑 Linux 的芯片,而且支持各种启动方式,比如 EMMC、NAND、NOR FLASH 等等,这些都是 uboot 官方所不支持的。但是图 30.1.4 中的 uboot 是针对NXP 自家评估板的,如果是我们自己做的板子就需要修改 NXP 官方的 uboot,使其支持我们自己做的板子,正点原子的 I.MX6U 开发板就是自己做的板子,虽然大部分都参考了 NXP 官方的I.MX6ULL EVK 开发板,但是还是有很多不同的地方,所以需要修改 NXP 官方的 uboot,使其适配正点原子的 I.MX6U 开发板。所以当我们拿到开发板以后,是有三种 uboot 的,这三种 uboot的区别如表 30.1.1 所示:

那么这三种 uboot 该如何选择呢?首先 uboot 官方的基本是不会用的,因为支持太弱了。最常用的就是半导体厂商或者开发板厂商的 uboot,如果你用的半导体厂商的评估板,那么就使用半导体厂商的 uboot,如果你是购买的第三方开发板,比如正点原子的 I.MX6ULL 开发板,那么就使用正点原子提供的 uboot 源码(也是在半导体厂商的 uboot 上修改的)。当然了,你也可以在购买了第三方开发板以后使用半导体厂商提供的 uboot,只不过有些外设驱动可能不支持,需要自己移植,这个就是我们常说的 uboot 移植。

本节是 uboot 的使用,所以就直接使用正点原子已经移植好的 uboot,这个已经放到了开发板光盘中了,路径为:开发板光盘->1、程序源码->3、正点原子 Uboot 和 Linux 出厂源码->uboot imx-2016.03-2.1.0-ge468cdc-v1.5.tar.bz2。

U-Boot 初次编译

首先在 Ubuntu 中安装 ncurses 库,否则编译会报错,安装命令如下:

sudo apt-get install libncurses5-dev

在 Ubuntu 中创建存放 uboot 的目录,比如我的是/home/$USER/linux/uboot,然后在此目录下新建一个名为“alientek_uboot”的文件夹用于存放正点原子提供的 uboot 源码。alientek_uboot文件夹创建成功以后使用 FileZilla 软件将正点原子提供的 uboot 源码拷贝到此目录中,正点原子提供的 uboot 源码已经放到了开发板光盘中,路径为:开发板光盘->1、例程源码->3、正点原子 Uboot 和 Linux 出厂源码-> uboot-imx-2016.03-2.1.0-ge468cdc-v1.5.tar.bz2。将其拷贝到 Ubuntu中新建的 alientek_uboot 文件夹下,完成以后如图 30.2.1 所示:

图 30.2.1 将 uboot 拷贝到 Ubuntu 中使用如下命令对其进行解压缩:

tar -vxjf uboot-imx-2016.03-2.1.0-g8b546e4.tar.bz2

解压完成以后 alientek_uboot 文件夹内容如图 30.2.2 所示:

图 30.2.2 中除了 uboot-imx-2016.03-2.1.0-g8b546e4.tar.bz2 这个正点原子提供的 uboot 源码压缩包以外,其他的文件和文件夹都是解压出来的 uboot 源码。

如果使用的是 512MB+8GB 的 EMMC 核心板,使用如下命令来编译对应的 uboot:

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

这三条命令中 ARCH=arm 设置目标为 arm 架构,CROSS_COMPILE 指定所使用的交叉编译器。第一条命令相当于“make distclean”,目的是清除工程,一般在第一次编译的时候最好清理一下工程。第二条指令相当于“make mx6ull_14x14_ddr512_emmc_defconfig”,用于配置 uboot,配置文件为 mx6ull_14x14_ddr512_emmc_defconfig。最后一条指令相当于 “make -j12”也就是使用 12 核来编译 uboot。当这三条命令执行完以后 uboot 也就编译成功了,如图 30.2.3 所示:

编译完成以后的 alentek_uboot 文件夹内容如图 30.2.4 所示:

可以看出,编译完成以后 uboot 源码多了一些文件,其中 u-boot.bin 就是编译出来的 uboot二进制文件。uboot是个裸机程序,因此需要在其前面加上头部(IVT、DCD等数据)才能在I.MX6U上执行,图 30.2.4 中的 u-boot.imx 文件就是添加头部以后的 u-boot.bin,u-boot.imx 就是我们最终要烧写到开发板中的 uboot 镜像文件。

每次编译 uboot 都要输入一长串命令,为了简单起见,我们可以新建一个 shell 脚本文件,将这些命令写到 shell 脚本文件里面,然后每次只需要执行 shell 脚本即可完成编译工作。新建名为 mx6ull_alientek_emmc.sh 的 shell 脚本文件,然后在里面输入如下内容:

示例代码 30.2.1 mx6ull_alientek_emmc.sh 文件代码
1 #!/bin/bash
2 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
3 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
4 make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12

第 1 行是 shell 脚本要求的,必须是“#!/bin/bash”或者“#!/bin/sh”。

第 2 行使用了 make 命令,用于清理工程,也就是每次在编译 uboot 之前都清理一下工程。这里的 make 命令带有三个参数,第一个是 ARCH,也就是指定架构,这里肯定是 arm;第二个参数 CROSS_COMPILE 用于指定编译器,只需要指明编译器前缀就行了,比如 arm-linux-gnueabihf-gcc 编译器的前缀就是“arm-linux-gnueabihf-”;最后一个参数 distclean 就是清除工程。

第 3 行也使用了 make 命令,用于配置 uboot。同样有三个参数,不同的是,最后一个参数是 mx6ull_14x14_ddr512_emmc_defconfig。前面说了 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 目录中。

第 4 行有 4 个参数,用于编译 uboot,通过第 3 行配置好 uboot 以后就可以直接“make”编译 uboot 了。其中 V=1 用于设置编译过程的信息输出级别;-j 用于设置主机使用多少线程编译uboot,最好设置成我们虚拟机所设置的核心数,如果在 VMware 里面给虚拟就分配了 4 个核,那么使用-j4 是最合适的,这样 4 个核都会一起编译。

使用 chmod 命令给予 mx6ull_alientek_emmc.sh 文件可执行权限,然后就可以使用这个 shell脚本文件来重新编译 uboot,命令如下:

./mx6ull_alientek_emmc.sh

更多待补充。 

配置defconfig时报错

关键在这一句

/bin/sh: 1: cc: not found

cc未找到,这是因为linux环境没有安装gcc,虽然已经安装了交叉编译工具链,但是也要基本的gcc的支持。

使用以下命令安装gcc即可

sudo apt install gcc

安装后再配置defconfig如下所示:

U-Boot 烧写与启动

uboot 编译好以后就可以烧写到板子上使用了,这里我们跟前面裸机例程一样,将 uboot烧写到 SD 卡中,然后通过 SD 卡来启动来运行 uboot。使用 imxdownload 软件烧写,命令如下:

chmod 777 imxdownload //给予 imxdownload 可执行权限,一次即可
./imxdownload u-boot.bin /dev/sdd //烧写到 SD 卡,不能烧写到/dev/sda 或 sda1 设备里面!

等待烧写完成,完成以后将 SD 卡插到 I.MX6U-ALPHA 开发板上,BOOT 设置从 SD 卡启动,使用 USB 线将 USB_TTL 和电脑连接,也就是将开发板的串口 1 连接到电脑上。打开MobaXterm,设置好串口参数(默认波特率115200)并打开,最后复位开发板。在 MobaXterm 上出现“Hit any key to stop autoboot: ”倒计时的时候按下键盘上的回车键,默认是 3 秒倒计时,在 3 秒倒计时结束以后如果没有按下回车键的话 uboot 就会使用默认参数来启动 Linux 内核了。如果在 3 秒倒计时结束之前按下回车键,那么就会进入 uboot 的命令行模式,如图 30.3.1 所示:

从图 30.3.1 可以看出,当进入到 uboot 的命令行模式以后,左侧会出现一个“=>”标志。

uboot 启动的时候会输出一些信息,这些信息如下所示:

示例代码 30.3.1 uboot 输出信息
1 U-Boot 2016.03-gd3f0479 (Aug 07 2020 - 20:47:37 +0800)
2
3 CPU: Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)
4 CPU: Industrial temperature grade (-40C to 105C) at 51C
5 Reset cause: POR
6 Board: I.MX6U ALPHA|MINI
7 I2C: ready
8 DRAM: 512 MiB
9 MMC: FSL_SDHC: 0, FSL_SDHC: 1
10 Display: ATK-LCD-7-1024x600 (1024x600)
11 Video: 1024x600x24
12 In: serial
13 Out: serial
14 Err: serial
15 switch to partitions #0, OK
16 mmc1(part 0) is current device
17 Net: FEC1
18 Error: FEC1 address not set.
19
20 Normal Boot
21 Hit any key to
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值