1、普通用户登录系统
查看当前内核版本
$ uname -r
5.15.0-118-generic
2、下载主线内核源码
www.kernel.org
用户home目录新建子目录linux,下载并解压 linux-5.15.165.tar.xz
3、创建起始的配置文件.config
Configuration targets (见linux kernel in a nutshell)
config | Updates the current kernel configuration by using a line-oriented program. |
menuconfig | Updates the current kernel configuration by using a text-based menu program. |
xconfig | Updates the current kernel configuration by using a QT-based graphical program. |
gconfig | Updates the current kernel configuration by using a GTK+-based graphical program. |
oldconfig | Updates the current kernel configuration by using the current .config file and prompting for any new options that have been added to the kernel. |
silentoldconfig | Just like oldconfig, but prints nothing to the screen except when a question needs to be answered. |
randconfig | Generates a new kernel configuration with random answers to all of the different options. |
defconfig | Generates a new kernel configuration with the default answer being used for all options. The default values are taken from a file located in the arch/$ARCH/defconfig file, where $ARCH refers to the specific architecture for which the kernel is being built. |
allmodconfig | Generates a new kernel configuration in which modules are enabled whenever possible. |
allyesconfig | Generates a new kernel configuration with all options set to yes. |
allnoconfig | Generates a new kernel configuration with all options set to no. |
$ cd linux-5.15.165
四种方法创建.config文件
(1)最基本的方法,从头开始
$ sudo make config
内核配置程序逐项询问每一个配置选项,是否启用(Y/m/n/?)。
内核包含数千个配置选项,配置所有选项需要很长时间。
(2)使用源码“默认”的内核配置
$ sudo make defconfig
通常基于内核维护者认为的最好选项,也可能只是内核维护者个人计算机所使用的配置,为了确保新内核正常运行,应该根据自己的计算机进行定制。
(3)使用发行版提供的内核配置
$ cp /boot/config-$(uname -r) ./.config
新内核增加的配置项需要手工配置。
(4)从正在运行的内核中获得配置(本文使用)
发布版的内核包含很多内核模块,但是对某个特定机器,实际用到的模块只是其中的极小一部分。
重新构建内核时,对不使用的模块进行编译就会浪费时间。
将localmodconfig作为make的目标,kbuild系统会获取一个当前在用的模块列表,
生成仅以正在使用的内核模块为对象的.config文件,减少编译时间。
localmodconfig 也是使用 /boot/config-$(uname -r) 作为基准的。
$ lsmod > /tmp/mod
$ sudo make LSMOD=/tmp/mod localmodconfig
4、按需修改配置
$ sudo make menuconfig
按/输入配置项名称,可以省略CONFIG_前缀,回车搜索
按搜索结果旁的数字,可跳转至配置项,输入y、m、n更改配置
按Esc,直至返回到初始页
继续下一个配置项
选择Save,输入新文件名
5、构建内核
Build targets(见linux kernel in a nutshell)
all | Builds all of the different targets needed for this kernel to be able to be used. This includes both the modules and the static portion of the kernel. |
vmlinux | Builds just the static portion of the kernel, not any loadable modules. |
modules | Builds all of the loadable kernel modules for this configuration. |
modules_install | Installs all of the modules into the specified location. If no location is specified with the INSTALL_MODULE_PATH environment variable, they are installed in the default root directory of the machine. |
dir/ | Builds all of the files in the specified directory and in all subdirectories below it. |
dir/file.[o|i|s] | Builds only the specified file. |
dir/file.ko | Builds all of the needed files and links them together to form the specified module. |
tags | Builds all of the needed tags that most common text editors can use while editing the source code. |
$ sudo make
问题:
scripts/extract-cert.c:21:10: fatal error: openssl/bio.h: No such file or directory
解决:
sudo apt install libssl-dev
问题:
<stdin>:1:10: fatal error: libelf.h: No such file or directory
解决:
sudo apt install libelf-dev
问题:
make[1]: *** No rule to make target 'debian/canonical-certs.pem', needed by 'certs/x509_certificate_list'. Stop.
解决:
vi .config
CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem" 改为""
CONFIG_SYSTEM_REVOCATION_KEYS="debian/canonical-revoked-certs.pem" 改为""
问题:
net/core/rtnetlink.c:3528:1: warning: the frame size of 1112 bytes is larger than 1024 bytes [-Wframe-larger-than=]
解决:
vi .config
CONFIG_FRAME_WARN=1024 改为 4096
问题:
arch/x86/kernel/head_64.o: warning: objtool: .text+0x5: unreachable instruction
arch/x86/kernel/smp.o: warning: objtool: sysvec_reboot()+0x54: unreachable instruction
arch/x86/kernel/smp.o: warning: objtool: sysvec_reboot()+0x4c: unreachable instruction
解决:TODO
问题:
FAILED: load BTF from vmlinux: Invalid argument
解决:
https://devkernel.io/posts/pahole-error/
There are three ways to address the problem.
1. Disable the configuration setting
By disabling the CONFIG_DEBUG_INFO_BTF configuration option, the kernel will build successfully.
However this has a downside, as BPF programs cannot be run.
2. Downgrade the pahole package
The pahole program is part of the pahole package.
If your Linux distribution still provides an earlier version, it is the easiest to downgrade to the previous version.
3. Patch pahole-flags.sh
The new pahole provides the --skip_encoding_btf_enum64 option to skip BTF_KIND_ENUM64 generation.
By specifying this option, a stable kernel will be created.
Applying the following patch to scripts/pahole-flags.sh will achieve enabling the new flag.
if [ "${pahole_ver}" -ge "124" ]; then
extra_paholeopt="${extra_paholeopt} --skip_encoding_btf_enum64"
fi
6、安装构建的所有模块
$ sudo make modules_install
INSTALL /lib/modules/5.15.165/kernel/drivers/net/dummy.ko
INSTALL /lib/modules/5.15.165/kernel/drivers/net/vxlan/vxlan.ko
INSTALL /lib/modules/5.15.165/kernel/drivers/thermal/intel/x86_pkg_temp_thermal.ko
INSTALL /lib/modules/5.15.165/kernel/fs/efivarfs/efivarfs.ko
INSTALL /lib/modules/5.15.165/kernel/net/ipv4/netfilter/iptable_nat.ko
INSTALL /lib/modules/5.15.165/kernel/net/ipv4/udp_tunnel.ko
INSTALL /lib/modules/5.15.165/kernel/net/ipv6/ip6_udp_tunnel.ko
INSTALL /lib/modules/5.15.165/kernel/net/netfilter/nf_log_syslog.ko
INSTALL /lib/modules/5.15.165/kernel/net/netfilter/xt_LOG.ko
INSTALL /lib/modules/5.15.165/kernel/net/netfilter/xt_MASQUERADE.ko
INSTALL /lib/modules/5.15.165/kernel/net/netfilter/xt_addrtype.ko
INSTALL /lib/modules/5.15.165/kernel/net/netfilter/xt_mark.ko
INSTALL /lib/modules/5.15.165/kernel/net/netfilter/xt_nat.ko
INSTALL /lib/modules/5.15.165/kernel/net/sched/act_bpf.ko
INSTALL /lib/modules/5.15.165/kernel/net/sched/act_gact.ko
INSTALL /lib/modules/5.15.165/kernel/net/sched/act_police.ko
INSTALL /lib/modules/5.15.165/kernel/net/sched/cls_bpf.ko
INSTALL /lib/modules/5.15.165/kernel/net/sched/sch_sfq.ko
DEPMOD /lib/modules/5.15.165
将模块放在文件系统中的适当位置,以便新内核正确找到。
模块位于 /lib/modules/kernel_version 目录中,其中 kernel_version 是刚构建的新内核的版本。
7、安装内核
将启动以下过程:
(1)内核构建系统将验证内核是否构建成功。
(2)构建系统会将 static kernel 部分安装到 /boot 目录下,并根据构建内核的内核版本命名这个可执行文件。
(3)将使用刚刚在 modules_install 阶段安装的模块自动创建任何所需的初始 ramdisk 映像。
(4)bootloader程序将被正确通知存在新内核,并将其添加到相应的菜单中,以便用户可以在下次引导机器时选择它。
(5)完成此操作后,内核安装成功,您可以安全地重新启动并试用新的内核映像。
请注意,此安装不会覆盖任何较旧的内核映像,因此,如果新内核映像出现问题,可以在引导时选择旧内核。
几乎所有发行版都附带一个名为 installkernel 的脚本(/usr/sbin/installkernel),内核构建系统可以使用该脚本自动将构建的内核安装到正确的位置并修改引导加载程序,开发人员无需执行任何额外操作。提供 installkernel 的发行版通常会将其放在名为 mkinitrd 的包中,因此如果在机器上找不到该脚本,请尝试安装该包。
$ sudo make install
arch/x86/Makefile:142: CONFIG_X86_X32 enabled but no binutils support
sh ./arch/x86/boot/install.sh 5.15.165 \
arch/x86/boot/bzImage System.map "/boot"
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 5.15.165 /boot/vmlinuz-5.15.165
update-initramfs: Generating /boot/initrd.img-5.15.165
run-parts: executing /etc/kernel/postinst.d/unattended-upgrades 5.15.165 /boot/vmlinuz-5.15.165
run-parts: executing /etc/kernel/postinst.d/update-notifier 5.15.165 /boot/vmlinuz-5.15.165
run-parts: executing /etc/kernel/postinst.d/xx-update-initrd-links 5.15.165 /boot/vmlinuz-5.15.165
run-parts: executing /etc/kernel/postinst.d/zz-update-grub 5.15.165 /boot/vmlinuz-5.15.165
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.15.165
Found initrd image: /boot/initrd.img-5.15.165
Found linux image: /boot/vmlinuz-5.15.165.old
Found initrd image: /boot/initrd.img-5.15.165
Found linux image: /boot/vmlinuz-5.15.0-118-generic
Found initrd image: /boot/initrd.img-5.15.0-118-generic
Warning: os-prober will not be executed to detect other bootable partitions.
Systems on them will not be added to the GRUB boot configuration.
Check GRUB_DISABLE_OS_PROBER documentation entry.
done
问题:
arch/x86/Makefile:142: CONFIG_X86_X32 enabled but no binutils support
解决:
安装binutils 或者 找到arch/x86/Makefile的142行,注释掉CONFIG_X86_X32相关配置。
问题:
Warning: os-prober will not be executed to detect other bootable partitions.
解决:
vi /etc/default/grub
添加 GRUB_DISABLE_OS_PROBER=false
sudo update-grub
8、重启系统
# reboot
查看当前内核版本
# uname -r
5.15.165
9、实现开机进入grub引导菜单,选择可用内核启动
# vi /etc/default/grub
注释 GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT 改为 30
GRUB_CMDLINE_LINUX_DEFAULT 改为 text
# update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.15.165
Found initrd image: /boot/initrd.img-5.15.165
Found linux image: /boot/vmlinuz-5.15.165.old
Found initrd image: /boot/initrd.img-5.15.165
Found linux image: /boot/vmlinuz-5.15.0-118-generic
Found initrd image: /boot/initrd.img-5.15.0-118-generic
Warning: os-prober will be executed to detect other bootable partitions.
Its output will be used to detect bootable binaries on them and create new boot entries.
done
# reboot
选择第二项,显示可选的启动内核项
10、从源码目录导出内核头文件
$ sudo make headers_install INSTALL_HDR_PATH=/usr/src/linux-headers-$(make kernelrelease)
$ ll /usr/src/linux-headers-5.15.165/
total 12
drwxr-xr-x 3 root root 4096 Sep 22 05:32 ./
drwxr-xr-x 5 root root 4096 Sep 22 05:33 ../
drwxr-xr-x 13 root root 4096 Sep 22 05:32 include/
与内核升级前系统自带的头文件目录相比,少了很多子目录
$ ll /usr/src/linux-headers-5.15.0-118
total 184
drwxr-xr-x 25 root root 4096 Aug 20 08:12 ./
drwxr-xr-x 5 root root 4096 Sep 22 05:33 ../
drwxr-xr-x 25 root root 4096 Aug 20 08:12 arch/
drwxr-xr-x 3 root root 4096 Aug 20 08:12 block/
drwxr-xr-x 2 root root 4096 Aug 20 08:12 certs/
drwxr-xr-x 4 root root 4096 Aug 20 08:12 crypto/
drwxr-xr-x 12 root root 4096 Aug 20 08:12 Documentation/
drwxr-xr-x 138 root root 4096 Aug 20 08:12 drivers/
drwxr-xr-x 84 root root 4096 Aug 20 08:12 fs/
drwxr-xr-x 29 root root 4096 Aug 20 08:12 include/
drwxr-xr-x 2 root root 4096 Aug 20 08:12 init/
drwxr-xr-x 2 root root 4096 Aug 20 08:12 io_uring/
drwxr-xr-x 2 root root 4096 Aug 20 08:12 ipc/
-rw-r--r-- 1 root root 1327 Oct 31 2021 Kbuild
-rw-r--r-- 1 root root 580 Jul 5 08:53 Kconfig
drwxr-xr-x 20 root root 4096 Aug 20 08:12 kernel/
drwxr-xr-x 21 root root 4096 Aug 20 08:12 lib/
-rw-r--r-- 1 root root 67259 Jul 5 08:53 Makefile
drwxr-xr-x 5 root root 4096 Aug 20 08:12 mm/
drwxr-xr-x 71 root root 4096 Aug 20 08:12 net/
drwxr-xr-x 34 root root 4096 Aug 20 08:12 samples/
drwxr-xr-x 17 root root 12288 Aug 20 08:12 scripts/
drwxr-xr-x 14 root root 4096 Aug 20 08:12 security/
drwxr-xr-x 27 root root 4096 Aug 20 08:12 sound/
drwxr-xr-x 36 root root 4096 Aug 20 08:12 tools/
drwxr-xr-x 4 root root 4096 Aug 20 08:12 ubuntu/
drwxr-xr-x 3 root root 4096 Aug 20 08:12 usr/
drwxr-xr-x 4 root root 4096 Aug 20 08:12 virt/
可能需要手工复制一些额外的目录和文件。
PS:
如果 apt search能够查到相应版本的头文件安装包,则使用apt install安装,这样安装得到的目录是完整的。
$ apt search linux-headers | grep headers-5.15
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
linux-headers-5.15.0-100/jammy-updates,jammy-security 5.15.0-100.110 all
linux-headers-5.15.0-100-generic/jammy-updates,jammy-security 5.15.0-100.110 amd64
linux-headers-5.15.0-100-lowlatency/jammy-updates,jammy-security 5.15.0-100.110 amd64
linux-headers-5.15.0-1002-gke/jammy 5.15.0-1002.2 amd64
linux-headers-5.15.0-1002-ibm/jammy 5.15.0-1002.2 amd64
......
$ sudo apt install linux-headers-5.15.0-100
$ ll /usr/src
total 20
drwxr-xr-x 5 root root 4096 Sep 22 06:40 ./
drwxr-xr-x 14 root root 4096 Aug 9 2022 ../
drwxr-xr-x 25 root root 4096 Aug 20 08:12 linux-headers-5.15.0-118/
drwxr-xr-x 7 root root 4096 Aug 20 08:12 linux-headers-5.15.0-118-generic/
drwxr-xr-x 3 root root 4096 Sep 22 05:32 linux-headers-5.15.165/
drwxr-xr-x 25 root root 4096 Aug 22 05:52 linux-headers-5.15.0-100/