UBOOT、KERNEL移植过程(一)

Linux搭建环境

​ 在进行UBOOT、KERNEL移植之前,需要先在Linux下搭建好开发环境,基本的有tftp环境、nfs环境、交叉编译工具链的搭建

报错处理

​ tftp和nfs环境搭建时,如果配置文件写错,重启服务时会有报错提示,此时需要查看系统日志根据日志消息解决问题

1
2
3
4
# 查看系统日志指令
tail -f /var/log/syslog
# 或是查看倒数10条日志
tail -10 /var/log/syslog

tftp环境

​ tftp协议:

典型的cs模型: ubuntu为服务器端,开发板为客户端

客户端可以下载服务器端上的内容,效率高

1、查看是否已经安装tftp服务器

1
dpkg -s tftpd-hda

2、若不存在则执行以下命令安装tftp服务

1
2
3
4
5
# 更新apt源
sudo apt-get updata
# 安装tftp相关服务
# tftpd-hpa是服务器 tftp-hda是客户端
sudo apt-get install tftpd-hpa tftp-hpa -y

3、创建服务器工作路径并设置为最高权限

1
2
3
4
# 在用户路径下创建tftp文件夹作为tftp共享文件夹
sudo mkdir ~/tftp
# 设置权限
sudo chmod 777 ~/tftp -R

4、修改tftp服务器配置文件

1
2
# 修改配置文件
sudo vim /etc/default/tftpd-hpa
1
2
3
4
5
6
7
# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp" # 命令名称
TFTP_DIRECTORY="/home/noah/tftp" # tftp共享路径
TFTP_ADDRESS=":69" # tftp使用的端口
TFTP_OPTIONS="-c -s -l" # tftp命令默认选项

5、重启tftp服务,使配置生效

1
sudo service tftpd-hpa restart

6、自行测试是否安装成功

nfs环境

网络文件系统(英语:Network File System,缩写作 NFS),搭建好后相当于在远程有一套文件系统,目的是使客户端主机可以访问服务器端文件,并且其过程与访问本地存储时一样

1、查看是否已经安装NFS

1
dpkg -s nfs-kernel-server

2、若不存在则执行以下命令安装tftp服务

1
2
3
4
# 更新apt源
sudo apt-get updata
# 安装nfs-kernel-server相关服务
sudo apt-get install nfs-kernel-server -y

3、创建服务器工作路径并设置为最高权限

1
2
3
4
# 在用户路径下创建nfs文件夹
sudo mkdir -p ~/nfs/rootfs
# 设置权限
sudo chmod 777 ~/nfs/rootfs -R

4、修改nfs服务器配置文件

1
sudo vim /etc/exports
1
2
3
# 在文章的末尾添加
# 这里设置 IP为 * 即允许所有客户端挂载
/home/noah/nfs/rootfs/ *(rw,sync,no_subtree_check,no_root_squash)

这一行的详细释义为

1
2
3
# 此为示例
/home/test 192.168.121.0/24(rw)
# 共享文件路径 允许共享网段(共享文件可执行权限)

共享文件可执行权限的详细释义为:

参数 说明
ro 只读访问
rw 读写访问
sync 所有数据在请求时写入共享
async nfs 在写入数据前可以响应请求
secure nfs 通过 1024 以下的安全 TCP/IP 端口发送
insecure nfs 通过 1024 以上的端口发送
wdelay 如果多个用户要写入 nfs 目录,则归组写入(默认)
no_wdelay 如果多个用户要写入 nfs 目录,则立即写入,当使用 async 时,无需此设置
hide 在 nfs 共享目录中不共享其子目录
no_hide 共享 nfs 目录的子目录
subtree_check 如果共享 /usr/bin 之类的子目录时,强制 nfs 检查父目录的权限(默认)
no_subtree_check 不检查父目录权限
all_squash 共享文件的 UID 和 GID 映射匿名用户 anonymous,适合公用目录
no_all_squash 保留共享文件的 UID 和 GID(默认)
root_squash root 用户的所有请求映射成如 anonymous 用户一样的权限(默认)
no_root_squash root 用户具有根目录的完全管理访问权限
anonuid=xxx 指定 nfs 服务器 /etc/passwd 文件中匿名用户的 UID
anongid=xxx 指定 nfs 服务器 /etc/passwd 文件中匿名用户的 GID

