LV05-03-Kernel-01-NXP-linux

本文主要是kernel——NXP官方固件的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
PC端开发环境 Windows Windows11
Ubuntu Ubuntu20.04.2的64位版本
VMware® Workstation 17 Pro 17.6.0 build-24238078
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
Win32DiskImager Win32DiskImager v1.0
Linux开发板环境 Linux开发板 正点原子 i.MX6ULL Linux 阿尔法开发板
uboot NXP官方提供的uboot,使用的uboot版本为U-Boot 2019.04
linux内核 linux-4.19.71(NXP官方提供)
点击查看本文参考资料
分类 网址 说明
官方网站 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内核的仓库
nxp-imx/linux-imx/releases/tag/v4.19.71 NXP linux内核仓库tags中的v4.19.71
nxp-imx/uboot-imx/releases/tag/rel_imx_4.19.35_1.1.0 NXP u-boot仓库tags中的rel_imx_4.19.35_1.1.0
I.MX6ULL i.MX 6ULL Applications Processors for Industrial Products I.MX6ULL 芯片手册(datasheet,可以在线查看)
i.MX 6ULL Applications ProcessorReference Manual I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网)
Source Code https://elixir.bootlin.com/linux/latest/source linux kernel源码
https://elixir.bootlin.com/u-boot/latest/source uboot源码

一、linux内核

我们可以看到内核源码目录中大概会有这些文件:

image-20241102165526821
  • arch:主要包含和硬件体系结构相关的代码,如arm、x86、MIPS,PPC,每种CPU平台占一个相应的目录,例如我们使用的imx系列CPU就在 arch/arm/mach-imx 目录下,Linux内核目前已经支持30种左右的CPU体系结构。arch中的目录下存放的是各个平台以及各个平台的芯片对Linux内核进程调度、 内存管理、 中断等的支持,以及每个具体的SoC和电路板的板级支持代码。
  • block:在Linux中block表示块设备(以块(多个字节组成的整体,类似于扇区)为单位来整体访问),譬如说SD卡、Nand、硬盘等都是块设备,block目录下放的是一些Linux存储体系中关于块设备管理的代码。
  • crypto:这个文件夹下存放的是常用加密和散列算法(如md5、AES、 SHA等) ,还有一些压缩和CRC校验算法。
  • Documentation:内核各部分的文档描述。
  • drivers:设备驱动程序,里面列出了linux内核支持的所有硬件设备的驱动源代码,每个不同的驱动占用一个子目录,如char、 block、 net、 mtd、 i2c等。
  • fs:fs就是file system,里面包含Linux所支持的各种文件系统,如EXT、 FAT、 NTFS、 JFFS2等。
  • include:目录包括编译核心所需要的大部分头文件,例如与平台无关的头文件在 include/linux 子目录下,与cpu架构相关的头文件在include目录下对应的子目录中。
  • init:内核初始化代码,这个目录下的代码就是linux内核启动时初始化内核的代码。
  • ipc:ipc就是 inter process commuication ,进程间通信,该文件夹下都是linux进程间通信的代码。
  • kernel:kernel就是Linux内核,是Linux中最核心的部分,包括进程调度、定时器等,而和平台相关的一部分代码放在 arch/*/kernel 目录下。
  • lib:lib是库的意思,lib目录下存放的都是一些公用的有用的库函数,注意这里的库函数和C语言的库函数不一样的,因为在内核编程中是不能用C语言标准库函数的,所以需要使用lib中的库函数,除此之外与处理器结构相关的库函数代码被放在 arch/*/lib/ 目录下。
  • mm: 目录包含了所有独立于 cpu 体系结构的内存管理代码,如页式存储管理内存的分配和释放等,而与具体硬件体系结构相关的内存管理代码位于 arch/*/mm 目录下,例如 arch/arm/mm/fault.c
  • net: 网络协议栈相关代码,net目录下实现各种常见的网络协议。
  • scripts:这个目录下全部是脚本文件,这些脚本文件不是linux内核工作时使用的,而是用了配置编译linux内核的。
  • security:内核安全模型相关的代码,例如最有名的SELINUX。
  • sound: ALSA、 OSS音频设备的驱动核心代码和常用设备驱动。
  • usr: 实现用于打包和压缩的cpio等。

提示:对于其他的未列出来的目录,暂时不用去理会。

二、linux内核源码下载

1. 版本选择

由于前面uboot升级到了2019.04,我们这里linux内核也选择一个同年份的,这里我选了4.19.71,主要是它的版本大于4.4支持设备树插件,也有利于后续的学习。

这个版本对于仓库来说还有有些老了,tag地址比较好找:Release v4.19.71 · nxp-imx/linux-imx (github.com),好像还有个类似分支的地址是nxp-imx/linux-imx at v4.19.71 (github.com)

image-20241102164724133可以看到提交记录是:e7d2672c66e4d3675570369bf20856296da312c4。我们点开这个tag就能看到所在的分支:

image-20241102164811762

它所在分支地址:nxp-imx/linux-imx at git.kernel.org/linux-stable/linux-4.19.y (github.com),不过有tag的话我们一般还是使用tag来下载源码。

2. 源码下载

我们通过以下命令下载源码:

1
2
git clone -b v4.19.71 --depth=1 https://github.com/nxp-imx/linux-imx.git
git clone -b v4.19.71 --depth=1 git@github.com:nxp-imx/linux-imx.git

这个仓库比较大,我就没放到自己的gitee上了,只是存了一些修改的文件。

三、编译源码

1. 安装依赖库

貌似前面uboot已经装过了,通用的,这里就不用了。野火的教程中需要安装这些:

1
sudo apt-get install lzop libncurses5-dev

这个lzop要装,不然会报错:

image-20241102171357088

2. 编译源码

1
2
3
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- clean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v6_v7_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16

不出意外的话编译完是这样的:

image-20241102171750221

Linux 内核编译完成以后会在 arch/arm/boot 目录下生成 zImage 镜像文件,如果使用设备树的话还会在 arch/arm/boot/dts 目录下开发板对应的.dtb(设备树)文件,比如 imx6ull-14x14-evk.dtb就是 NXP 官方的 I.MX6ULL EVK 开发板对应的设备树文件。至此我们得到两个文件:

(1)Linux 内核镜像文件: zImage。

(2)NXP 官方 I.MX6ULL EVK 开发板对应的设备树文件: imx6ull-14x14-evk.dtb。

四、内核启动测试

1. tftp环境搭建

这个主要是在ubuntu搭建tftp环境,可以看这个《01嵌入式开发/02IMX6ULL平台/LV02-开发环境/LV02-03-网络环境-02-TFTP环境搭建.md》

2. 拷文件到服务器目录

1
2
3
cd ~/7Linux/imx6ull-kernel 
cp -f arch/arm/boot/zImage ~/3tftp/
cp -f arch/arm/boot/dts/imx6ull-14x14-evk.dtb ~/3tftp/
image-20241102183137319

3. 启动测试

我们使用前面自己移植的uboot,要保证网口可以正常使用:

image-20241102183326480

启动开发板后进入命令模式,然后输入以下命令下载内核镜像和设备树到开发板指定的地址:

1
2
tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-evk.dtb
image-20241102183417930

最后我们启动内核:

1
bootz 80800000 - 83000000
image-20241102183536564

有这些出现表示内核已经成功启动了。但是最后一直处于这个状态:

image-20241102184349887

我们后面再说为什么。

4. 一个问题

我们上面启动后,最后一直提示在打开网口,为什么?

Linux 内核启动以后是需要根文件系统的,根文件系统存在哪里是由 uboot 的 bootargs 环境变量指定,bootargs 会传递给 Linux 内核作为命令行参数 。这里我之前配置了uboot的ip以及服务器参数,默认情况下,会从网络挂载根文件系统:

image-20241102184518183

所以之前启动后,由于linux还未适配我们开发板的网口,驱动还未移植,所以网络不通,就没法挂载就会一直不断尝试。那如果我们不设置根文件系统路径,或者说根文件系统路径设置错误的话会出现什么问题?这个问题是很常见的,我们在实际的工作中开发一个产品,这个产品的第一版硬件出来以后我们是没有对应的根文件系统可用的,必须要自己做根文件系统。在构建出对应的根文件系统之前 Linux 内核是没有根文件系统可用的,此时 Linux 内核启动以后会出现什么问题呢?我们在uboot中设置:

1
setenv bootargs 'console=ttymxc0,115200' # 设置 bootargs
image-20241102184701087

然后按照刚才的命令,启动一下linux内核,看一下会有什么现象:

image-20241102184807074

会发现最后报了一句:

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

也就是提示内核崩溃,因为 VFS(虚拟文件系统)不能挂载根文件系统,因为根文件系统目录不存在。即使根文件系统目录存在,如果根文件系统目录里面是空的依旧会提示内核崩溃。这个就是根文件系统缺失导致的内核崩溃,但是内核是启动了的,只是根文件系统不存在而已。