imx6ull移植v6.15-rc1主线内核

一、内核下载、配置、编译

1.内核下载

1
git clone --depth=1 --branch v6.15-rc1 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

2.交叉编译链

使用armv7架构的交叉编译工具

1
2
3
4
sudo apt update
sudo apt install gcc-arm-linux-gnueabihf
#装好之后
which arm-linux-gnueabihf-gcc

出现路径则成功。

3.内核的配置

我的开发板是正点原子的imx6ull mini,使用他们提供的config文件配置内核(imx_v7_mfg_defconfig),文件可以从原子官网获取。

(1)将imx_v7_mfg_defconfig配置文件复制到6.12.0-rc5-dirty内核目录arch/arm/configs/下,并在内核根目录下并make.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_mfg_defconfig

❯ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_mfg_defconfig ─╯
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/confdata.o
HOSTCC scripts/kconfig/expr.o
LEX scripts/kconfig/lexer.lex.c
YACC scripts/kconfig/parser.tab.[ch]
HOSTCC scripts/kconfig/lexer.lex.o
HOSTCC scripts/kconfig/menu.o
HOSTCC scripts/kconfig/parser.tab.o
HOSTCC scripts/kconfig/preprocess.o
HOSTCC scripts/kconfig/symbol.o
HOSTCC scripts/kconfig/util.o
HOSTLD scripts/kconfig/conf
#
# configuration written to .config
#

(2)因为 I.MX6ULL 是 ARMV7 架构的,因此要屏蔽掉 V6 相关选项,否则后面做驱动实验的时候可能会遇到驱动模块无法加载的情况,在内核根目录下:

1
2
3
❯ cat .config | grep 'CONFIG_ARCH_MULTI_V6'                                                                 ─╯
CONFIG_ARCH_MULTI_V6=y
CONFIG_ARCH_MULTI_V6_V7=y
1
2
3
4
❯ vim .config 
# CONFIG_ARCH_MULTI_V6 is not set ->如CONFIG_ARCH_MULTI_V6=y,则屏蔽掉
CONFIG_ARCH_MULTI_V7=y
CONFIG_ARCH_MULTI_V6_V7=y

4.设备树文件选择

(1)为了先完成开发板的启动,先使用nxp提供的dtb文件 imx6ull-14x14-evk.dtb,文件位置在arch/arm/boot/dts/nxp/imx/下,我们把imx6ull-14x14-evk.dtb拷贝一份,命名为imx6ull-hailin.dtb(随意)

(2)修改设备树目录下的Makefile文件

此时我们复制完后,make时并不会来编译我们的dtb文件,我们需要在Makefile文件里把我们的dtb添加上

1
2
3
4
5
326         imx6ul-tx6ul-0011.dtb \
327 imx6ul-tx6ul-mainboard.dtb \
328 imx6ull-14x14-evk.dtb \ ->放在之后即可
329 imx6ull-hailin.dtb \ ->拷贝的dtb
330 imx6ull-colibri-aster.dtb \

然后回到内核根目录下

1
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16

(3)编译成功后将zimage和imx6ull-14x14-evk.dtb文件拷贝到 开发板 /run/media/mmcblk1p1/ 下

1
2
scp -r arch/arm/boot/zImage root@开发板ip:/run/media/mmcblk1p1
scp -r arch/arm/boot/dts/nxp/imx/imx6ull-14x14-evk.dtb root@开发板ip:/run/media/mmcblk1p1

然后复位开发板。

从dmesg打印信息可以看到已经成功启动了

1
2
3
4
5
Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 6.12.0-rc5-dirty (root@ubuntu) (arm-linux-gnueabihf-gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1 SMP PREEMPT Sun Apr 13 15:42:55 CST 2025

5.u-boot修改

在启动过程中应该会看到内核找不到根文件系统

1
2
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) ]---

原因是我们没有在bootargs里指定文件系统的位置,内核不知道去哪里挂载

(1)进入uboot命令行,我是从 eMMC 分区启动,通常加参数像这样

1
2
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv

参数的具体含义可以参考之前文章

[]: https://github.com/HL0019/Uboot-Learning-Record/blob/main/uboot-problem-analysis.md

然后kernel就可以正常启动了。

(2)启动方式

因为现在跑的是nxp提供的dtb文件,和我们开发板上的网口可能不一样,为了可以次可以正常启动,我这里把zimage和dtb的启动方式改为了tftp,让它使用uboot的tftp来加载kernrl和dtb。

我们还是进入uboot命令行

1
2
3
4
5
6
7
8
9
10
11
12
13
setenv ipaddr 192.168.xxx(开发板的ip)
setenv serverip 192.168.xxx(主机ip)

setenv kernel_addr 0x80800000
setenv fdt_addr 0x83000000

setenv ethaddr 00:11:22:33:44:55 # 若未设置过 ethaddr,请添加

tftp ${kernel_addr} zImage
tftp ${fdt_addr} imx6ull-hailin.dtb

bootz ${kernel_addr} - ${fdt_addr}

你可以把这些命令合并成 bootcmd 并保存,这样每次上电开发板就会自动执行,省得每次敲一遍。

1
2
setenv bootcmd 'setenv ipaddr 192.168.xxx.xxx; setenv serverip 192.168.xxx.xxx; setenv kernel_addr 0x80800000; setenv fdt_addr 0x83000000; setenv ethaddr 00:11:22:33:44:55; tftp ${kernel_addr} zImage; tftp ${fdt_addr} imx6ull-.dtb; bootz ${kernel_addr} - ${fdt_addr}'
saveenv

这样我们下次在主机修改完设备树直接把dtb文件放到主机的tftp服务器目录下(我的是/tftp),板子上电后就可以直接从这个目录下来加载文件了。

####接下来就是漫长的适配环节了####


imx6ull移植v6.15-rc1主线内核
http://example.com/2025/04/22/imx6ull移植主线内核6.12.0-rc5-dirty/
作者
Encrow
发布于
2025年4月22日
许可协议