编译生成IMX6ULL开发板的Linux内核(Kernel)zImage文件、设备树文件(dtb)、内核模块(ko)文件,编译好后更新(替换)开发板上之前的【编译内核-内核编译】

准备工作

之前已经利用git命令把IMX6ULL开发板的BSP克隆到Ubuntu中了,详情见
https://blog.youkuaiyun.com/wenhao_ir/article/details/144325141

之前也已经配置好gcc交叉编译器了,详情见
https://blog.youkuaiyun.com/wenhao_ir/article/details/144326545

关于zImage文件、设备树文件(dtb)、内核模块(ko)文件的介绍

关于zImage文件、设备树文件(dtb)、内核模块(ko)文件的详细介绍见:
https://blog.youkuaiyun.com/wenhao_ir/article/details/144422140

当然通过一个完整的移植u-boot、设备树、内核、驱动的完整过程能更好的理解这些文件,详情请在优快云博客的“内容管理”中搜索“移植。”

Linux-4.9.88源码来源及百度网盘下载地址

Linux-4.9.88源码来源请参考博文 https://blog.youkuaiyun.com/wenhao_ir/article/details/144325141

通过上面这篇博文利用git得到的Linux-4.9.88源码我打包了一份,压缩包下载地址:
https://pan.baidu.com/s/1yjIBXmxG9pwP0aOhW8VAVQ?pwd=e9cv
注意:只能在大小写敏感的文件系统中解压,比如ext4文件系统中解压,否则会出现因大小写不敏感而导致重名的问题,详见 https://blog.youkuaiyun.com/wenhao_ir/article/details/144871115

配置Linux源码

不同的开发板有不同的配置文件,配置文件位于内核源码arch/arm/configs/ 目录,如下图所示:
在这里插入图片描述
确认有配置文件100ask_imx6ull_defconfig后,切换到Linux的源码目录:

cd /home/book/100ask_imx6ull-sdk/Linux-4.9.88

然后执行下面的命令:

make mrproper

make mrproper 是清理编译环境的命令,用于移除内核源码目录中可能遗留的编译产物和配置文件,确保一个干净的编译环境。
在这里插入图片描述

再执行下面的命令:

make 100ask_imx6ull_defconfig

100ask_imx6ull_defconfig 是为特定硬件平台(例如这里的 100ASK IMX6ULL 开发板)提供的预定义配置文件。这个命令会将该设备的默认配置复制到内核源码目录的 .config 文件中,作为后续编译的配置基础。
在这里插入图片描述

内核(Kernel)的zImage文件的编译生成

上面的准备工作做好后, 执行生成zImage文件的命令即可生成zImage文件:

make zImage -j4

-j4 参数指定使用4个线程并行编译以加快速度。
这里要花点时间,我是吃午饭前开始编译,吃完午饭后发现编译结束的,应该花费的时间 5到10分钟吧,注意,CPU负载会比较高,夏天的话注意给CPU做好降温准备后再开始编译。
编译完后图如下:
在这里插入图片描述
在这里插入图片描述
大小只有8.8M
在这里插入图片描述
把生成的这个 zImage 文件复制到NFS目录中备用:

cp arch/arm/boot/zImage ~/nfs_rootfs

在这里插入图片描述

设备树文件(dtb)的编译生成

编译完成 zImage 后才可编译设备树文件,编译命令如下:

同样要先进入Linux的源码目录:

cd /home/book/100ask_imx6ull-sdk/Linux-4.9.88

然后执行下面这条命令编译出设备树的dtb文件:

make dtbs

在这里插入图片描述
生成的dtb文件位于/arm/boot/dts/100ask_imx6ull-14x14.dtb中。
绝对路径:/home/book/100ask_imx6ull-sdk/Linux-4.9.88/arch/arm/boot/dts
在这里插入图片描述
注意:上图中的dts就是设备树文件的源码。
把生成的这个文件 100ask_imx6ull-14x14.dtb 复制到NFS目录中备用:

cp arch/arm/boot/dts/100ask_imx6ull-14x14.dtb ~/nfs_rootfs

在这里插入图片描述

编译内核模块并安装内核模块到指定的目录

同样要先进入Linux的源码目录:

cd /home/book/100ask_imx6ull-sdk/Linux-4.9.88

用下面这条命令编译内核模块:

make modules

在这里插入图片描述
使用 make modules 生成的 Linux 内核模块通常存储在 Linux 源代码树中的各个子目录下,根据模块对应的功能和分类决定具体位置。一般情况下,模块生成的 .ko 文件(Kernel Object 文件)会出现在以下目录中:

  • drivers/:驱动程序模块,例如网卡、显卡、存储设备驱动等。

    • 示例:drivers/net/drivers/gpu/drivers/usb/
  • fs/:文件系统模块,例如 ext4、xfs、nfs 等文件系统支持。

    • 示例:fs/ext4/fs/nfs/
  • net/:网络相关模块,例如 TCP/IP 协议栈的扩展。

  • arch/:与特定架构相关的模块,例如 ARM、x86 架构的特定硬件支持。

  • sound/:与音频设备相关的模块。

  • crypto/:与加密算法或安全相关的模块。

  • lib/:通用的库模块,例如压缩算法支持等。

