目录
- 前言
- 获取`FSL Yocto Project Community BSP`使用的Linux内核源码
- 配置内核
- 编译构建生成内核镜像文件zImage
- 编译生成设备树文件(dtb文件)
- 修改设备树文件`imx6ul-14x14-evk.dts`
- 设备树文件中关于以太网设备的描述的说明
- 将内核镜像和设备树文件放到TFTP目录中
- 将根文件系统放到Ubuntu系统中并解压
- 权限设置:将根文件目录中的所有子目录和文件的权限都设为777
- 【启动系统】设置好u-boot的相关环境变量,然后从网络启动Linux系统
- 触摸屏驱动移植适配
- USB蓝牙设备的驱动适配(将驱动改为模块的形式进行加载)
- Wifi驱动的移植
- 烧写设备树dtb文件、内核镜像、根文件系统到eMMC中
- 附这篇博文涉及到的相关文件的下载地址
- 附移植完成后的完整启动日志文件
前言
本篇博文承接我的上一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145662136
上一篇博文中已经实现u-boot的成功移植了,这篇博文就继续移植Linux内核。
获取FSL Yocto Project Community BSP
使用的Linux内核源码
根据上一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145662136 的经验,官方的git仓库已经不能用了,那就只用用百问网当时保存在那里的了。
百度网盘下载地址:
https://pan.baidu.com/s/1Y-Wz69K9tsWFxTTdhZWV_g?pwd=n79q
注意:文件有点大…4.04GB呢…
下载好后如下图所示:
##内核源码复制到Ubuntu中并解压
首先检查自己的交叉编译器是否配置好了,如果没有弄好,按照博文 https://blog.csdn.net/wenhao_ir/article/details/145649698去配置安装。
当然,因为我前面在编译构建u-boot时已经使用过了,所以肯定是没有问题的了。
把之前下载好的源码压缩包linux-imx.tar.gz
复制到Ubuntu中。
然后解压,解压是需要点时间的,因为压缩文件有4.04GB嘛,解压出来后如下图所示:
配置内核
执行下面的命令来配置内核
make imx_v7_defconfig
因为IMX6ULL是Cortex-A7架构的处理器,所以上面的名字中是v7
。
运行结果如下:
编译构建生成内核镜像文件zImage
运行下面的命令进行构建编译内核镜像文件(zImage)
make zImage -j4
当然,如果处理器的资源够多,可以用8线程加快构建速度,即把-j4
改为-j8
运行时间和结果如下:
起始时间: 2025-02-24 13:47:12
结束时间:2025-02-24 13:54:41
根据上图的运行结果,我们知道生成的zImage镜像文件位于目录/arch/arm/boot
中,如下图所示:
编译生成设备树文件(dtb文件)
承接上一步,继续编译生成设备树文件。
执行下面的命令生成设备树文件:
make dtbs
运行结果如下(1分钟左右就完成了):
在目录/arch/arm/boot/dts
下生成了所有设备树文件(dts文件)的二进制文件(dtb文件),我们需要的dts文件和对应生成的dtb文件如下面的截图如示:
注意:我们要的设备树文件的名字中是im6ull
,而不是im6ul
,它们的区别是前者的末尾是两个l
,而后者的末尾是一个l
,我们要的是名字中含两个l
的。
即我们要的文件是imx6ull-14x14-evk.dts
和文件imx6ull-14x14-evk.dtb
。
注意:下面这幅图中的两个文件不是我们要的文件:
这样,我们就测试了编译生成设备树文件(dtb文件)是没有问题的,接下来我们就可以修改dts设备树文件了,使其能适应我们的开发板。
修改设备树文件imx6ul-14x14-evk.dts
复制并重命名百问网提供的设备树文件
上一步中我们测试了编译生成设备树文件(dtb文件)是没有问题的,接下来我们就可以修改dts设备树文件了,使其能适应我们的开发板。
先把上一步末尾中提到的文件imx6ull-14x14-evk.dts
和文件imx6ull-14x14-evk.dtb
分别改名为:
imx6ull-14x14-evk.dts.bak0
imx6ull-14x14-evk.dtb.bak0
然后把百问网提供的位于目录/home/book/100ask_imx6ull-sdk/Linux-4.9.88/arch/arm/boot/dts
中的设备树文件100ask_imx6ull-14x14.dts
复制到目录/home/book/mybuild/Linux-BSP_raw/linux-imx/arch/arm/boot/dts
中,并重命名为:imx6ull-14x14-evk.dts
然后我们尝试编译生成生dtb文件,肯定有错误,运行下面的命令进行编译:
make dtbs
运行结果如下:
book@100ask:~/mybuild/Linux-BSP_raw/linux-imx$ make dtbs
DTC arch/arm/boot/dts/imx6ull-14x14-evk.dtb
Error: arch/arm/boot/dts/imx6ull-14x14-evk.dts:234.1-10 Label or path flexcan1 not found
FATAL ERROR: Syntax error parsing input tree
scripts/Makefile.lib:285: recipe for target 'arch/arm/boot/dts/imx6ull-14x14-evk.dtb' failed
make[1]: *** [arch/arm/boot/dts/imx6ull-14x14-evk.dtb] Error 1
Makefile:1250: recipe for target 'dtbs' failed
make: *** [dtbs] Error 2
错误的原因提取如下:
Error: arch/arm/boot/dts/imx6ull-14x14-evk.dts:234.1-10 Label or path flexcan1 not found
这个错误提示表明设备树文件(imx6ull-14x14-evk.dts)中第234行出现了一个问题,具体是“flexcan1标签或路径未找到”。从错误信息看,可能是设备树的某个部分引用了flexcan1,但设备树中并没有定义或正确引用这个节点。
与标签flexcan1
有关的错误修改
我们不妨去看下这个设备树文件imx6ull-14x14-evk.dts
的234行:
这里先说明一下,这个设备树文件imx6ull-14x14-evk.dts
其实就是100ask_imx6ull-14x14.dts
,通过前面的操作,我们知道只是100ask_imx6ull-14x14.dts
重命名为imx6ull-14x14-evk.dts
而已。
不妨用Vscode来查看。
文件imx6ull-14x14-evk.dts
的234行左右的内容如下:
可见这是一个对标签名为flexcan1
的节点的引用,关于标签名和引用的详情,见我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145060032
这应该是与CAN设备节点有关,我们不妨去查看下公板提供的内核里的设备树文件里是怎么描述CAN设备节点的。
我们打开公板提供的内核里的设备树文件imx6ull-14x14-evk.dts.bak0
【后面的bak0是我重命名的】,发现内容如下:
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
//
// Copyright (C) 2016 Freescale Semiconductor, Inc.
/dts-v1/;
#include "imx6ull.dtsi"
#include "imx6ul-14x14-evk.dtsi"
/ {
model = "Freescale i.MX6 ULL 14x14 EVK Board";
compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
};
&clks {
assigned-clocks = <&clks IMX6UL_CLK_PLL3_PFD2>,
<&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
assigned-clock-rates = <320000000>, <786432000>;
};
&csi {
status = "okay";
};
&ov5640 {
status = "okay";
};
/delete-node/ &sim2;
可见它包含了两个了设备树文件,名字分别为imx6ull.dtsi
、imx6ul-14x14-evk.dtsi
。
这里要说明下,我在博文 https://blog.csdn.net/wenhao_ir/article/details/145060032 中已经说明了:当设备树文件通过 #include 引入其他 dtsi 文件时,dtsi 文件中的内容会被嵌入到主文件中,但不会定义新的根节点,这些嵌入的内容通常作为子节点或并列节点加入现有的设备树结构。
所以我们不妨先去文件imx6ull.dtsi
中搜索下关键词can1
,看下有没有相关的设备节点:
搜索的结果为没有结果,也就是说在文件imx6ull.dtsi
中没有搜索到关键词can1
。
然后再去文件imx6ul-14x14-evk.dtsi
中搜索关键词can1
,看下有没有相关的设备节点:
这就有了:
可见在公板提供的内核里的设备树文件中,对应的CAN设备的标签名为can1
,我们不妨再去查看标签名can1
的定义处,我们继续在文件imx6ul-14x14-evk.dtsi
中搜索关键词can1:
,看下在文件imx6ul-14x14-evk.dtsi
中是否定义了标签can1
,结果没有相关的结果。
那我们就只有去看文件imx6ul-14x14-evk.dtsi
通过include包括的文件,很遗憾的是文件imx6ul-14x14-evk.dtsi
并没有包含另外的设备树文件。
但是文件imx6ull.dtsi
中有包含的另外的设备树文件啊:
#include "imx6ul.dtsi"
#include "imx6ull-pinfunc.h"
#include "imx6ull-pinfunc-snvs.h"
所以我们现在去文件imx6ul.dtsi
中搜索关键词can1:
,看有没有标签can1
的定义,这就有了,如下图所示:
可见在公板提供的内核里的设备树文件中,对应的CAN1设备的标签名为can1
,节点名为flexcan@2090000
。
总结一下:在公板提供的内核里的设备树文件中,对于设备CAN1的描述结构情况如下:
顶层设备设备树文件imx6ull-14x14-evk.dts.bak0
【后面的bak0是我重命名的】中包含了两个设备树文件,分别如下:
#include "imx6ull.dtsi"
#include "imx6ul-14x14-evk.dtsi"
在文件imx6ull.dtsi
中又包含了另一个设备树文件,如下:
#include "imx6ul.dtsi"
在设备树文件imx6ul.dtsi
中定义了标签名为can1
、节点名为flexcan@2090000
的节点,用来描述设备CAN1,如下图所示:
而在设备树文件imx6ul-14x14-evk.dtsi
中有对标签can1
代表的节点的引用,截图如下:
百问网提供的内核的设备树文件与公板提供的内核的设备树文件的主要区别如下:
①百问网提供的设备树文件把公板提供的设备树文件imx6ul-14x14-evk.dtsi的内容直接写在了文件imx6ull-14x14-evk.dts
中,所以百问网提供的设备树文件不需要文件imx6ull-14x14-evk.dts
。
②百问网提供的设备树文件对CAN1这个设备描述的节点的标签名为flexcan1
,而公板提供的设备树文件对CAN1这个设备描述的节点的标签名为can1
。
③公板中的设备文件没有引用头文件 #include <dt-bindings/input/input.h>
,而百问网引用了这个文件,相关截图如下:
对于上面第①点和第②点的区别,我们作如下修改:
将imx6ull-14x14-evk.dts
(其实是100ask_imx6ull-14x14.dts
)作如下修改:
将
&flexcan1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexcan1>;
xceiver-supply = <®_can_3v3>;
status = "okay";
};
改为:
&can1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexcan1>;
xceiver-supply = <®_can_3v3>;
status = "okay";
};
对于第③点,我们首先要了解清楚头文件 #include <dt-bindings/input/input.h>
的作用是什么,先查看下它的代码,如下:
/* SPDX-License-Identifier: GPL-2.0 */
/*
* This header provides constants for most input bindings.
*
* Most input bindings include key code, matrix key code format.
* In most cases, key code and matrix key code format uses
* the standard values/macro defined in this header.
*/
#ifndef _DT_BINDINGS_INPUT_INPUT_H
#define _DT_BINDINGS_INPUT_INPUT_H
#include "linux-event-codes.h"
#define MATRIX_KEY(row, col, code) \
((((row) & 0xFF) << 24) | (((col) & 0xFF) << 16) | ((code) & 0xFFFF))
#define FT5416 0x54160002
#define FT5