5、重启nfs服务,使得配置生效

1
sudo service nfs-kernel-server restart

交叉编译工具链

Buildroot制作交叉编译器

​ 一般来说,制作交叉编译器,有两种工具,即crosstool-NGBuildroot,制作交叉编译器仅是第一步,后续还需要使用交叉编译器移植bootloader、kernel和制作根文件系统rootfs以及交叉编译各种需要的应用程序。其中 crosstool-NG 只是制作了一个交叉编译器,而如果你希望一键完成这所有的事情, 则可以使用 Buildroot

Buildroot是一组MakefilePatch文件,用来简化和自动化为嵌入式系统建造一个完整和可引导的Linux环境的过程,特别是在使用交叉编译来允许在单一的基于Linux的开发系统上为多个目标平台进行建造的时候。Buildroot可以自动建造所需要的交叉编译工具链,创建根文件系统,编译一个Linux内核映像,并为目标嵌入式系统生成引导装载器,它还可以进行这些独立步骤的任何组合。

​ 接下来我们将介绍如何使用 buildroot 来制作交叉编译器,同时生成一个开发板可以使用的根文件系统。需要注意的是,因为 Linux 内核 和 u-boot 今后需要自己针对开发板做移植修改,所以这里将不编译 Linux内核 和 u-boot 程序。

使用Buildroot构建交叉编译工具链请看郭工的文档:i.MX6ULL开发板-Buildroot制作交叉编译器

Uboot

​ uboot是BootLoader的一种,可以利用uboot制作sd卡启动盘,下面是uboot的详细介绍

​ U-Boot,全称 Universal Boot Loader,是遵循GPL条款的从FADSROM、8xxROM、PPCBOOT逐步发展演化而来的 开放源码项目。

​ U-boot,是一个主要用于嵌入式系统的引导加载程序,可以支持多种不同的计算机系统结构,其主要作用为:引导系统的启动。

​ 目前,U-Boot不仅支持Linux系统的引导,还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS, android等多种嵌入式操作系统。

uboot开发源码

uboot目录结构

目录名称 主要内容
api uboot中的接口函数
arch uboot中有关处理器架构的相关的代码
board 为开发板定制的相关代码
common 通用代码,大部分与命令行有关
disk 磁盘分区相关代码
doc 有关README、.md、.txt相关代码
drivers 与驱动程序相关的代码
examples 示例程序
fs 文件系统,适合大部分开发板上的文件系统
include 包含全局的头文件
lib 通用库文件
net 网络相关代码,小型协议栈
post Power On Self Test,上电自检程序
tools 辅助程序,用于编译和检查uboot目标文件

移植Uboot

配置uboot defconfig

准备:下载好郭工文件服务器下提供的imx6ull的相关源码,使用的芯片为imx6ull,对应板卡为“IGKBoard”

在下载的imx6ull的文件夹下,进入uboot的configs文件夹

找到igkboard_defconfig

1
2
noah@ubuntu:~/imx6ull$ cd bsp/bootloader/uboot-imx/configs/
noah@ubuntu:~/imx6ull/bsp/bootloader/uboot-imx/configs$ find ig*
1
2
# 查看igkboard_defconfig
vim igkboard_defconfig

