一、简介
1.1 Linux内核
Kernel 即是Linux内核,Linux内核采用宏内核架构,即Linux大部分功能都会在内核中实现,如进程管理、内存管理、设备管理、文件管理以及网络管理等功能,Linux在发展的过程中,引入了内核模块(Loadable Kernel Module,LKM)机制,内核模块全称为动态可加载内核模块,就是在内核运行时可以动态加载一组目标代码来实现某些特定的功能,在这过程中不需要重新编译内核就可以实现动态扩展。
1.2 Linux内核组成
Linux内核主要由5部分组成,分别为:进程管理子系统
,内存管理子系统
,文件子系统
,网络子系统
,设备子系统
。
-
进程管理
负责进程的创建和销毁,进程的调度。 -
内存管理
负责内存的分配和回收,记录哪些内存被哪些进程使用,管理虚拟内存,将内存的物理地址和逻辑地址做一个映射,主要由MMU进行转换,页表的方式。 -
文件系统
这里的文件系统不仅仅只是硬盘的抽象管理,它也可以是某些io口的抽象;文件系统屏蔽了底层的细节,为上层提供统一的接口;linux中一切皆文件。 -
网络功能
网络功能值的是除了驱动程序提供的基本硬件操作外,还有系统提供的机制和功能,比如TCP协议,地址解析等。 -
设备管理
设备管理功能主要由驱动程序提供,主要任务是控制设备完成输入或输出操作;linux把设备看作是特殊的文件,系统通过处理文件的接口(虚拟文件系统VFS)来管理和控制各种设备。
二、安装编译工具和依赖
sudo apt install make gcc-arm-linux-gnueabihf gcc bison flex libssl-dev dpkg-dev lzop vim libncurses5-dev
三、获取Linux内核
【不推荐,仅列出】
- 官方kernel下载:https://git.kernel.org
- NXP提供kernel下载:https://source.codeaurora.org/external/imx/linux-imx
【新手推荐使用以下开发板商提供kernel】
- 野火提供kernel下载:https://github.com/Embedfire/ebf_linux_kernel.git
- 韦东山提供kernel下载:https://e.coding.net/weidongshan/imx-linux4.9.88.git
四、Linux内核工程结构
此处仅列出一些常见的目录:
目录/文件 | 说明 |
---|---|
arch | 硬件架构相关目录 |
block | 块设备相关目录 |
crypto | 加密和散列算法相关目录 |
Documentation | 内核各部分的文档描述 |
drivers | 设备驱动相关目录 |
firmeare | 固件相关目录 |
fs | 文件系统相关目录 |
include | 编译核心所需要的大部分头文件相关目录 |
init | 内核初始化相关目录 |
ipc | 进程间通信相关目录 |
kernel | 内核相关目录 |
lib | 库相关目录 |
mm | 内存管理相关目录 |
net | 网络协议栈相关目录 |
samples | 例程相关目录 |
scripts | 脚本相关目录 |
security | 内核安全相关目录 |
sound | 音频处理相关目录 |
tools | 工具相关目录 |
usr | 实现用于打包和压缩的cpio等 |
五、编译野火提供Linux内核
编译 Kernel 有两种方法:
- 一种是编译较为通用的
zImage
,常用于构建成镜像固件。 - 另一种则是编译成
deb
安装包,将其下载到板子上安装即可更新 Kernel。
5.1 编译内核zImage
-
获取野火提供Linux内核源码
git clone https://gitee.com/Embedfire/ebf_linux_kernel_6ull_depth1
-
进入工程目录
cd ebf_linux_kernel_6ull_depth1
-
清除工程
清除上次生成的编译环境,避免之前的环境干扰影响编译结果
sudo make distclean
-
配置工程
sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- npi_v7_defconfig
- ARCH=arm:设置目标为 arm 架构
- CROSS_COMPILE:指定所使用的交叉编译器
-
配置内核选项
sudo make menuconfig KCONFIG_CONFIG=arch/arm/configs/npi_v7_defconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
这里我们不需要做任何的配置,直接按两下ESC
键退出。
-
编译工程
sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8
- ARCH=arm:设置目标为 arm 架构
- CROSS_COMPILE:指定所使用的交叉编译器
- -j8:允许8个编译命令同时执行,提高编译速度
编译过程中可能出现的错误:解决方法:Ubuntu 22.04编译Linux内核提示错误multiple definition of `yylloc‘
-
生成文件
- zImage :编译得到的 zImage 内核在
arch/arm/boot
目录下。 - 设备树 :在
arch/arm/boot/dts
目录下,设备树分为 emmc 版本 imx6ull-mmc-npi.dtb 以及 nand 版本 imx6ull-nand-npi.dtb 。
- zImage :编译得到的 zImage 内核在
-
新建编译脚本文件
每次编译 kernel 都要输入一长串命令,为了简单起见,我们可以新建一个 shell 脚本文件,将这些命令写到 shell 脚本文件里面,然后每次只需要执行 shell 脚本即可完成编译工作。-
新建名为 imx6ull_kernel.sh 的 shell 脚本文件:
vim imx6ull_kernel.sh
-
然后在里面输入如下内容:
#!/bin/bash sudo make distclean sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- npi_v7_defconfig sudo make menuconfig KCONFIG_CONFIG=arch/arm/configs/npi_v7_defconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
- 第1行:shell 脚本要求的,必须是 “#!/bin/bash” 或者 “#!/bin/sh”。
- 第2行:使用了 make 命令,用于清理工程,也就是每次在编译 uboot 之前都清理一下工程。带有三个参数,第一个是 ARCH,也就是指定架构,这里肯定是 arm;第二个参数 CROSS_COMPILE 用于指定编译器,只需要指明编译器前缀就行了,比如 arm-linux-gnueabihf-gcc 编译器的前缀就是 “arm-linux-gnueabihf-”;最后一个参数 distclean 就是清除工程。
- 第3-4行:也使用了 make 命令,用于配置 kernel。
- 第5行:用于编译 kernel,通过第 3 行配置好 kernel 以后就可以直接 “make” 编译 kernel 了
-
增加可执行权限
chmod 777 imx6ull_kernel.sh
-
执行脚本文件
./imx6ull_kernel.sh
-
5.2 编译内核deb安装包
-
获取野火提供U-Boot源码
git clone https://gitee.com/Embedfire/ebf_linux_kernel_6ull_depth1
-
安装必要软件
sudo apt install build-essential
-
进入工程目录
cd ebf_linux_kernel_6ull_depth1
-
运行野火提供的make_deb.sh脚本
sudo ./make_deb.sh
这种编译方式编译内核,构建出来的 deb 安装包可直接使用
sudo dpkg -i xxx.deb
命令安装在鲁班猫系统上,然后重启使用cat /proc/version
查看内核是否更新。编译成功打印消息如下:
- 生成文件
构成生成的 deb 包在内核源码/build_image
目录下。
• 由 Leung 写于 2022 年 9 月 12 日
• 参考:10. Linux内核的编译