模块的生成路径与它们在源码目录中的位置是一致的。例如:

  • 如果模块的源代码文件是 drivers/net/ethernet/e1000/e1000_main.c,则编译生成的模块会在对应的 drivers/net/ethernet/e1000/ 目录中。

在这里插入图片描述
面对这些分散的模块文件,我们怎么办呢?此时就要使用make modules_install命令来安装它们到指定的目录了,这里我们把安装位置设为/home/book/nfs_rootfs/,命令如下:

make ARCH=arm INSTALL_MOD_PATH=/home/book/nfs_rootfs modules_install

这里要说明下参数“ARCH=arm”的作用,它是告诉make modules_install命令我的目标架构是什么,从而确保模块被安装到与目标架构相关的正确目录结构中,如果没有设置 ARCH=arm,它有可能会将模块安装到别的架构的目录结构中,比如如果“ARCH=arm”,那么目录结构为:/home/book/nfs_rootfs/lib/modules/4.9.88/.....,但如果没有设置这个值,就可能成目录结构: /lib/modules/x86_64....了。

执行完成后,在目录/home/book/nfs_rootfs下成了lib目录及相关的子目录:
在这里插入图片描述
在这里插入图片描述

安装内核(Kernel)zImage文件、设备树文件(dtb)、内核模块(ko)文件到开发板上

通过上面的品作,NFS文件下已经有下图红框中圈着的三个文件或目录了。
在这里插入图片描述
接下来我们通过挂载NFS文件的方式,将这些文件传到开发板的Linux系统的对应目录下,从而完成内核的更新。

传这些文件之前先确认开发板的根目录上有下面这些目录:

/boot
/lib

打开串口,启动开发板,执行下面的命令:

cd ..
ls

在这里插入图片描述
我们再看下当前boot目录中有哪些文件:

cd /boot
ls

在这里插入图片描述
可见是存在内核zImage文件和设备树100ask_imx6ull-14x14.dtb文件的,我们现在是要把自己编译得到的覆盖掉之前的。

再看lib目录下有哪些文件:

cd /lib
ls

在这里插入图片描述
可见,里面是已经有目录bash和firmware的,我们现在是要把自己编译得到的模块库覆盖掉之前的。

然后测试一下开发板和Ubuntu中能不能互相Ping通,具体怎么Ping,详情见 https://blog.youkuaiyun.com/wenhao_ir/article/details/144425154

能互相Ping通后再在开发板中挂载NFS文件:

mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt

挂载好后首先复制zImage文件,命令如下:

cp /mnt/zImage /boot/

执行完后注意执行下面的命令以使数据真正写入,因为有可能文件数据可能仍在缓存中,而尚未真正写入存储设备。

sync

至于为什么内核镜像是存放于目录/boot下,这其实是由u-boot的相关环境变量来决定的,详情见博文 https://blog.youkuaiyun.com/wenhao_ir/article/details/145953214 【搜索“详解u-boot倒计时完成后执行的首条命令相关的环境变量”】
另外,还要问下怎么样确认更新成功了内核?请看下面这篇博文:
https://blog.youkuaiyun.com/wenhao_ir/article/details/146599539

然后是复制设备树文件(dtb),命令如下:

cp /mnt/100ask_imx6ull-14x14.dtb /boot/

执行完后注意执行下面的命令以使数据真正写入,因为有可能文件数据可能仍在缓存中,而尚未真正写入存储设备。

sync

注意:这条命令有时候看上去运行成功了,但实际上设备树并没有更新,并且在后面的第二次重启(注意:不是第1次重启),会提示设备树文件不存在,此时我还得去重新烧写dtb文件,所以第一次重启后请务必按照博文 https://blog.youkuaiyun.com/wenhao_ir/article/details/146455604](https://blog.youkuaiyun.com/wenhao_ir/article/details/146455604) 【搜索“看下内核中有没有相关的设备树节点”】去看下相关的节点有没有新增或是被修改,如果没有,请赶紧重新复制,复制的时候可以考虑先删除再复制。

至于为什么设备树文件是存放于目录/boot下,这其实是由u-boot的相关环境变量来决定的,详情见博文 https://blog.youkuaiyun.com/wenhao_ir/article/details/145953214 【搜索“详解u-boot倒计时完成后执行的首条命令相关的环境变量”】

最后是复制模块ko文件,命令如下:

cp /mnt/lib/modules /lib/ -rfd