以下是详细释义

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
CONFIG_ARM=y                       # 使用ARM体系结构
CONFIG_ARCH_MX6=y # 指定为i.MX 6处理器架构
CONFIG_SYS_MALLOC_LEN=0x1000000 # 分配1MB内存作为堆空间(malloc)
CONFIG_NR_DRAM_BANKS=1 # 内存条银行数量为1
CONFIG_SYS_MEMTEST_START=0x80000000# 内存测试开始地址
CONFIG_SYS_MEMTEST_END=0x88000000 # 内存测试结束地址
CONFIG_ENV_SIZE=0x2000 # 环境变量大小为8KB
CONFIG_ENV_OFFSET=0xE0000 # 环境变量偏移地址
CONFIG_IMX_CONFIG="board/lingyun/igkboard/imximage.cfg" # i.MX配置文件路径
CONFIG_SYS_PROMPT="[u-boot@igkboard]# " # U-Boot 命令行提示符
CONFIG_MX6ULL=y # 配置为MX6ULL型号
CONFIG_TARGET_LINGYUN_IGKBOARD=y # 配置目标板为Lingyun IGKBoard
CONFIG_SYS_I2C_MXC_I2C1=y # 配置I2C1总线支持
CONFIG_SYS_I2C_MXC_I2C2=y # 配置I2C2总线支持
CONFIG_DM_GPIO=y # 配置使用GPIO驱动模型
CONFIG_DEFAULT_DEVICE_TREE="igkboard" # 默认设备树为igkboard.dtb
CONFIG_SUPPORT_RAW_INITRD=y # 支持直接使用裸镜像启动
CONFIG_USE_BOOTCOMMAND=y # 启用自定义的bootcmd命令
CONFIG_BOOTDELAY=3 # 自动启动延迟时间为3秒
# CONFIG_CONSOLE_MUX is not set # 控制台多路复用未配置
CONFIG_SYS_CONSOLE_IS_IN_ENV=y # 将控制台设置在环境变量里
CONFIG_BOARD_EARLY_INIT_F=y # 配置brought up函数指针
CONFIG_HUSH_PARSER=y # 启用Hush shell解析器
CONFIG_CMD_BOOTZ=y # 支持 bootz 命令
# CONFIG_CMD_IMLS is not set # 禁止支持 imls 命令
CONFIG_CMD_MEMTEST=y # 支持 memtest 命令
CONFIG_CMD_GPIO=y # 支持 gpio 命令
CONFIG_CMD_I2C=y # 支持 i2c 命令
CONFIG_CMD_MMC=y # 支持 mmc 命令
CONFIG_CMD_SF=y # 支持 spi flash 命令
CONFIG_CMD_USB=y # 支持 usb 命令
CONFIG_CMD_DHCP=y # 支持 dhcp 命令
CONFIG_CMD_PING=y # 支持 ping 命令
CONFIG_CMD_BMP=y # 支持 bmp 命令
CONFIG_CMD_CACHE=y # 支持 cache 命令
CONFIG_CMD_NET=y # 支持 net 命令
CONFIG_CMD_EXT2=y # 支持 ext2 文件系统
CONFIG_CMD_EXT4=y # 支持 ext4 文件系统
CONFIG_CMD_EXT4_WRITE=y # 支持写入 ext4 文件系统
CONFIG_CMD_FAT=y # 支持 fat 文件系统
CONFIG_CMD_FS_GENERIC=y # 支持文件系统通用命令
CONFIG_OF_CONTROL=y # 支持使用设备树
CONFIG_ENV_OVERWRITE=y # 允许覆盖环境变量
CONFIG_ENV_IS_IN_MMC=y # 环境变量保存在MMC中
CONFIG_SYS_RELOC_GD_ENV_ADDR=y # 重定位地址设置为环境变量地址
CONFIG_SYS_MMC_ENV_DEV=1 # MMC中环境变量分区所在的设备号
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y # 启用uboot运行时配置的环境变量
CONFIG_BOUNCE_BUFFER=y # 启用内存缓冲区用于DMA操作
CONFIG_DM_74X164=y # 启用74X164设备模型支持
CONFIG_DM_I2C=y # 启用I2C设备模型支持
CONFIG_SYS_I2C_MXC=y # 启用i.MX系列的I2C控制器
CONFIG_FSL_USDHC=y # 启用i.MX系列的USDHC(SD卡/SDIO)控制器支持
CONFIG_MTD=y # 启用存储器设备支持
CONFIG_DM_SPI_FLASH=y # 启用SPI Flash设备模型支持
CONFIG_SF_DEFAULT_SPEED=40000000 # 设置SPI Flash的默认速度为40MHz
CONFIG_SPI_FLASH_STMICRO=y # 启用ST微电子的SPI Flash支持
CONFIG_PHYLIB=y # 启用物理层驱动库支持
CONFIG_PHY_MICREL=y # 启用Micrel系列物理层驱动支持
CONFIG_PHY_MICREL_KSZ8XXX=y # 启用KSZ8XXX系列物理层驱动支持
CONFIG_DM_ETH=y # 启用以太网设备模型支持
CONFIG_DM_ETH_PHY=y # 启用以太网物理层设备模型支持
CONFIG_FEC_MXC=y # 启用i.MX系列的FEC(以太网控制器)支持
CONFIG_MII=y # 启用MII(媒体独立接口)支持
CONFIG_PINCTRL=y # 启用引脚控制器支持
CONFIG_PINCTRL_IMX6=y # 启用i.MX6系列的引脚控制器支持
CONFIG_DM_REGULATOR=y # 启用电源调节器设备模型支持
CONFIG_DM_REGULATOR_FIXED=y # 启用固定电源调节器设备模型支持
CONFIG_DM_REGULATOR_GPIO=y # 启用GPIO电源调节器设备模型支持
CONFIG_MXC_UART=y # 启用i.MX系列的UART支持
CONFIG_SPI=y # 启用SPI总线支持
CONFIG_DM_SPI=y # 启用SPI设备模型支持
CONFIG_FSL_QSPI=y # 启用i.MX系列的QSPI(快速SPI)支持
CONFIG_SOFT_SPI=y # 启用软件模拟的SPI支持
CONFIG_IMX_THERMAL=y # 启用i.MX系列的热管理支持
CONFIG_USB=y # 启用USB支持
CONFIG_USB_STORAGE=y # 启用USB存储支持
CONFIG_CMD_USB_MASS_STORAGE=y # 启用USB大容量存储命令支持
CONFIG_USB_HOST_ETHER=y # 启用USB主机以太网支持
CONFIG_USB_ETHER_ASIX=y # 启用ASIX系列USB以太网适配器支持
CONFIG_DM_VIDEO=y # 启用视频设备模型支持
CONFIG_VIDEO_LOGO=y # 启用uboot启动时的视频logo支持
CONFIG_SYS_WHITE_ON_BLACK=y # 设置uboot的控制台颜色为白底黑字
CONFIG_VIDEO_MXS=y # 启用i.MX系列的视频显示支持
CONFIG_SPLASH_SCREEN=y # 启用启动画面支持
CONFIG_SPLASH_SCREEN_ALIGN=y # 对齐启动画面
CONFIG_BMP_16BPP=y # 启用16位BMP格式的启动画面支持

