准备工作
之前已经利用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”】
4928

被折叠的 条评论
为什么被折叠?



