LV05-02-linux内核-02-NXP提供的内核

本文主要是获取和编译NXP官方提供的内核的相关笔记。若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
Windows版本 windows11
Ubuntu版本 Ubuntu16.04的64位版本
VMware® Workstation 16 Pro 16.2.3 build-19376536
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
Linux开发板 正点原子 i.MX6ULL Linux 阿尔法开发板
uboot NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)
linux内核 linux-4.15(NXP官方提供)
Win32DiskImager Win32DiskImager v1.0
点击查看本文参考资料
分类 网址 说明
官方网站 https://www.arm.com/ ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档
https://www.nxp.com.cn/ NXP官方网站
https://www.nxpic.org.cn/NXP 官方社区
https://u-boot.readthedocs.io/en/latest/u-boot官网
https://www.kernel.org/linux内核官网
点击查看相关文件下载
分类 网址 说明
NXP https://github.com/nxp-imx NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库
https://elixir.bootlin.com/linux/latest/source 在线阅读linux kernel源码
nxp-imx/linux-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga NXP linux内核仓库tags中的rel_imx_4.1.15_2.1.0_ga
nxp-imx/uboot-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga NXP u-boot仓库tags中的rel_imx_4.1.15_2.1.0_ga
I.MX6ULL i.MX 6ULL Applications Processors for Industrial Products I.MX6ULL 芯片手册(datasheet,可以在线查看)
i.MX 6ULL Applications ProcessorReference Manual I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网)

一、简介

1. 获取NXP内核源码

我们知道NXP有一款IMX6ULL EVK评估板,所以自然也会有自己维护的对应的内核,我们可以在这里下载:Release rel_imx_4.1.15_2.1.0_ga: MLK-14762 ARM: dts: imx6sll-evk: correct gpio pin for lcd power control · nxp-imx/linux-imx (github.com)

image-20230802191729343

我们下载后就可以得到对应的压缩包:

image-20230802202827283

2. 有那些文件?

我们解压看一下都有哪些文件:

image-20230802203038633

这里先不介绍这些目录和文件都是什么,因为还有些文件要编译后才能生成。

3. 编译NXP的linux内核源码

3.1 编译命令

我们在linux内核源码目录执行以下命令(也可以创建一个脚本,写进去,方便一些),NXP官方的IMX6ULL EVK评估板对应的默认配置文件为imx_v7_defconfig,所以有:

1
2
3
4
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16

编译的时候,在执行menuconfig的时候,会弹出 Linux 图形配置界面 :

image-20230802203358667

这里暂时不管,直接按两下Esc退出即可,然后就开始编译啦,但是若是首次编译的话,应该会有报错。后边报错处理完后编译成功会有以下信息:

image-20230802220917207

3.2 报错处理

3.2.1 gcc版本过高问题

不出意外的话,最先报的肯定是这个问题:

image-20230802213514900

经查询,好像是gcc编译器10及以上版本才会出现问题,可以修改linux内核源码文件,我们在linux内核源码中scripts/dtc目录下的dtc-lexer.lex.c_shipped文件中找到 YYLTYPE yyloc 这一行:

image-20230802215832306

可以看到在640行,我们在这个之前面加上extern :

image-20230802215922688

然后就可以正常编译啦。

3.2.2 缺少lzop库

编译过程中可能会有下边的报错提示:

image-20230802215304599

怎么解决?我们需要安装一下lzop库:

1
sudo apt-get install lzop

然后再编译应该就可以了。

二、工程目录分析

1. 概述

我们编译完的linux内核源码的顶层目录将会有以下文件及目录:

image-20230802220951094

各个目录说明如下:

image-20230802221029033

2. 重要目录与文件

2.1 arch 目录

这个目录是和架构有关的目录,比如 arm、 arm64、 avr32、 x86 等等架构。每种架构都对应一个目录,在这些目录中又有很多子目录,比如 boot、 common、 configs 等等 :

image-20230802221150464

以 arch/arm 为例,其子目录如图:

image-20230802221301088

这些子目录用于控制系统引导、系统调用、动态调频、主频设置等。 arch/arm/configs 目录是不同平台的默认配置文件: xxx_defconfig,如图

image-20230802221358652

在 arch/arm/configs 中就包含有NXP官方的 IMX6ULL EVK 评估板的默认配置文件: imx_v7_defconfig,执行“make imx_v7_defconfig”即可完成配置。 arch/arm/boot/dts 目录里面是对应开发平台的设备树文件 :

image-20230802221632663

arch/arm/boot 目录下会保存编译出来的 Image 和 zImage 镜像文件,而 zImage 就是我们要用的 linux 镜像文件。

arch/arm/mach-xxx 目录分别为相应平台的驱动和初始化文件,比如 mach-imx 目录里面就是 I.MX 系列 CPU 的驱动和初始化文件。

3.2 block 目录

block 是 Linux 下块设备目录,像 SD 卡、 EMMC、 NAND、硬盘等存储设备就属于块设备,block 目录中存放着管理块设备的相关文件。

2.3 crypto 目录

crypto 目录里面存放着加密文件,比如常见的 crc、 crc32、 md4、 md5、 hash 等加密算法。

2.4 Documentation 目录

此目录里面存放着 Linux 相关的文档,如果要想了解 Linux 某个功能模块或驱动架构的功能,就可以在 Documentation 目录中查找有没有对应的文档。

2.5 drivers 目录

驱动目录文件,此目录根据驱动类型的不同,分门别类进行整理,比如 drivers/i2c 就是 I2C相关驱动目录, drivers/gpio 就是 GPIO 相关的驱动目录,这是我们学习的重点。