CONFIG_USB_GADGET=y # 启用USB Gadget支持
CONFIG_USB_GADGET_DOWNLOAD=y # 启用USB下载Gadget支持
CONFIG_USB_GADGET_MANUFACTURER="FSL" # 设置USB Gadget的制造商字符串为"FSL"
CONFIG_USB_GADGET_VENDOR_NUM=0x0525 # 设置USB Gadget的供应商ID为0x0525
CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 # 设置USB Gadget的产品ID为0xa4a5
CONFIG_CI_UDC=y # 启用USB设备控制器模式(CI_UDC)

CONFIG_CMD_FASTBOOT=y # 启用Fastboot命令支持
CONFIG_USB_FUNCTION_FASTBOOT=y # 启用Fastboot USB功能支持
CONFIG_FASTBOOT_UUU_SUPPORT=y # 启用UUU工具的Fastboot支持
CONFIG_FASTBOOT=y # 启用Fastboot支持
CONFIG_FASTBOOT_BUF_ADDR=0x83800000 # 设置Fastboot缓冲区的起始地址为0x83800000
CONFIG_FASTBOOT_BUF_SIZE=0x40000000 # 设置Fastboot缓冲区的大小为0x40000000
CONFIG_FASTBOOT_FLASH=y # 启用Fastboot刷写闪存支持
CONFIG_EFI_PARTITION=y # 启用EFI分区支持
CONFIG_ARCH_MISC_INIT=y # 启用架构相关的杂项初始化
CONFIG_DM_RNG=y # 启用RNG设备模型支持
CONFIG_CMD_RNG=y # 启用RNG命令支持
CONFIG_FSL_DCP_RNG=y # 启用FSL DCP硬件随机数生成器支持
CONFIG_OF_SYSTEM_SETUP=y # 启用设备树系统设置支持
CONFIG_CMD_CRC32=y # 启用CRC32命令支持
CONFIG_CRC32_VERIFY=y # 启用CRC32校验支持

CONFIG_OF_LIBFDT_OVERLAY=y # 启用设备树覆盖支持
CONFIG_NET_RANDOM_ETHADDR=y # 启用网络随机MAC地址支持
CONFIG_DM_SERIAL=y # 启用串行设备模型支持


