准备工作
之前已经利用git命令把IMX6ULL开发板的BSP克隆到Ubuntu中了,详情见
http://iyenn.com/rec/1709244.html
之前也已经配置好gcc交叉编译器了,详情见
http://iyenn.com/rec/1709220.html
关于zImage文件、设备树文件(dtb)、内核模块(ko)文件的介绍
关于zImage文件、设备树文件(dtb)、内核模块(ko)文件的详细介绍见:
http://iyenn.com/rec/1709284.html
配置Linux源码
不同的开发板有不同的配置文件,配置文件位于内核源码arch/arm/configs/
目录,如下图所示:
确认有配置文件100ask_imx6ull_defconfig
后,切换到Linux的源码目录:
cd /home/book/100ask_imx6ull-sdk/Linux-4.9.88
- 1
然后执行下面的命令:
make mrproper
- 1
make mrproper 是清理编译环境的命令,用于移除内核源码目录中可能遗留的编译产物和配置文件,确保一个干净的编译环境。
再执行下面的命令:
make 100ask_imx6ull_defconfig
- 1
100ask_imx6ull_defconfig 是为特定硬件平台(例如这里的 100ASK IMX6ULL 开发板)提供的预定义配置文件。这个命令会将该设备的默认配置复制到内核源码目录的 .config 文件中,作为后续编译的配置基础。
内核(Kernel)的zImage文件的编译生成
上面的准备工作做好后, 执行生成zImage文件的命令即可生成zImage文件:
make zImage -j4
- 1
-j4 参数指定使用4个线程并行编译以加快速度。
这里要花点时间,我是吃午饭前开始编译,吃完午饭后发现编译结束的,应该花费的时间 5到10分钟吧,注意,CPU负载会比较高,夏天的话注意给CPU做好降温准备后再开始编译。
编译完后图如下:
大小只有8.8M
把生成的这个 zImage 文件复制到NFS目录中备用:
cp arch/arm/boot/zImage ~/nfs_rootfs
- 1
设备树文件(dtb)的编译生成
编译完成 zImage 后才可编译设备树文件,编译命令如下:
同样要先进入Linux的源码目录:
cd /home/book/100ask_imx6ull-sdk/Linux-4.9.88
- 1
然后执行下面这条命令:
make dtbs
- 1
生成的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
- 1
编译内核模块并安装内核模块到指定的目录
同样要先进入Linux的源码目录:
cd /home/book/100ask_imx6ull-sdk/Linux-4.9.88
- 1
用下面这条命令编译内核模块:
make modules
- 1
使用
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
- 1
这里要说明下参数“ARCH=arm”的作用,它是告诉make modules_install
命令我的目标架构是什么,从而确保模块被安装到与目标架构相关的正确目录,如果没有设置 ARCH=arm,它有可能会尝试将模块安装到默认的目录(如 /lib/modules/x86_64/)。
那这里有问题了,为什么我在执行模块编译命令“make modules”时没有加上这个参数呢?那是因为我在准备工作中已经把配置文件写好。
执行完成后,在目录/home/book/nfs_rootfs
下成了lib目录及相关的子目录:
安装内核(Kernel)zImage文件、设备树文件(dtb)、内核模块(ko)文件到开发板上
通过上面的品作,NFS文件下已经有下图红框中圈着的三个文件或目录了。
接下来我们通过挂载NFS文件的方式,将这些文件传到开发板的Linux系统的对应目录下,从而完成内核的更新。
传这些文件之前先确认开发板的根目录上有下面这些目录:
/boot
/lib
- 1
- 2
打开串口,启动开发板,执行下面的命令:
cd ..
ls
- 1
- 2
我们再看下当前boot目录中有哪些文件:
cd /boot
ls
- 1
- 2
可见是存在内核zImage文件和设备树100ask_imx6ull-14x14.dtb文件的,我们现在是要把自己编译得到的覆盖掉之前的。
再看lib目录下有哪些文件:
cd /lib
ls
- 1
- 2
可见,里面是已经有目录bash和firmware的,我们现在是要把自己编译得到的模块库覆盖掉之前的。
然后测试一下开发板和Ubuntu中能不能互相Ping通,具体怎么Ping,详情见 http://iyenn.com/rec/1709532.html
能互相Ping通后再在开发板中挂载NFS文件:
mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt
- 1
挂载好后首先复制zImage文件,命令如下:
cp /mnt/zImage /boot/
- 1
然后是复制设备树文件(dtb),命令如下:
cp /mnt/100ask_imx6ull-14x14.dtb /boot/
- 1
最后是复制模块ko文件,命令如下:
cp /mnt/lib/modules /lib/ -rfd
- 1
上面命令中的参数-rfd
是什么意思?
在 Linux 的 cp
命令中,选项 -rfd
实际上是组合了多个选项的写法,用来指定 cp
命令的行为。我们可以分解并逐一解释每个选项的含义:
1. -r
- 全称:
--recursive
- 含义:递归复制目录及其内容。
- 作用:如果源路径是一个目录,
cp
会递归地复制该目录下的所有内容,包括子目录及文件。
2. -f
- 全称:
--force
- 含义:强制覆盖目标文件。
- 作用:
- 如果目标文件已存在,
cp
会覆盖它而不会提示。 - 如果目标文件无法写入(例如权限问题),
cp
会尝试先删除目标文件,然后再复制。
- 如果目标文件已存在,
3. -d
- 全称:
--no-dereference
- 含义:保留符号链接而不解引用。
- 作用:
- 如果源文件是符号链接,
cp
会复制符号链接本身,而不是符号链接指向的目标文件。 - 这对于复制目录或系统文件时非常重要,因为有些系统文件以符号链接形式存在。
- 如果源文件是符号链接,
上面三条命令执行完毕后的截图如下:
此时重启下系统,看下系统还能启动不…如果顺利启动,那么就是用的新的内核(Kernel)zImage文件、设备树文件(dtb)、内核模块(ko)文件了。
至此,更换完毕!
如何通过一个文件img烧录boot、内核、设备树、文件系统到开发板?
参考博文 http://iyenn.com/rec/1709264.html 【搜索“BV1HT421k7GW”】



评论记录:
回复评论: