IMX6ULL Linux内核移植

准备工作

网络设置

关闭主机的Ubuntu的防火墙:

1
sudo ufw disable

确认VMWare使用桥接模式,主机、虚拟机和开发板三者处于同一网段,如:

  • 主机:192.168.1.100
  • 虚拟机:192.168.1.105
  • 开发板:192.168.1.103 (DHCP获取)

在uboot下,开发板ping虚拟机和主机、虚拟机ping主机应当都能ping通。未加载Linux内核前网卡尚未使能,虚拟机ping开发板应当ping不通。

TFTP搭建

TFTP常见用途:

  • U-Boot 加载 Linux 内核、设备树和根文件系统
  • NFS 结合 TFTP 进行网络启动
  • 固件更新
  • 开发调试

安装xinetd:

1
sudo apt install xinetd

检查/etc/xinetd.conf是否存在,不存在则创建,修改内容如下:

1
2
3
4
5
6
7
8
9
10
# Simple configuration file for xinetd
#
# Some defaults, and include /etc/xinetd.d/
defaults
{
# Please note that you need a log_type line to be able to use log_on_success
# and log_on_failure. The default is the following :
# log_type = SYSLOG daemon info
}
includedir /etc/xinetd.d

新建TFTP目录于/home/aki/linux,然后chmod 777该目录。

安装tftp-hpa和tftpd-hpa:

1
sudo apt install tftp-hpa tftpd-hpa

安装完后,sudo nvim /etc/default/tftpd-hpa,修改tftp目录为TFTP服务器工作目录:

TFTP_DIRECTORY

然后sudo nvim /etc/xinetd.d/tftp,添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server tftp
{
socket_type = dgram
wait = yes
disable = no
user = root
protocol = udp
server = /usr/sbin/in.tftpd
server_args = -s /home/aki/linux/tftp -c
#log_on_success += PID HOST DURATION
#log_on_failure += HOST
per_source = 11
cps =100 2
flags =IPv4
}

保存,重启TFTP服务:sudo service tftpd-hpa restart,重启xinetd服务:sudo service xinetd restart

NFS搭建

NFS主要用于:

  • 嵌入式设备的根文件系统(RootFS)挂载:在开发阶段,NFS 服务器可以存放 根文件系统(RootFS),嵌入式设备通过网络直接挂载,而无需烧录到 Flash 或 SD 卡
  • 远程文件访问:如开发板访问PC共享目录

安装NFS服务:

1
sudo apt install nfs-kernel-server

新建NFS共享目录并chmod 777

1
2
sudo mkdir /home/aki/linux/nfs
sudo chmod 777 /home/aki/linux/nfs

安装完后,sudo nvim /etc/exports,在最后添加:

1
/home/aki/linux/nfs *(rw,sync,no_root_squash)

保存退出,重启NFS服务:sudo /etc/init.d/nfs-kernel-server restart,确认共享目录已经配置完毕:shouwmount -e

Linux镜像测试

先确认官方linux镜像是否可以。在linux根目录中,修改顶层Makefile,添加ARCHCROSS_COMPILE变量,然后

1
2
make clean
make imx_v7_mfg_defconfig

然后

1
make -j16

make完成后makefile会提示得到两个重要的文件:

  • zImage:linux内核镜像,位于/arch/arm/boot/
  • imx6ull-14x14-evk.dtb:编译后的设备树文件,位于/arch/arm/boot/dts/

然后,启动uboot,设置uboot中的envbootargs为:

1
console=ttymxc0,115200 root=/dev/mmcblk 1p2 rootwait rw

表明将从eMMC/SD卡的第2分区启动 Linux。然后,修改bootcmd

1
setenv bootcmd 'tftp 80800000 zImage;tftp 83000000 imx6ull-14x14-evk.dtb;bootz 80800000 - 83000000`

表明将通过TFTP从虚拟机拉取内核镜像和设备树并启动内核。然后,boot,启动内核。

配置主频、EMMC和网络驱动

主频设置

WIP

EMMC设置

6.6版本的Kernel已经默认禁用1.8V供电,同时自动启用了8位宽的EMMC总线,所以不用进行其他的设置。