需要特别注意的是这几行,其他为对板卡的系统设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 这是指定我们板子的设备树配置,原版设置为
# CONFIG_DEFAULT_DEVICE_TREE="imx6ull-14x14-evk-emmc"
# 这里修改默认的设备树文件
CONFIG_DEFAULT_DEVICE_TREE="igkboard" # 默认设备树为igkboard.dtb

CONFIG_IMX_CONFIG="board/lingyun/igkboard/imximage.cfg" # i.MX配置文件路径

CONFIG_SYS_PROMPT="[u-boot@igkboard]# " # U-Boot 命令行提示符



# 这里原版NXP官方EVK开发板的为
# CONFIG_TARGET_MX6ULL_14X14_EVK=y
# 这里修改为自己的板子
CONFIG_TARGET_LINGYUN_IGKBOARD=y # 配置目标板为Lingyun IGKBoard

​ 根据前面分类可知,board文件夹下是为开发板定制的相关代码,那么其指示的i.MX配置文件即为郭工对igkboard板卡的定制配置文件。

​ 同时这里还指定了uboot的命令行指示符和默认的igkboard.dtb,一个是进入uboot命令窗时配置的命令行提示,一个是查找文件目录下的设备树指定名称并引导,这也告诉了我们为什么前面驱动学习的时候为什么设备树编译出来的文件名称一定是igkboard.btb。

添加开发板对应的头文件

​ 添加开发板对应的头文件,操作的目录在 “include/configs/”下

1
2
# 不要执行此命令,仅是做示例,否则将覆盖郭工已经修改好的igkboard.h
cp mx6ullevk.h igkboard.h

​ 这就创建了自己开发板的头文件,接下来对igkboard.h进行自定义修改

uboot包含什么功能基本上都是由这个文件控制,换句话说我们可以根据这个文件完成对uboot的裁剪。

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* 这段代码使用条件编译,它的作用是检查是否已经定义了 __IGKBOARD_CONFIG_H 宏,如果未定义,则定义它,以避免重复包含。 */
#ifndef __IGKBOARD_CONFIG_H
#define __IGKBOARD_CONFIG_H

/* 这些是头文件的包含指令,包含了一些需要在此配置文件中使用的系统和硬件相关的头文件。 */
#include <asm/arch/imx-regs.h>
#include <linux/sizes.h>
#include <linux/stringify.h>
#include "mx6_common.h"
#include <asm/mach-imx/gpio.h>
#include "imx_env.h"

/* 这是一个宏定义,用于检查是否启用了 TARGET_MX6ULL_9X9_EVK 配置。如果启用了该配置,宏 is_mx6ull_9x9_evk() 将返回非零值,否则返回零。 */
#define is_mx6ull_9x9_evk() CONFIG_IS_ENABLED(TARGET_MX6ULL_9X9_EVK)

/* 这是一个条件编译块,根据是否启用了 CONFIG_TARGET_MX6ULL_9X9_EVK 配置,设置了物理内存的大小 (PHYS_SDRAM_SIZE) 和 CMA 大小 (BOOTARGS_CMA_SIZE)。 */
#ifdef CONFIG_TARGET_MX6ULL_9X9_EVK
#define PHYS_SDRAM_SIZE SZ_256M
#define BOOTARGS_CMA_SIZE "cma=96M "
#else
#define PHYS_SDRAM_SIZE SZ_512M
#define BOOTARGS_CMA_SIZE ""
/* DCDC used on 14x14 EVK, no PMIC */
#undef CONFIG_LDO_BYPASS_CHECK
#endif

/* 这是指定 MXC UART 的基地址的宏定义,将 UART1 的基地址设置为 CONFIG_MXC_UART_BASE。 */
#define CONFIG_MXC_UART_BASE UART1_BASE

/* 这段代码定义了 MMC(多媒体卡)的配置。根据是否启用了 CONFIG_FSL_USDHC 配置,设置了 FSL ESDHC 控制器的基地址 (CONFIG_SYS_FSL_ESDHC_ADDR)。如果启用了 CONFIG_NAND_MXS 配置,则将 CONFIG_SYS_FSL_USDHC_NUM 设置为 1,否则设置为 2。 */

/* MMC Configs */
#ifdef CONFIG_FSL_USDHC
#define CONFIG_SYS_FSL_ESDHC_ADDR USDHC2_BASE_ADDR