上面命令中的参数-rfd是什么意思?
在 Linux 的 cp 命令中,选项 -rfd 实际上是组合了多个选项的写法,用来指定 cp 命令的行为。我们可以分解并逐一解释每个选项的含义:
1. -r

  • 全称--recursive
  • 含义:递归复制目录及其内容。
  • 作用:如果源路径是一个目录,cp 会递归地复制该目录下的所有内容,包括子目录及文件。

2. -f

  • 全称--force
  • 含义:强制覆盖目标文件。
  • 作用
    • 如果目标文件已存在,cp 会覆盖它而不会提示。
    • 如果目标文件无法写入(例如权限问题),cp 会尝试先删除目标文件,然后再复制。

3. -d

  • 全称--no-dereference
  • 含义:保留符号链接而不解引用。
  • 作用
    • 如果源文件是符号链接,cp 会复制符号链接本身,而不是符号链接指向的目标文件。
    • 这对于复制目录或系统文件时非常重要,因为有些系统文件以符号链接形式存在。

上面三条命令执行完毕后的截图如下:
在这里插入图片描述
此时重启下系统,看下系统还能启动不…如果顺利启动,那么就是用的新的内核(Kernel)zImage文件、设备树文件(dtb)、内核模块(ko)文件了。

至此,更换完毕!

另外,还要问下怎么样确认更新成功了内核?请看下面这篇博文:
https://blog.youkuaiyun.com/wenhao_ir/article/details/146599539

附编译出的内核镜像、设备树文件、lib库(固件和模块库)

百度网盘地址:
https://pan.baidu.com/s/1P5eO50vHiuH-eFylWb3EPQ?pwd=hnq9

延伸:如何将一个包含u-boot、内核、设备树、文件系统的镜像烧写到eMMC存储器中?

参考博文 https://blog.youkuaiyun.com/wenhao_ir/article/details/145367198 【搜索“BV1HT421k7GW”】

为了将最新版本的Linux内核移植到i.MX6ULL开发板上,以下是详细的步骤指南: ### 准备工作 1. **获取最新Linux内核源码** 访问 [kernel.org](https://www.kernel.org/) 下载最新的稳定版Linux内核源码。例如,使用`wget`命令下载: ```bash wget https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.32.tar.xz ``` 2. **解压源码包** 使用以下命令解压下载内核源码包: ```bash tar -xvf linux-5.4.32.tar.xz cd linux-5.4.32 ``` ### 配置交叉编译环境 1. **安装交叉编译工具链** 确保已经安装了适用于ARM架构的交叉编译工具链。可以使用如下命令安装: ```bash sudo apt-get install gcc-arm-linux-gnueabi ``` 2. **设置交叉编译环境变量** 设置交叉编译器的路径,以便在编译过程中使用正确的工具链: ```bash export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabi- ``` ### 配置内核 1. **选择默认配置** 使用i.MX6ULL的默认配置文件来初始化内核配置: ```bash make imx_v7_defconfig ``` 2. **自定义内核配置(可选)** 如果需要对内核进行特定的功能调整,可以运行以下命令进入配置界面: ```bash make menuconfig ``` ### 编译内核 1. **编译内核镜像** 使用多线程加速编译过程,假设你的机器有4个CPU核心: ```bash make -j4 zImage ``` 2. **编译设备树** 编译适用于i.MX6ULL设备树文件: ```bash make dtbs ``` ### 复制内核设备树文件 1. **复制内核镜像** 将生成内核镜像文件复制到TFTP服务器的根目录中,以便通过网络加载: ```bash cp arch/arm/boot/zImage /home/book/linux/tftpboot/ ``` 2. **复制设备树文件** 将生成设备树文件也复制到TFTP服务器的根目录中: ```bash cp arch/arm/boot/dts/imx6ull-*.dtb /home/book/linux/tftpboot/ ``` ### 更新U-Boot引导参数 1. **修改U-Boot环境变量** 在U-Boot提示符下,更新内核设备树的加载地址以及启动参数: ```bash setenv bootargs console=ttymxc0,115200 root=/dev/mmcblk0p2 rootwait setenv kernel zImage setenv fdtfile imx6ull-14x14-evk-emmc.dtb saveenv ``` 2. **加载并启动内核** 通过TFTP从服务器加载内核设备树,并启动系统: ```bash tftp 80800000 ${kernel} tftp 83000000 ${fdtfile} bootz 80800000 - 83000000 ``` ### 常见问题与调试 - **内核崩溃或无法启动** 检查内核配置是否正确,特别是关于硬件支持的部分。确保使用的设备树文件与目标硬件匹配。 - **串口输出无显示** 确认串口线连接正确,并且终端软件的波特率设置为115200。 - **网络加载失败** 确保TFTP服务器正常运行,并且开发板能够访问该服务器。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昊虹AI笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值