1、普通用户登录系统
查看当前内核版本
bash
$ uname -r
5.15.0-118-generic
2、下载内核源码
用户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. |
bash
$ cd linux-5.15.165
三种方法创建.config文件
(1)使用源码自带的defconfig文件。适合嵌入式系统。
bash
$ sudo make defconfig
(2)使用当前系统的config文件
bash
$ cp /boot/config-$(uname -r) ./.config
一些新内核新增加的配置需要手工配置。
(3)使用localmodconfig 获取精简的编译配置(本文使用)
发布版的内核包含很多内核模块,但是对某个特定机器,实际用到的模块只是其中的极小一部分。
重新构建内核时,对不使用的模块进行编译就会浪费时间。
将localmodconfig作为make的目标,kbuild系统会获取一个当前在用的模块的列表,
生成仅以正在使用的内核模块为对象的.config文件,减少编译时间。
localmodconfig 也是使用 /boot/config-$(uname -r) 作为基准的。
bash
$ lsmod > /tmp/mod
$ sudo make LSMOD=/tmp/mod localmodconfig
4、按需修改配置
bash
$ 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. |
bash
$ 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
6、安装构建的所有模块
几乎所有发行版都附带一个名为 installkernel 的脚本(/usr/sbin/installkernel),内核构建系统可以使用该脚本自动将构建的内核安装到正确的位置并修改引导加载程序,开发人员无需执行任何额外操作。提供 installkernel 的发行版通常会将其放在名为 mkinitrd 的包中,因此如果在机器上找不到该脚本,请尝试安装该包。
bash
$ 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)完成此操作后,内核安装成功,您可以安全地重新启动并试用新的内核映像。
请注意,此安装不会覆盖任何较旧的内核映像,因此,如果新内核映像出现问题,可以在引导时选择旧内核。
bash
$ 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
bash
$ sudo make install
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 be executed to detect other bootable partitions.
Its output will be used to detect bootable binaries on them and create new boot entries.
done
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
选择第二项,显示可选的启动内核项