网络驱动

和uboot中进行过的很像。已知NXP原版设备树中的SPI4节点中的两个引脚和SR8201F的冲突,因此打开/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi这个底层设备树,找到pinctrl_spi4: spi4grp这个节点,删掉包含GPIO5 7GPIO5 8的两行。然后前往SPI4的子节点,把status改成disable,直接禁用掉SPI4。

然后,修改pinctrl复用信息,来到&iomuxc节点,在节点末尾新增两个pinctrl group

1
2
3
4
5
6
7
8
9
10
11
12
13
pinctrl_enet1_reset: enet1resetgrp {
fsl,pins = <
/* used for enet1 reset */
MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10B0
>;
};

pinctrl_enet2_reset: enet2resetgrp {
fsl,pins = <
/* used for enet2 reset */
MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0
>;
};

按照步骤还需要修改ENET1和ENET2的网络时钟引脚配置,但是6.6版本的kernel设备树已经添加了,就不用手动操作了。

继续,在fec1fec2节点里加入刚刚设置好的复位引脚的pinctrl group信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
&fec1 {
.....
pinctrl-0 = <&pinctrl_enet1
&pinctrl_enet1_reset>;
.....
}

&fec2 {
.....
pinctrl-0 = <&pinctrl_enet2
&pinctrl_enet2_reset>;
.....
}

继续,检查设备树fec1fec2节点下mdio子节点中的PHY地址是否正确。新版kernel默认都是设置好的。

然后,在defconfig里告知kernel使用realtek的PHY驱动:

1
CONFIG_REALTEK_PHY=y

最后,根据SR8201F复位后至少延时150ms才能开始使用的要求,修改drivers/net/ethernet/freescale/fec_main.c,在static void fec_reset_phy()函数的末尾加入:

1
msleep(200);

重新编译kernel,然后启动,通过ifconfig观察网卡是否工作正常(正常情况下ETH1会自动启动):

1
2
3
4
ifconfig eth0 up    //启动ETH0网卡
ifconfig eth1 up //启动ETH1网卡
ifconfig eth0 192.168.xx.xx
ifconfig eth1 192.168.xx.xx

构建根文件系统

使用busybox构建,在busybox根目录的顶层Makefile中添加ARCHCORSS_COMPILE,然后:

1
2
make defconfig
make menuconfig

进入图形化配置界面:

  • 选中Settings->Build static binary
  • 选中Setttings->vi-style line editing commands
  • 取消选中Linux Module Utilities->Simpilified modutils

编译busybox时必须使用静态库,动态库会缺库文件导致dns解析没法正常使用。

然后,

1
2
make 
make install CONFIG_PREFIX=/home/aki/linux/nfs/rootfs

注意:1.37.0版本busybox报告有一个bug,即:

1
2
3
4
5
6
7
8
9
10
compilation
of tc.c fails with:

networking/tc.c: In function ‘cbq_print_opt’:
networking/tc.c:236:27: error: ‘TCA_CBQ_MAX’ undeclared (first use in this
function); did you mean ‘TCA_CBS_MAX’?
236 | struct rtattr *tb[TCA_CBQ_MAX+1];
| ^~~~~~~~~~~
| TCA_CBS_MAX
————————————————

和CBQ队列管理有关的大量宏会报错,解决方法是把tc.c/busybox/networking文件夹里删除。

然后,需要将编译器所包含的库文件全部打包到根目录下。

使用NFS挂载时,bootargs要设成:

1
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.105:/home/aki/linux/nfs/rootfs,vers=3,proto=tcp rw ip=192.168.1.103:192.168.1.105:192.168.1.1:255.255.255.0::eth0:off'

注意:这里通过vers=3强制使用NFS v3版本,否则会挂载失败。

如果碰到hotplug:can’t create /proc/sys/kernel/hotplug: nonexistent directory问题:参见

fstab要加一行:

1
mdev  /dev  ramfs defaults 0 0

IMX6ULL Linux内核移植
http://akichen891.github.io/2025/03/11/Linux内核移植/
作者
Aki
发布于
2025年3月11日
更新于
2025年4月1日
许可协议