2.6 firmware 目录

此目录用于存放固件。

2.7 fs 目录

此目录存放文件系统,比如 fs/ext2、 fs/ext4、 fs/f2fs 等,分别是 ext2、 ext4 和 f2fs 等文件系统。

3. VScode工程

还和之前一样,创建一个VScode工程,方便管理工程,工程工作区文件内容如下:

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
{
"folders": [
{
"path": "."
}
],
"settings": {
// 搜索时不想显示的文件可按以下格式屏蔽(为 true 时屏蔽)
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
"**/*.o":true,
"**/*.su":true,
"**/*.cmd":true,
"Documentation":true,

/* 屏蔽不用的架构相关的文件 */
"arch/alpha":true,
"arch/arc":true,
"arch/arm64":true,
"arch/avr32":true,
"arch/[b-z]*":true,
"arch/arm/plat*":true,
"arch/arm/mach-[a-h]*":true,
"arch/arm/mach-[n-z]*":true,
"arch/arm/mach-i[n-z]*":true,
"arch/arm/mach-m[e-v]*":true,
"arch/arm/mach-k*":true,
"arch/arm/mach-l*":true,

/* 屏蔽排除不用的配置文件 */
"arch/arm/configs/[a-h]*":true,
"arch/arm/configs/[j-z]*":true,
"arch/arm/configs/imo*":true,
"arch/arm/configs/in*":true,
"arch/arm/configs/io*":true,
"arch/arm/configs/ix*":true,
/* 屏蔽掉不用的 DTB 文件 */
"arch/arm/boot/dts/[a-h]*":true,
"arch/arm/boot/dts/[k-z]*":true,
"arch/arm/boot/dts/in*":true,
"arch/arm/boot/dts/imx1*":true,
"arch/arm/boot/dts/imx7*":true,
"arch/arm/boot/dts/imx2*":true,
"arch/arm/boot/dts/imx3*":true,
"arch/arm/boot/dts/imx5*":true,
"arch/arm/boot/dts/imx6d*":true,
"arch/arm/boot/dts/imx6q*":true,
"arch/arm/boot/dts/imx6s*":true,
"arch/arm/boot/dts/imx6ul-*":true,
"arch/arm/boot/dts/imx6ull-9x9*":true,
"arch/arm/boot/dts/imx6ull-14x14-ddr*":true,
},
// 不想在工作区显示的文件可按以下格式屏蔽(为 true 时屏蔽)
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/*.o":true,
"**/*.su":true,
"**/*.cmd":true,
"Documentation":true,

/* 屏蔽不用的架构相关的文件 */
"arch/alpha":true,
"arch/arc":true,
"arch/arm64":true,
"arch/avr32":true,
"arch/[b-z]*":true,
"arch/arm/plat*":true,
"arch/arm/mach-[a-h]*":true,
"arch/arm/mach-[n-z]*":true,
"arch/arm/mach-i[n-z]*":true,
"arch/arm/mach-m[e-v]*":true,
"arch/arm/mach-k*":true,
"arch/arm/mach-l*":true,

/* 屏蔽排除不用的配置文件 */
"arch/arm/configs/[a-h]*":true,
"arch/arm/configs/[j-z]*":true,
"arch/arm/configs/imo*":true,
"arch/arm/configs/in*":true,
"arch/arm/configs/io*":true,
"arch/arm/configs/ix*":true,

/* 屏蔽掉不用的 DTB 文件 */
"arch/arm/boot/dts/[a-h]*":true,
"arch/arm/boot/dts/[k-z]*":true,
"arch/arm/boot/dts/in*":true,
"arch/arm/boot/dts/imx1*":true,
"arch/arm/boot/dts/imx7*":true,
"arch/arm/boot/dts/imx2*":true,
"arch/arm/boot/dts/imx3*":true,
"arch/arm/boot/dts/imx5*":true,
"arch/arm/boot/dts/imx6d*":true,
"arch/arm/boot/dts/imx6q*":true,
"arch/arm/boot/dts/imx6s*":true,
"arch/arm/boot/dts/imx6ul-*":true,
"arch/arm/boot/dts/imx6ull-9x9*":true,
"arch/arm/boot/dts/imx6ull-14x14-ddr*":true,
},
}
}

三、NXP内核和设备树启动测试

上边我们编译完后,会的到下边两个文件:

image-20230802222948023

他们位于linux内核源码的这两个目录中:

1
2
arch/arm/boot/zImage
arch/arm/boot/dts/imx6ull-14x14-evk.dtb

我们按照之前的方式,将这两个文件放到tftp目录下:

1
2
cp arch/arm/boot/zImage ~/3tftp/imx6ull/
cp arch/arm/boot/dts/imx6ull-14x14-evk.dtb ~/3tftp/imx6ull/
image-20230802223238289

由于设备树名字变了,所以我们还要修改一下uboot中的bootcmd参数:

1
2
=> setenv bootcmd 'tftp 80800000 /imx6ull/zImage\;tftp 83000000 /imx6ull/imx6ull-14x14-evk.dtb\;bootz 80800000 - 83000000'
=> saveenv

然后重启开发板即可,但是正常来讲由于我们的网口是跟evk板不同,所以linux内核可以起来,但是由于网口驱动异常,所以会卡在这里:

image-20230802223537239

但是到这里其实我们的目的已经达到了,就是获取zImage和dtb设备树,我们知道怎么编译就可以了,后边就是学习内核、然后移植和开发啦。