文章目录
备注1:本文以正点原子imx6ull芯片Alpha开发板为例。参考《正点原子嵌入式linux驱动开发指南V1.4.pdf》整理的笔记。
备注2:移植Linxu内核之前,需要安装交叉编译工具链,安装方法见另一篇博客:1.1、Ubuntu18.04安装交叉编译工具链。
一、Linux内核源码编译
下载下载的源码不做修改直接进行编译,目的在于验证下载的源码可以正常编译通过,包括自己Linux系统环境也可以进行验证,免得后续出现各种问题怀疑源码不对(事实上源码一般不会编译不通过,所以该步骤可以直接跳过,直接看下一小节)。
-
下载Linux内核镜像源码,并解压
备注:我这里直接使用正点原子提供的内核源码,路径为:
【正点原子】阿尔法Linux开发板(A盘)-基础资料\1、例程源码\4、NXP官方原版Uboot和Linux
tar -jxvf linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2
内核目录常用目录含义如下:
目录 含义 arch 架构相关目录 drivers 驱动相关目录 fs 文件系统相关目录 include 头文件相关目录 kernel 内核相关目录 lib 库相关目录 .config Linux最终使用的配置文件(编译生成) Kconfig 图形化配置界面配置文件 Makefile 顶层Makefile,工程结构从此Makefile作为入口
源码刚下载下来第一步需要在该Makefile中修改交叉编译工具链 -
安装依赖库(否则会编译失败)
sudo apt-get install lzop
-
修改顶层Makefile,配置交叉编译工具链
cd linux-imx-rel_imx_4.1.15_2.1.0_ga vim Makefile
找到如下代码(252,253行):
ARCH ?= $(SUBARCH) CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
修改为:
ARCH ?= arm CROSS_COMPILE ?= arm-linux-gnueabihf-
-
配置编译内核
备注:编译时需要使用板卡对应的默认配置文件(每个板卡都有),配置文件保存在arch/arm/config文件夹中,imx6ull开发板可以使用配置文件:imx_v7_defconfig和imx_v7_mfg_defconfig
make clean #内核源码顶层目录下执行 make imx_v7_mfg_defconfig #配置Linux内核 make -j16 #编译内核
-
编译完成以后界面如下
可以看到提示Kernel: arch/arm/boot/zImage is ready,内核镜像已经准备好了。
... LD [M] lib/crc7.ko LD [M] lib/libcrc32c.ko AS arch/arm/boot/compressed/piggy.lzo.o LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready
-
zImage镜像和.dtb设备树文件所在路径
编译完成之后会生成Linux内核镜像文件zImage和设备树文件xxx.dtb,后面需要将该两个文件烧写到emmc中。两个文件所在目录分别如下
文件 含义 所在目录 zImage Linux内核镜像文件 arch/arm/boot xxx.dtb 设备树文件 arch/arm/boot/dts NXP官方I.MX6ULL EVK开发板对应设备树文件为:imx6ull-14x14-evk.dtb
将zImage和imx6ull-14x14-evk.dtb拷贝到tftp服务器目录中:
cp arch/arm/boot/zImage ~/Tools/tftp/ cp arch/arm/boot/dts/imx6ull-14x14-evk.dtb ~/Tools/tftp/ ls ~/Tools/tftp/
-
下载zImage和imx6ull-14x14-evk.dtb到Flash中
启动U-Boot,倒数结束之前按任意键,进入U-Boot命令行界面,输入如下命令:
tftp 80800000 zImage tftp 83000000 imx6ull-14x14-evk.dtb bootz 80800000 - 83000000
-
此时就可以进入Linux系统了,如果系统报错,无法启动,大概率是因为环境变量的问题,暂时不用理会,后面错误解决章节会记录如何设置环境变量。
二、修改源码添加自己的开发板
上面步骤是将下载下来的源码直接进行编译,确保源码可以编译通过且环境没有问题。此步骤是将Linux内核源码进行修改,编译生成自己板卡适用的zImage和设备树文件。
同上面一样,还是先解压一份正点原子提供的Linux内核源码,然后按下面步骤逐步修改:
-
解压源码包
tar -jxvf linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2
-
安装依赖库(如上面步骤已安装,则此处可以跳过)
sudo apt-get install lzop
-
修改顶层Makefile交叉编译工具链
cd linux-imx-rel_imx_4.1.15_2.1.0_ga vim Makefile
找到如下代码(252,253行):
ARCH ?= $(SUBARCH) CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
修改为:
ARCH ?= arm CROSS_COMPILE ?= arm-linux-gnueabihf
-
拷贝配置文件为自己板卡的配置文件
cd arch/arm/configs cp imx_v7_mfg_defconfig imx_alientek_emmc_defconfig
后续就可以使用imx_alientek_emmc_defconfig文件配置对应开发板内核了:
cd {内核源码顶层目录} make imx_alientek_emmc_defconfig
-
拷贝开发板设备树文件
cd arch/arm/boot/dts cp imx6ull-14x14-evk.dts imx6ull-alientek-emmc.dts
在当前目录下的Makefile中添加该设备树文件
vim Makefile
找到CONFIG_SOC_IMX6ULL配置项(400行),在此配置项中加入“imx6ull-alientek-emmc.dtb” (我加在了末尾425行)
400 dtb-$(CONFIG_SOC_IMX6ULL) += \ 401 >---imx6ull-14x14-ddr3-arm2.dtb \ 402 >---imx6ull-14x14-ddr3-arm2-adc.dtb \ 403 >---imx6ull-14x14-ddr3-arm2-cs42888.dtb \ 404 >---imx6ull-14x14-ddr3-arm2-ecspi.dtb \ 405 >---imx6ull-14x14-ddr3-arm2-emmc.dtb \ 406 >---imx6ull-14x14-ddr3-arm2-epdc.dtb \ 407 >---imx6ull-14x14-ddr3-arm2-flexcan2.dtb \ 408 >---imx6ull-14x14-ddr3-arm2-gpmi-weim.dtb \ 409 >---imx6ull-14x14-ddr3-arm2-lcdif.dtb \ 410 >---imx6ull-14x14-ddr3-arm2-ldo.dtb \ 411 >---imx6ull-14x14-ddr3-arm2-qspi.dtb \ 412 >---imx6ull-14x14-ddr3-arm2-qspi-all.dtb \ 413 >---imx6ull-14x14-ddr3-arm2-tsc.dtb \ 414 >---imx6ull-14x14-ddr3-arm2-uart2.dtb \ 415 >---imx6ull-14x14-ddr3-arm2-usb.dtb \ 416 >---imx6ull-14x14-ddr3-arm2-wm8958.dtb \ 417 >---imx6ull-14x14-evk.dtb \ 418 >---imx6ull-14x14-evk-btwifi.dtb \ 419 >---imx6ull-14x14-evk-emmc.dtb \ 420 >---imx6ull-14x14-evk-gpmi-weim.dtb \ 421 >---imx6ull-14x14-evk-usb-certi.dtb \ 422 >---imx6ull-9x9-evk.dtb \ 423 >---imx6ull-9x9-evk-btwifi.dtb \ 424 >---imx6ull-9x9-evk-ldo.dtb \ 425 >---imx6ull-alientek-emmc.dtb
-
编译源码测试
创建编译脚本
cd {内核源码根目录} vim imx6ull_alientek_emmc.sh
加入如下内容:(注意倒数第二行尾配置内核功能,如果不需要配置,在编译的时候直接选择EIXT退出即可)
#!/bin/sh make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_alientek_emmc_defconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16
修改权限,并执行脚本:
chmod 777 imx6ull_alientek_emmc.sh ./imx6ull_alientek_emmc.sh
-
编译完成后终端显示如下:
... LD [M] lib/crc7.ko AS arch/arm/boot/compressed/ashldi3.o LD [M] lib/crc-ccitt.ko AS arch/arm/boot/compressed/bswapsdi2.o AS arch/arm/boot/compressed/piggy.lzo.o LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready
-
将zImage和imx6ull-alientek-emmc.dtb拷贝到tftp服务器目录中:
cp arch/arm/boot/zImage ~/Tools/tftp/ cp arch/arm/boot/dts/imx6ull-alientek-emmc.dtb ~/Tools/tftp/ ls ~/Tools/tftp/
-
下载zImage和imx6ull-14x14-evk.dtb到Flash中
启动U-Boot,倒数结束之前按任意键,进入U-Boot命令行界面,输入如下命令:
tftp 80800000 zImage tftp 83000000 imx6ull-alientek-emmc.dtb bootz 80800000 - 83000000
-
此时就可以进入Linux系统了。
三、系统无法启动,错误解决
3.1 报错信息:not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
如果启动时碰到报错信息如下:
[ 2.667765] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[ 2.676044] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
则说明是因为U-Boot环境变量未进行设置。在U-Boot中输入如下命令设置环境变量,再重启即可:
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv
如果想要再重新复现该错误,只需要删掉刚设置的环境变量即可,在U-Boot中输入如下代码:
setenv bootargs 'console=ttymxc0,115200'
saveenv
重启即可复现上步骤错误。
3.2 如果使用nfs挂载文件系统,提示找不到系统,则可设置如下环境变量
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.0.250:/home/lsy/Tools/nfs/rootfs ip=192.168.0.100:192.168.0.250:192.168.0.1:255.255.255.0::eth0:off'
三、写在最后:答疑
-
如何判断每个板卡应该使用哪个默认的配置文件,比如如何判断imx6ull EVK对应的配置文件就可以使用imx_v7_defconfig和imx_v7_mfg_defconfig?
答: