1. 完整编译
1.1. 查看内核版本
可以使用下列
uname -r
5.13.0
1.2. 下载内核代码
可以直接下载一个比当前内核版本新的代码,也可以去https://mirrors.edge.kernel.org/pub/linux/kernel下载自己内核使用的版本。此文下载的是更新的版本 5.17.15,去官网https://www.kernel.org/,下载linux-5.17.12.tar.xz。
1.3. 解压
tar -xavf linux-5.17.12.tar.xz
1.4. 配置环境
1.4.1. 更换源
不同版本的Ubuntu,需要对应不同版本的源。可以通过。https://mirror.tuna.tsinghua.edu.cn/help/ubuntu/上可以选择不同版本的Ubuntu对应的源。
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
将上述内核拷贝进下面打开的文件。
sudo gedit /etc/apt/sources.list
拷贝完了之后,更新源
sudo apt-get update
1.4.2. 安装依赖
sudo apt-get install gcc g++
sudo apt-get install libncurses5-dev
sudo apt-get install build-essential
sudo apt-get install kernel-package
sudo apt-get install libssl-dev
sudo apt-get install libc6-dev
sudo apt-get install bin86
sudo apt-get install flex
sudo apt-get install bison
sudo apt-get install qttools5-dev
sudo apt-get install libelf-dev
1.5. 编译
1.5.1. 清理
首次编译可以不用清理,编译之后如果想完整重新编译,可以使用清理命令。
# make mrproper会删除配置的.config以及其他备份
sudo make mrproper
# make clean会删除编译过程中生成的中间文件和内核镜像文件
sudo make clean
1.5.2. 配置内核
内核的编译配置放在.config文件中,内核arch目录中有提供不同架构的推荐.config供参考。也可以从当前内核的源usr/src/xxx目录中拷贝.config文件到当前目录。如果使用内核自带的参考.config。
可以使用命令:
make xconfig
会启动一个Qt的配置窗口,默认保存即可。
1.5.3. 编译
- 全部编译
# 编译内核镜像及其他所有模块,-j6指定6个线程进行编程,提升编译效果 sudo make -j6
- 单独编译
# 编译内核镜像 sudo make bzImage -j6 # 编译其他所有模块 sudo make modules -j6
1.5.4. 安装
安装其实就是将生成的ko库文件拷贝到指定目录lib\modules。
sudo make modules_install -j6
1.5.5. 安装启动文件
分别生成initrd文件,将镜像文件和map文件拷贝到boot目录。
sudo mkinitramfs /lib/modules/5.17.12 -o /boot/initrd.img-5.17.12
sudo cp arch/x86/boot/bzImage /boot/vmlinuz-5.17.12
sudo cp System.map /boot/System.map-5.17.12
1.5.6. 更新grub
更新grub文件,命令会自动检测boot目录中的initrd文件,将最新的initrd文件设置为默认启动版本。
sudo update-grub
1.6. 重启验证
重启电脑,在终端查看版本号
uname -r
5.17.12
1.7. 异常处理
- 提示相关库缺失,自行安装相关库依赖。
- 提示“make[1]: *** No rule to make target ‘debian/certs/benh@debian.org.cert.pem’, needed by ”,将下面的内存修改为空
CONFIG_SYSTEM_TRUSTED_KEYS=“debian/canonical-certs.pem”
CONFIG_SYSTEM_REVOCATION_KEYS=“debian/canonical-revoked-certs.pem”
新值
CONFIG_SYSTEM_TRUSTED_KEYS=“”
CONFIG_SYSTEM_REVOCATION_KEYS=“” - 提示“BTF: .tmp_vmlinux.btf: pahole (pahole) is not available”时,修改
CONFIG_DEBUG_INFO_BTF=y
为
CONFIG_DEBUG_INFO_BTF=n
1.8. 配置ccache
为了加速gcc编译内核,编译过的文件可以缓存起来,再次编译时就不用编译了。
1.8.1. 安装
sudo apt install ccache
1.8.2. 配置
sudo gedit ~/.bashrc
#在末尾回车,添加如下语句,注意ubuntu要改成你的用户名。
export CCACHE_DIR="/home/ubuntu/.ccache"
export CC="ccache gcc" export CXX="ccache g++"
export PATH="$PATH:/usr/lib/ccache"
#Ctrl+S或点击“保存”按钮保存,然后使其生效。
source ~/.bashrc
#20G是cache大小,可以自行指定
ccache -M 20G
2. 编译指定模块
整个内核是由一个初始化模块程序initrd.img,内核可执行程序vmlinuz和这么多动态库ko文件组成。Linux在启动时可以动态选择需要的库来进行加载,这样可以提升内核的启动效率。另外,将模块编译成动态库(ko文件),在进行自定义模块功能时,也可以只用编译单个模块的代码,也更便利。模块是否编译,是编译进内核镜像还是单独生成内核模块文件ko文件,这些都是在.config文件中配置的。
2.1. 配置文件介绍
2.1.1. .config文件
哪些模块编译进主内核模块,哪些模块单独作为动态库存在。这些都是通过一个配置文件.config来描述的。.config文件中有记录一些配置名,一些配置的大小,剩余的主要是描述是描述是否编译进内核文件,是否编译为单独的模块。如:
# m表示编译成单独的动态库ko文件
CONFIG_ACPI_SBS=m
# y表示编译进内核文件
CONFIG_ACPI_HED=y
# 如果没有配置则表示不编译或者配置为n
CONFIG_ACPI_HED=n
2.1.2. Kconfig文件
哪些字段可以配置,可以匹配什么样的值,默认配置的值是什么等,这些准备信息都是记录kconfig文件中。
Kconfig文件有基本的语法要求:
config TMPFS_POSIX_ACL
bool "Tmpfs POSIX Access Control Lists"
depends on TMPFS
select GENERIC_ACL
help
POSIX Access Control Lists (ACLs) support permissions for users and
groups beyond the owner/group/world scheme.
To learn more about Access Control Lists, visit the POSIX ACLs for
Linux website <http://acl.bestbits.at/>.
If you don't know what Access Control Lists are, say N.
config是关键字,指定后面的内容为.config文件中的可配置字段名,.config文件中实际使用时会加上CFONFIG_。
bool是描述此字段的类型。Kconfig支持的类型有:bool、tristate、string、hex和int。
● bool类型取值:y或n
● trisate类型取值:y,n或m(三态值,y表示安装进内核,n表示不安装,m表示以模块安装)
● string类型取值:字符串
● hex类型取值:十六进制数字
● int类型取值:十进制数字
bool后面的字符串表示提示信息,在配置界面中显示的。
depends on表示此模块依赖于TMPFS模块,只有TMPFS模块被选中时,此配置信息才可以设置。
select表示此模块被选中时,GENERIC_ACL也会被选中。
help下面的是帮助信息。
详细说明见:Documentation/kbuild/kconfig-language.rst
2.1.3. menuconfig
参考Kconfig文件来配置.config文件,可以完成Kernel的编译配置,但是此方法不够直观,效率不高。make menuconfig可以根据arch/目录下不同架构下的Kconfig和.config文件生成一个菜单窗口,更直观的配置有关信息。
Kconfig中的bool类型在menucofig中对应[],有[]表示选中,[]表示不选中。
Kconfig中的tristate类型在menuconfig中应对<>,<>表示选中编译进内核,表示以模块化编译,<>表示不编译。
配置完成之后,可以保存为.config文件。
2.1.4. xconfig
menuconfig是字符终端,依然不够直观,xconfig是基于xWindow的UI窗口终端,更清晰直观。 其功能和menuconfig一样的。
2.1.5. oldconfig
当.config有修改时,调用make oldconfig来验证相关修改是否匹配正确,会自动修改。
2.1.6. defcofig
内核源代码目录中的arch/下有不同架构cpu下的defconfig文件仅参考配置。
2.2. 配置指定模块
有些模块已经配置为编译为ko文件,有些模块没有配置。查看kconfig文件,找出该模块是否可以编译为模块,是否有依赖模块,有则选中,然后在.config中将指定模块配置为CONFIG_XX=m。
2.3. 完整编译
首次使用时,需要完整编译。
2.4. 单独编译
内核模块的makefile中有提供相关方法:
$(MAKE) -C ( K D I R ) M = (KDIR) M= (KDIR)M=(PWD) modules
KDIR为内核顶层目录。
PWD为指定编译模块的目录。
例如:
cd /home/michael/work/Kernel/linux-5.17.12
sudo make -C CONFIG_JBD2=m ./ M=fs/jbd2 modules
2.5. 拷贝
拷贝编译的模块到指定目录
sudo cp jbd2.ko /lib/modules/5.17.12/kernel/fs/jbd2
2.6. 更新驱动信息
sudo depmod-a
# 将变化的驱动信息更新到相关文件中.
2.7. 加载驱动
modprobe jbd2,动态加载驱动,如果jbd2有依赖驱动,会先加载依赖驱动再加载此驱动。
insmod jbd2,只加载此驱动,如果有依赖驱动会加载失败。
3. 制作deb安装文件
3.1. deb-pkg
上面的编译安装方便比较麻烦,如果想部署多台电脑时更不方便。如果能够制作安装包进行部署升级会更方便。
make deb-pkg
上面的命令即可以完成编译并生成deb安装文件存放在上级目录,有三个安装文件,分别为头文件,镜像文件以及libc开发文件,头文件和libc安装包都是用来进行应用程序开发的,可以不用安装。
linux-headers-5.17.12_5.17.12-1_amd64.deb
linux-image-5.17.12_5.17.12-1_amd64.deb
linux-libc-dev_5.17.12-1_amd64.deb
然后可以使用如下命令安装升级重启。
sudo dpkg -i *.deb
sudo update-grub
sudo reboot
3.2. make-kpkg
make-kpkg也是编译并生成deb安装文件,并且可以修改版本号等操作。
- 首先要安装make-kpkg
sudo apt install kernel-package
- 开始
sudo make-kpkg --initrd --append-to-version -20220228 --revision 001 kernel_image kernel_headers -j4
参数说明:
–initrd: 生成initramfs
–append-to-version:生成内核版本附加信息
–revision:deb文件的版本信息,只影响文件名
kernel_image:内核和模块的安装包
kernel_headers:生成内核头文件的安装包。
-j:指定多少个线程编译内核
3. 安装
sudo dpkg -i *.deb
sudo update-grub
sudo reboot