7. 定制自己的Uboot单板¶
7.1. 简介¶
我们提供的uboot中默认都是我们的开发板,虽说我们可以直接在我们的开发板上直接修改,使 uboot 可以完整的运行在我们的板子上。但是从学习的角度来讲,这样我们就不能了解到 uboot 是如何添加新平台的。接下来我们就参考我们的IMX6ULL开发板,学习如何在 uboot 中添加自己的开发板或者开发平台
7.2. 下载安装编译镜像系统¶
使用平台:Ubuntu 18.04.5 LTS 版本
可以使用我们提供的虚拟机镜像 https://doc.embedfire.com/products/link/zh/latest/linux/ebf_i.mx6ull.html#id4
也可以自己下载ubuntu 18.04.5 LTS官方镜像搭建
https://mirrors.aliyun.com/ubuntu-releases/bionic/ubuntu-18.04.5-desktop-amd64.iso
7.3. 安装编译工具和依赖¶
使用apt工具能快速安装好我们需要的工具和依赖
1 | sudo apt install make git gcc-arm-none-eabi gcc bison flex libssl-dev dpkg-dev lzop libncurses5-dev
|
7.4. 获取uboot¶
7.4.1. 下载源代码¶
下载我们的uboot源码
1 2 3 4 | git clone -b ebf_v2020_10_imx https://gitee.com/Embedfire/ebf_linux_uboot
#或者
git clone -b ebf_v2020_10_imx https://github.com/Embedfire/ebf_linux_uboot
|
7.5. 添加开发板默认配置文件¶
重要
下面以mmc版本为例,如果是nand版本把“mmc”改为“nand”即可。“name”可改为自己定义的名字。
先在 configs 目录下创建默认配置文件,复制 mx6ull_fire_mmc_defconfig,然后重命名为 mx6ull_name_mmc_defconfig,命令如下:
1 2 3 4 5 | cd configs/
cp mx6ull_fire_mmc_defconfig mx6ull_name_mmc_defconfig
#若为nand版本则是以下命令,后续“mmc”版本和“nand”版本区别说明不再重复
cp mx6ull_fire_nand_defconfig mx6ull_name_nand_defconfig
|
然后将文件mx6ull_name_mmc_defconfig中的CONFIG_SYS_EXTRA_OPTIONS内容改成如下
1 | CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_name/imximage.cfg"
|
board/freescale/mx6ull_name就是我们后续要添加的单板目录。
7.5.1. 添加头文件¶
复制一份include/configs/mx6ullfire.h更名为include/configs/mx6ull_name.h
1 | cp include/configs/mx6ullfire.h include/configs/mx6ull_name.h
|
更改
1 2 3 4 5 | #ifndef __MX6ULLFIRE_CONFIG_H
#define __MX6ULLFIRE_CONFIG_H
改为:
#ifndef __MX6ULL_NAME_CONFIG_H
#define __MX6ULL_NAME_CONFIG_H
|
以下是部分代码分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #define PHYS_SDRAM_SIZE SZ_512M
....
#define CONFIG_SYS_MALLOC_LEN (16 * SZ_1M)
....
#define CONFIG_MXC_UART_BASE UART1_BASE
....
#define CONFIG_SYS_FSL_ESDHC_ADDR USDHC2_BASE_ADDR
....
#CONFIG_EXTRA_ENV_SETTINGS "....."
....
#define CONFIG_BOOTCOMMAND "....."
....
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
#define CONFIG_SYS_HZ 1000
#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR
....
#define CONFIG_SYS_INIT_SP_OFFSET \
(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
#define CONFIG_SYS_INIT_SP_ADDR \
(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
#define CONFIG_MMCROOT "/dev/mmcblk1p2" /* USDHC2 */
#define CONFIG_FEC_ENET_DEV 1
#if (CONFIG_FEC_ENET_DEV == 0)
#define CONFIG_ETHPRIME "eth0"
#elif (CONFIG_FEC_ENET_DEV == 1)
#define CONFIG_ETHPRIME "eth1"
|
PHYS_SDRAM_SIZE :设置了SDRAM的内存大小
CONFIG_SYS_MALLOC_LEN :为malloc内存池大小,这里设置为16MB
CONFIG_MXC_UART_BASE :这里使用串口1,基地址为 UART1_BASE, UART1_BASE 定义在文件arch/arm/include/asm/arch-mx6/imx-regs.h 中, imx-regs.h 是 I.MX6ULL 寄存器描述文件,根据imx-regs.h 可得到 UART1_BASE 的值如下
1 2 3 4 | UART1_BASE= (ATZ1_BASE_ADDR + 0x20000)
=AIPS1_ARB_BASE_ADDR + 0x20000
=0x02000000 + 0x20000
=0X02020000
|
可以看到在手册中UART1的基地址
CONFIG_SYS_FSL_ESDHC_ADDR:宏CONFIG_SYS_FSL_ESDHC_ADDR为 EMMC 所使用接口的寄存器基地址,也就是 USDHC2 的基地址
CONFIG_EXTRA_ENV_SETTINGS : 通 过 条 件 编 译 来 设 置 宏 CONFIG_EXTRA_ENV_SETTINGS,宏CONFIG_EXTRA_ENV_SETTINGS 也是设置一些环境变量,此宏会设置bootargs这个环境变量
CONFIG_BOOTCOMMAND:设置宏 CONFIG_BOOTCOMMAND,此宏就是设置环境变量bootcmd的值。
CONFIG_SYS_LOAD_ADDR:表示 linux kernel 在DRAM中的加载地址,也就是 linux kernel 在 DRAM 中的存储首地址,CONFIG_LOADADDR=0X80800000
CONFIG_SYS_HZ:宏 CONFIG_SYS_HZ 为系统时钟频率,这里为 1000Hz。
PHYS_SDRAM:为 I.MX6ULL 的 DRAM 控制器 MMDC0 所管辖的 DRAM 范围起始地址,也就是 0X80000000
CONFIG_SYS_SDRAM_BASE:为 DRAM 的起始地址。
CONFIG_SYS_INIT_RAM_ADDR:为 I.MX6ULL 内部 IRAM 的起始地址(也就是 OCRAM 的起始地址),为 0X00900000
CONFIG_SYS_INIT_RAM_SIZE:为 I.MX6ULL 内部 IRAM 的大小(OCRAM的大小),为 0X00040000=128KB
CONFIG_SYS_INIT_SP_OFFSET和CONFIG_SYS_INIT_SP_ADDR:CONFIG_SYS_INIT_SP_OFFSET 和 CONFIG_SYS_INIT_SP_ADDR 与初始 SP 有关,第一个为初始 SP 偏移,第二个为初始 SP 地址
CONFIG_MMCROOT :设置进入 linux 系统的根文件系统所在的分区,这里设置为”/dev/mmcblk1p2”,也就是 EMMC 设备的第 2 个分区。第 0 个分区保存 uboot,第 1 个分区保存 linux 镜像和设备树,第 2 个分区为 Linux 系统的根文件系统
CONFIG_FEC_ENET_DEV:指定 uboot 所使用的网口, I.MX6ULL 有两个网口,为 0 的时候使用 ENET1,为 1 的时候使用 ENET2
CONFIG_VIDEO:用于开启 LCD,CONFIG_VIDEO_LOGO 使能 LOGO 显示, CONFIG_CMD_BMP 使能 BMP 图片显示指令。这样就可以在 uboot 中显示图片了,一般用于显示 logo。
关于 mx6ull_name_emmc.h 就讲解到这里,其中以 CONFIG_CMD 开头的宏都是用于使能相应命令的,其他的以 CONFIG 开头的宏都是完成一些配置功能的。以后会频繁的和mx6ull_name_emmc.h 这个文件打交道。
7.5.2. 添加单板目录和文件¶
uboot 中每个板子都有一个对应的文件夹来存放板级文件,比如开发板上外设驱动文件等等。 NXP 的 I.MX 系列芯片的所有板级文件夹都存放在 board/freescale 目录下,在这个目录下有个名为 mx6ullfire的文件夹,这个文件夹就是我们IMX6LL的开发板的板级文件夹。复制 mx6ullfire,将其重命名为 mx6ull_name,命令如下:
1 2 | cd board/freescale/
cp -rf mx6ullfire mx6ull_name
|
进入mx6ull_name目录中,将其中的mx6ullfire.c文件重命名为mx6ull_name.c,命令如下:
1 2 | cd mx6ull_name/
mv mx6ullfire.c mx6ull_name.c
|
将mx6ull_name.c里面的mx6ullfire.h头文件修改为mx6ull_name.h
1 | #include <configs/mx6ull_name.h>
|
mx6ull_name单板目录文件结构如下:
1 2 3 4 5 6 7 | ./mx6ull_name
├── imximage.cfg
├── Kconfig
├── MAINTAINERS
├── Makefile
├── mx6ull_name.c
└── plugin.S
|
mx6ull_name.c :里写了一些uboot启动代码和我们对板子引脚读取的代码
plugin.S :用汇编写的设置ddr和时钟,一般不需要更改
Makefile :里面修改C文件编译后的o文件,有多少个就写多少个o文件,注意与c文件名字相同
将Makefile里面的mx6ullfire.o修改为mx6ull_name.o
1 | obj-y := mx6ull_name.o
|
Kconfig :(目录:board/路径/目标文件夹/Kconfig)
将Kconfig修改为以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 | if TARGET_MX6ULL_FIRE //上面所说的两处对应其中的一处
config SYS_BOARD
default "mx6ull_name" //目标文件夹
config SYS_VENDOR
default "freescale" //路径
config SYS_CONFIG_NAME
default "mx6ull_name" //头文件名称 注意:头文件在include/configs下名称为"头文件名称.h"
endif
|
imximage.cfg :(目录:board/路径/目标文件夹)(NXP特有的文件,只需要修改一处即可,这是添加头部信息的)
将imximage.cfg文件里面的PLUGIN board/freescale/mx6ullfire/plugin.bin 0x00907000 修改为以下内容,更改单板目录:
1 | PLUGIN board/freescale/mx6ull_name /plugin.bin 0x00907000
|
7.5.3. 配置文件¶
emmc版本为 mx6ull_fire_mmc_defconfig
nand版本为 mx6ull_fire_nand_defconfig
以下以emmc版本为例:
1 | cp configs/mx6ull_fire_mmc_defconfig configs/mx6ull_name_defconfig
|
这里有几个参数要注意一下
CONFIG_TARGET_MX6ULL_FIRE=y 这行参数与两处有相对应,下面会讲到,这里留意一下。
CONFIG_DEFAULT_DEVICE_TREE= 这行参数是设备树名称,要与uboot设备树对应,将其修改为如下配置:
1 | CONFIG_DEFAULT_DEVICE_TREE="imx6ull-name-mmc"
|
因为后续准备使用的设备树为imx6ull-name-mmc.dts。
CONFIG_SYS_EXTRA_OPTIONS= 这行参数是配置头部信息的,指向的是板子目录的cfg文件,将其修改为如下配置,改为我们单板目录。
1 | CONFIG_SYS_EXTRA_OPTIONS=="IMX_CONFIG=board/freescale/mx6ull_name/imximage.cfg"
|
7.5.4. 添加Kconfig信息¶
在这个文件中添加我们的板子信息方便Makefile识别编译
修改文件目录为:arch/arm/mach-imx/mx6/Kconfig
7.5.4.1. 修改U-Boot图形界面配置文件¶
在config TARGET_MX6ULL_14X14_EVK配置的下面添加如下代码
1 2 3 4 5 6 7 | config TARGET_MX6ULL_FIRE
bool "Support mx6ull_name"
depends on MX6ULL
select BOARD_LATE_INIT
select DM
select DM_THERMAL
imply CMD_DM
|
在source “board/freescale/mx6ullevk/Kconfig”下添加如下代码
1 | source "board/freescale/mx6ull_name/Kconfig"
|
7.5.5. 添加设备树¶
7.5.5.1. 添加设备树信息¶
修改文件目录为:arch/arm/dts/Makefile
在dtb-$(CONFIG_MX6ULL) += 下面添加(为什么在这添加,因为配置文件里设置了CONFIG_MX6ULL=y)
设备树的名字,参考config里的CONFIG_DEFAULT_DEVICE_TREE=”imx6ull-name-mmc”
添加内容:imx6ull-name-mmc.dtb
1 2 3 4 5 6 7 8 9 10 11 | dtb-$(CONFIG_MX6ULL) += \
imx6ull-14x14-evk.dtb \
imx6ull-fire-mmc.dtb \
imx6ull-fire-nand.dtb \
imx6ull-name-mmc.dtb \
imx6ull-colibri.dtb \
imx6ull-myir-mys-6ulx-eval.dtb \
imx6ull-phytec-segin-ff-rdk-emmc.dtb \
imx6ull-dart-6ul.dtb \
imx6ull-somlabs-visionsom.dtb \
imx6ulz-14x14-evk.dtb
|
7.5.5.2. 复制设备树源码¶
1 | cp arch/arm/dts/imx6ull-fire-mmc.dts arch/arm/dts/imx6ull-name-mmc.dts
|
7.5.6. 编译¶
1 2 3 4 | make distclean
make mx6ull_name_mmc_defconfig
#编译uboot
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
|