/* NAND pin conflicts with usdhc2 */
#ifdef CONFIG_NAND_MXS
#define CONFIG_SYS_FSL_USDHC_NUM 1
#else
#define CONFIG_SYS_FSL_USDHC_NUM 2
#endif

#endif

/* 如果CONFIG_NAND_BOOT已经定义,宏MFG_NAND_PARTITION将被定义为一个包含 NAND Flash 分区信息的字符串;如果CONFIG_NAND_BOOT未定义,宏MFG_NAND_PARTITION将被定义为空字符串。 */
#ifdef CONFIG_NAND_BOOT
#define MFG_NAND_PARTITION "mtdparts=gpmi-nand:64m(nandboot),16m(nandkernel),16m(nanddtb),16m(nandtee),-(nandrootfs)"
#else
#define MFG_NAND_PARTITION ""
#endif

#define CONFIG_CMD_READ
#define CONFIG_SERIAL_TAG
#define CONFIG_FASTBOOT_USB_DEV 0

#define CONFIG_MFG_ENV_SETTINGS \
CONFIG_MFG_ENV_SETTINGS_DEFAULT \
"initrd_addr=0x86800000\0" \
"initrd_high=0xffffffff\0" \
"emmc_dev=1\0"\
"emmc_ack=1\0"\
"sd_dev=1\0" \
"mtdparts=" MFG_NAND_PARTITION \
"\0"\

#if defined(CONFIG_NAND_BOOT)
#define CONFIG_EXTRA_ENV_SETTINGS \
CONFIG_MFG_ENV_SETTINGS \
TEE_ENV \
"splashimage=0x8c000000\0" \
"fdt_addr=0x83000000\0" \
"fdt_high=0xffffffff\0" \
"tee_addr=0x84000000\0" \
"console=ttymxc0\0" \
"bootargs=console=ttymxc0,115200 ubi.mtd=nandrootfs " \
"root=ubi0:rootfs rootfstype=ubifs " \
BOOTARGS_CMA_SIZE \
MFG_NAND_PARTITION \
"\0" \
"bootcmd=nand read ${loadaddr} 0x4000000 0xc00000;"\
"nand read ${fdt_addr} 0x5000000 0x100000;"\
"if test ${tee} = yes; then " \
"nand read ${tee_addr} 0x6000000 0x400000;"\
"bootm ${tee_addr} - ${fdt_addr};" \
"else " \
"bootz ${loadaddr} - ${fdt_addr};" \
"fi\0"

#else
#include "igkboard_overlay.h"

#define CONFIG_EXTRA_ENV_SETTINGS \
"env_conf=config.txt\0" \
"image=zImage\0" \
"console=ttymxc0\0" \
"fdt_file=igkboard.dtb\0" \
"fdt_addr=0x83000000\0" \
"splashimage=0x8c000000\0" \
"ipaddr=192.168.2.22\0" \
"serverip=192.168.2.2\0" \
"mmcpart=1\0" \
"mmcargs=setenv bootargs console=${console},${baudrate} root=/dev/mmcblk${mmc_no}p2 rootwait rw net.ifnames=0\0" \
"loadenvconf=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${env_conf};env import -t ${loadaddr} ${filesize}\0" \
"loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
"loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
"bdtb=tftp $fdt_addr $fdt_file && fatwrite mmc 1:1 $fdt_addr $fdt_file $filesize\0" \
"bker=tftp $loadaddr $image&& fatwrite mmc 1:1 $loadaddr $image $filesize\0" \
"bsys=run bdtb && run bker\0" \
"mmcboot=echo Booting from mmc ...; " \
"mmc dev ${mmcdev}; " \
"run mmcargs; run loadenvconf;" \
"run loadimage; run loadfdt; " \
"bootz ${loadaddr} - ${fdt_addr}\0" \
"netboot=echo Booting from net ...; " \
"tftp $loadaddr $image; tftp $fdt_addr ${fdt_file};" \
"run mmcargs; " \
"bootz ${loadaddr} - ${fdt_addr}\0" \
"upmode=fastboot 0\0" \
"bbl=tftp ${loadaddr} u-boot-igkboard.imx && mmc dev ${mmcdev} 1 && mmc write ${loadaddr} 2 0x500\0" \
MMC_FDT_OVERLAY_SETTING \
"bootcmd=run mmcbootdto\0" \
"author=linke\0"
#endif

/* 其他可配置选项 */

