提示:本系列文章重点学习Linux内核
Linux内核--内核自定义代码配置
简介
提示:在这里先对Linux内核内核自定义代码配置做一个概述,以便大家能更好的理解:
在定制Linux内核时,通过自定义代码配置是一种常见的方法。这种方法允许开发人员根据特定需求,添加、修改或删除内核的功能和选项。本文将介绍Linux内核自定义代码配置的概述,包括配置的原因、方法和常见用途。
提示:以下是本篇文章将重点阐述Linux内核的内核自定义代码配置
一、自定义配置的原因
自定义Linux内核的主要原因包括:
- 定制功能:根据特定的应用场景或需求,添加或删除内核的功能和选项,以满足系统的定制需求。
- 精简内核:移除不需要的功能和模块,以减小内核的体积,提高系统的性能和资源利用率。
- 优化性能:调整内核配置参数,以优化系统的性能和响应速度,适应不同的硬件环境和应用场景。
- 提高安全性:禁用不必要的功能或模块,以减少潜在的安全漏洞和攻击面。
二、常见用途
自定义代码配置的常见用途包括:
- 设备支持:添加或移除特定硬件设备的驱动程序和支持,以适配特定的硬件平台。
- 文件系统:选择性地添加或移除支持的文件系统类型,以适应系统的存储需求。
- 网络功能:启用或禁用特定的网络功能和协议栈,以满足网络通信的需求。
- 内存管理:调整内存管理参数和策略,以优化系统的内存使用和性能。
- 调试和跟踪:添加或移除调试选项和跟踪工具,以便进行系统调试和性能分析。
三、自定义代码添加配置选项过程(静态)
(1)Kconfig配置文件语法格式
1.config代表一个选项的开始,最终会出现在.config中(会自动增加一个CONFIG_前缀)
2.bool代表此选项仅能选中或不选中,bool后面的字符串代表此选项在make menuconfig中的名字
3.tristate:代表可以选择编译、不编译、编译成模块
4.string:字符串; hex:16进制的数; int:10进制的数
5.depends on:依赖其余的选项
6.default:默认选项值
7.select:表示当前config被选中时,此选项也被选中
8.menu/endmenu:表示生成一个菜单
9.choice/endchoice:表示选择性的菜单条目
10.comment:注释信息,菜单和.config文件中都会出现
11.source:用于包含其它Kconfig
(2)添加步骤
将自己开发的内核代码加入到Linux内核中,需要有3个步骤:
- 把自己编写的代码放到内核中合适的位置
- 把自己开发的功能增加到Linux内核的配置选项中,使用户能够选中这项功能并编译
- 构建或修改Makefile,根据用户的选择,将相应的代码编译到最终生成的Linux内核中去
说明:
把自己编写的代码放到内核中合适的位置后,添加修改对应位置的Kconfig文件
在Kconfig中配置完成我们的代码以后,退出重新开启图形配置工具即可。
在配置工具中将新加入的配置设置保存到.config文件中
确保顶层目录下的.config文件中存在新加入的代码配置
在对应位置的Makefile中修改添加配置
完成以上步骤后重新编译内核代码:
make uImage
最后记得更新uImage镜像
四、动态加载
(1)新功能源码与Linux内核源码在同一目录结构下时
给新功能代码配置Kconfig(同静态配置)
给新功能代码改写Makefile(同静态配置)
make menuconfig
界面里将新功能对应的那项选择成<M>
make uImage
cp arch/arm/boot/uImage /tftpboot
make modules
make modules会在新功能源码的同级目录下生成相应的同名.ko文件(生成的ko文件只适用于开发板linux)
注意:此命令执行前,开发板的内核源码已被编译
(2)新功能源码与Linux内核源码不在同一目录结构下时
cd 进入Linux顶层目录
mkdir mydrivercode
cd mydrivercode
cp Linux顶层目录/drivers/char/myhello.c .
添加Makefile文件,源码如下
ifeq ($(KERNELRELEASE),)
# 如果 $(KERNELRELEASE) 为空,则表示当前不是 Linux 内核的构建环境,即执行模块编译。
ifeq ($(ARCH),arm)# 如果当前的架构是 arm,则设置内核源码目录为 /home/linux/linux-6.1
# 自己的linux内核源码目录
KERNELDIR ?= /home/linux/linux-6.1# 设置 ROOTFS 为根文件系统目录 /opt/4412/rootfs
ROOTFS ?= /opt/4412/rootfs
else# 如果不是 arm 架构,则设置内核源码目录为 /lib/modules/当前内核版本号/build
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
# 设置当前目录为 PWD
PWD := $(shell pwd)
# 编译内核模块
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
# 安装内核模块到指定的根文件系统目录
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules INSTALL_MOD_PATH=$(ROOTFS) modules_install
# 清理编译产生的文件
clean:
rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else# 如果 $(KERNELRELEASE) 不为空,则表示当前是 Linux 内核的构建环境,即内核模块的编译阶段。
# 将 myhello.o 添加到 obj-m 变量,表示要编译的目标是 myhello.o 内核模块。
obj-m += myhello.o
endif
vim Makefile
make (生成的ko文件适用于主机ubuntu linux)
make ARCH=arm (生成的ko文件适用于开发板linux,注意此命令执行前,开发板的内核源码已被编译)
提示:
file命令可以查看指定ko文件适用于哪种平台,用法:
file ko文件
结果带x86字样的适用于主机ubuntu Linux,带arm字样的适用于开发板Linux
(3)ko文件的使用
主机ubuntu下使用ko文件
sudo insmod ./文件名.ko #将内核模块插入正在执行的内核中运行 --- 相当于安装插件
lsmod #查看已被插入的内核模块有哪些,显示的是插入内核后的模块名
sudo rmmod 文件名 #,将已被插入的内核模块从内核中移除 ----- 相当于卸载插件
sudo dmesg -C #清除内核已打印的信息
dmesg #查看内核的打印信息
开发板Linux下使用ko文件
#1.先将生成的ko文件拷贝到/opt/4412/rootfs目录下:
#2.在串口终端界面开发板Linux命令行下执行
insmod ./文件名.ko #将内核模块插入正在执行的内核中运行 ----- 相当于安装插件
lsmod #查看已被插入的内核模块有哪些
rmmod 文件名 #将已被插入的内核模块从内核中移除 ----- 相当于卸载插件
内核随时打印信息,我们可以在串口终端界面随时看到打印信息,不需要dmesg命令查看打印信息
五、注意事项
在进行自定义代码配置时,需要注意以下事项:
- 备份配置文件:在进行配置修改之前,务必备份原始的内核配置文件,以防意外发生,可以恢复到原始状态。
- 审慎选择选项:确保添加、修改或删除的选项符合系统的需求和硬件环境,避免导致不可预测的问题。
- 测试和验证:修改配置后,需要进行充分的测试和验证,确保系统的稳定性、兼容性和性能满足预期。
- 持续维护:随着系统需求的变化,可能需要定期重新评估和调整内核的配置,以满足新的需求和性能优化目标。