/* 物理内存映射 */
#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR

#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM
#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR
#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE

#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_SYS_MMC_ENV_DEV 1 /* USDHC2 */
#define CONFIG_MMCROOT "/dev/mmcblk1p2" /* USDHC2 */

#define CONFIG_IOMUX_LPSR

/* NAND 相关 */
#ifdef CONFIG_NAND_MXS
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_BASE 0x40000000
#define CONFIG_SYS_NAND_USE_FLASH_BBT

/* DMA 相关, 需要 GPMI/MXS NAND 支持 */
#endif

/* USB 设置 */
#ifdef CONFIG_CMD_USB
#define CONFIG_EHCI_HCD_INIT_AFTER_RESET
#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW)
#define CONFIG_MXC_USB_FLAGS 0
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#endif

#define CONFIG_FEC_XCV_TYPE RMII
#define CONFIG_ETHPRIME "eth1"

#ifndef CONFIG_SPL_BUILD
#if defined(CONFIG_DM_VIDEO)
#define CONFIG_VIDEO_LINK
#endif
#endif

#endif



添加板级支持包

接下来去查看这里所指示的board/lingyun/igkboard这个文件夹下即为板级支持包的文件

1
2
3
4
5
6
7
8
9
10
# 仅作为示例,请不要执行
# 从官方的板级支持包中复制
cp board/freescale/mx6ullevk board/lingyun/igkboard -r
# 重命名mx6ullevk.c为igkboard.c:
mv mx6ullevk.c igkboard.c
# 这里的imximage.cfg和Kconfig也需要根据硬件设计修改
# imximage.cfg文件包含一系列变量和命令,用于描述映像文件中应包含哪些内容,
# 如内核、根文件系统、设备树和其他数据等。主要是Device Configuration Data (DCD)部分,
# 这描述了设备启动时需要进行的一系列初始化操作,即向指定地址的寄存器写入什么数据
# 这里imximage.cfg保持与官方一致即可,硬件设计不同才需要修改
对Kconfig文件的修改

(注意该文件endif后面必须有换行)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 原版的Kconfig
if TARGET_MX6ULL_14X14_EVK || TARGET_MX6ULL_9X9_EVK

config SYS_BOARD
default "mx6ullevk"

config SYS_VENDOR
default "freescale"

config SYS_CONFIG_NAME
default "mx6ullevk"

config IMX_CONFIG
default "board/freescale/mx6ullevk/imximage.cfg"

config SYS_TEXT_BASE
default 0x87800000
endif

修改后的Kconfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if TARGET_LINGYUN_IGKBOARD	# 使用时请删除注释,这里添加注释仅为了逐条解释

config SYS_BOARD
default "igkboard" # 表示系统的板级名称为 "igkboard"。

config SYS_VENDOR
default "lingyun" # 表示系统的供应商名称为 "lingyun"。

config SYS_CONFIG_NAME
default "igkboard" # 表示系统的配置名称为 "igkboard"

config SYS_TEXT_BASE
default 0x87800000 # 表示系统的文本基地址为 0x87800000
endif

可以看出主要修改了这几个地方

image-20230517215513316

MAINTAINERS文件

​ 接下来是对MAINTAINERS文件的修改,将MAINTAINERS修改为

1
2
3
4
5
6
LingYun IoT Gateway Board(IGKBoard)
M: Guo Wenxue <guowenxue@gmail.com>
S: Maintained
F: board/lingyun/igkboard/
F: include/configs/igkboard.h
F: configs/igkboard_defconfig

​ MAINTAINERS文件是一个代码库中的清单,列出了负责维护该代码库的人员及其联系方式。通常,这个清单包括了代码库的作者、核心开发者和其他重要的贡献者。

​ 在开源项目中,MAINTAINERS文件是一个重要的组成部分,因为它可以帮助新的贡献者找到可联系的人员,向他们提供更改意见或报告问题。此外,这个清单还可以帮助协调贡献者之间的工作,防止多人同时修改同一个文件等冲突情况的发生。

​ 通常,MAINTAINERS文件存放在代码库的根目录下,以文本文件的形式存在。该文件的格式不是标准规范,但通常包含姓名、邮箱地址、职位、领域专长等信息。

  • M: Guo Wenxue guowenxue@gmail.com
    • M 表示这是一个维护者(Maintainer)条目。
    • Guo Wenxue 是该项目LingYun IoT Gateway Board(IGKBoard)的维护者姓名。
    • guowenxue@gmail.com 是联系该维护者的邮箱地址。
  • S: Maintained
    • S 表示状态(Status)条目。
    • Maintained表示这个项目正在被维护。
  • F: board/lingyun/igkboard/
    • F 表示文件(File)条目。
    • board/lingyun/igkboard/是指LingYun IoT Gateway Board(IGKBoard)项目中与板卡相关的代码存储在board/lingyun/igkboard/目录下。
  • F: include/configs/igkboard.h
    • include/configs/igkboard.h是指LingYun IoT Gateway Board(IGKBoard)项目的配置文件存储在include/configs/igkboard.h中。
  • F: configs/igkboard_defconfig
    • configs/igkboard_defconfig是指LingYun IoT Gateway Board(IGKBoard)项目的默认配置文件存储在configs/igkboard_defconfig中。
修改Makefile文件

修改Makefile文件

1
2
3
4
5
6
# SPDX-License-Identifier: GPL-2.0+
# (C) Copyright 2016 Freescale Semiconductor, Inc.

obj-y := igkboard.o
obj-y += ../../freescale/common/mmc.o

设备树文件

添加自己板子所对应的设备树文件

1
vim arch/arm/dts/igkboard.dts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
//
// Copyright (C) 2016 Freescale Semiconductor, Inc.

/dts-v1/;

#include "imx6ull.dtsi"
#include "imx6ul-14x14-evk.dtsi"
#include "imx6ul-14x14-evk-u-boot.dtsi"

/ {
model = "LingYun IoT Gateway Board";
compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
};

&clks {
assigned-clocks = <&clks IMX6UL_CLK_PLL3_PFD2>;
assigned-clock-rates = <320000000>;
};

修改arch/arm/dts/Makefile

修改`arch/arm/dts/Makefile`

将我们的开发板添加进编译uboot的编译选项,修改arch/arm/mach-imx/mx6/Kconfig文件:

1
vim arch/arm/mach-imx/mx6/Kconfig
1
2
3
4
# 找到以下的配置,在该配置下方添加:
choice
prompt "MX6 board select"
optional
1
2
3
4
5
6
7
8
9
config TARGET_LINGYUN_IGKBOARD
bool "LingYun IoT Gateway Kits Board(IGKBoard)"
depends on MX6ULL
select BOARD_LATE_INIT
select DM
select DM_THERMAL
select IMX_MODULE_FUSE
select OF_SYSTEM_SETUP
imply CMD_DM

在大约160行的位置,这里TARGET_LINGYUN_IGKBOARD和前面配置的相同

image-20230518134647390

再翻到最后,一堆source这里,将板子的配置添加上

1
source "board/lingyun/igkboard/Kconfig"

将板子的配置添加上

编译uboot

先回到uboot-imx目录

1
2
# 清理之前编译产生的文件
noah@ubuntu:~/imx6ull/bsp/bootloader/uboot-imx$ make distclean

清理之前编译产生的文件

1
2
# 设置编译配置文件为自定义的
noah@ubuntu:~/imx6ull/bsp/bootloader/uboot-imx$ make igkboard_defconfig

设置编译配置文件为自定义的

1
2
# 编译文件,我虚拟机设置了内核总数为8,这里8核一同编译,根据自己虚拟机设置修改一同编译的核数
noah@ubuntu:~/imx6ull/bsp/bootloader/uboot-imx$ make -j8

编译成功

1
2
3
make distclean
make mx6ull_14x14_hello_emmc_defconfig
make -j 2

编译完成

SD卡烧录uboot并启动测试

插入sd卡,使用以下命令查看sd卡位置,因为SD卡插入ubuntu后,会出现/dev/sdX,具体是/dev/sdb还是/dev/sdc又或者是/dev/sdd要视个人插入ubuntu的USB口设备情况而定。

1
sudo fdisk -l

同样在编译完成的目录下

1
sudo dd if=u-boot-dtb.imx of=/dev/sdb bs=1k seek=1 conv=fsync

dd命令可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。详细命令解释参见:https://www.runoob.com/linux/linux-comm-dd.html

将SD卡插入板子卡槽,设置板子上的拨码开关为SD卡启动,控制台打印内容如下

uboot