编译linux内核源码(适用Fedora/RHEL/CentOS/Oracle Linux /Debian/Ubuntu/Arch Linux/Manjaro)
本文介绍如何编译linux源码,然后以编译后的新内核启动linux系统。
目录
本文介绍如何编译linux源码,然后以编译后的新内核启动linux系统,可能在比较老的系统版本上编译会有问题。
一、获取内核源码
官网拉取所要编译的指定版本linux代码
或者从git上git clone源码:
# git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
国内git clone会比较慢,可以自行加梯子或者gitee上下载,下载到源码后,解压待使用。
tar.xz格式的使用unxz或者xz -d或者tar -zxf来解压;
zip包用unzip解压;
tar tar.gz用tar xf解压。
二、安装编译内核依赖的工具
主要是开发套件相关工具及组件,比如gcc或者clang及相关软件包。
1、Debian/Ubuntu
# apt-get install build-essential libncurses-dev bison flex libssl-dev libelf-dev
2、Fedora/RHEL/CentOS/Oracle Linux
# yum group install "Development Tools"
# yum install ncurses-devel bison flex elfutils-libelf-devel openssl-devel
3、Fedora
# dnf group install "Development Tools"
# dnf install ncurses-devel bison flex elfutils-libelf-devel openssl-devel
4、Arch linux/Manjaro
安装完系统要再次更新下:
# pacman -Syyu
# pacman -S gcc bc libelf flex bison make cmake
或者LLVM/clang工具链安装:
# pacman -S clang llvm lld bc flex bison make cmake unzip
注:下面执行命令都要在要编译的内核源码根目录下进行
三、配置内核相关参数项
1、首先,可以复用本机的config文件:
# cp -v /boot/config-$(uname -r) /new_kernel_src_path/.config
或者
# zcat /proc/config.gz > /new_kernel_src_path/.config
注意:这里是把本机config配置拷贝到我们前面解压出来的内核源码根目录下。
2、配置内核参数
基于文本的菜单配置,适用性强,也可用于远程编译内核
# make menuconfig
当然如果系统带有桌面,可以选择如下的图形界面菜单配置内核:
①如果系统是基于KDE桌面或者最新的QT库,可以使用:
# make xconfig
②如果系统基于gtk的库,如Gnome或者xfce桌面,可以使用:
# make gconfig
当然,你可以执行make allyesconfig或者make allnoconfig简单的将内核所有可配置的配置都启用或者禁用。
3、如果之前编译过内核源码,由于出错或者其它原因想重新编译,则需要先清理下之前的编译结果,执行:
# make mrproper
注:如果下面使用LLVM/clang工具构建内核的话,会报错如下:
BTF: .tmp_vmlinux.btf: pahole (pahole) is not available
Failed to generate BTF for vmlinux
Try to disable CONFIG_DEBUG_INFO_BTF
make: *** [Makefile:1170: vmlinux] Error 1
解决方案:
①、安装包含pahole的软件包
②、禁用掉CONFIG_DEBUG_INFO_BTF功能,可以在make menuconfig菜单中找到,,然后按空格键取消掉:
Main menu
-> Kernel hacking
->Compile-time checks and compiler options
-> Compile the kernel with debug info(DEBUG_INFO [=y])
四、编译内核源码
执行make命令即可,但是内核源码庞大,编译下来很费时间(跟机器性能有关,一般需要数十分钟到几个小时),可以make加上-jn选项多线程编译内核来加速内核编译,如:
# j后面数字,可以设置成cpu个数
# make -j4
如果使用LLVM/clang工具链编译,则可以:
# make LLVM=1 -j4
或者
# make CC=clang LD=ld.bfd -j4
注:此时可以干的别的,这个过程比较慢,普通机器一般会在小时级别。
五、安装新内核及其内核模块
1、通常情况下,编译没报错的话,此时可以安装新内核了,但是我们还是检查下arch/x86/boot/bzImage文件是否已经生成:
# ls arch/x86/boot/bzImage -lh
如果没生成,此时还需要执行:
# make bzImage
生成内核压缩镜像文件,此文件不生成的话,在后面make install的时候会报错:
[root@fedora linux-rust]# make install
sh ./arch/x86/boot/install.sh 5.16.0-rc3 \
arch/x86/boot/bzImage System.map "/boot"
*** Missing file: arch/x86/boot/bzImage
*** You need to run "make" before "make install".
make: *** [arch/x86/Makefile:262:install] 错误 1
[root@fedora linux-rust]#
2、安装内核新生成的内核模块(驱动)
# make modules_install
3、安装生成新内核,这里可以有多种方法
①、执行make install命令,安装内核及其内核模块,这个命令会帮我们把新生成的内核相关文件拷贝到/boot下:
# make install
②、手动复制内核相关文件到/boot/目录下,主要是bzImage文件、system map文件
# cp arch/x86/boot/bzImage /boot/new_bzImage_name
# cp System.map /boot/new_system_map_name
执行没报错的话,会在/boot/下生成新内核镜像vmlinuz、initramfs及systemmap文件:
注:此阶段可能出现的报错问题:
①、如下报错:
AS arch/x86/boot/compressed/efi_thunk_64.o
OBJCOPY arch/x86/boot/compressed/vmlinux.bin
RELOCS arch/x86/boot/compressed/vmlinux.relocs
ZSTD22 arch/x86/boot/compressed/vmlinux.bin.zst
/bin/sh:行1: zstd:未找到命令
make[2]: *** [arch/x86/boot/compressed/Makefile:136:arch/x86/boot/compressed/vmlinux.bin.zst] 错误 127
make[2]: *** 正在删除文件“arch/x86/boot/compressed/vmlinux.bin.zst”
make[1]: *** [arch/x86/boot/Makefile:115:arch/x86/boot/compressed/vmlinux] 错误 2
make: *** [arch/x86/Makefile:252:bzImage] 错误 2
此时,只需安装zstd,然后重新执行make install即可:
[root@fedora linux-rust]# dnf install zstd
上次元数据过期检查:1:57:52 前,执行于 2021年12月07日 星期二 08时44分53秒。
依赖关系解决。
======================================================================================================================================================
软件包 架构 版本 仓库 大小
======================================================================================================================================================
安装:
zstd x86_64 1.5.0-2.fc35 fedora 639 k
事务概要
======================================================================================================================================================
安装 1 软件包
总下载:639 k
安装大小:1.9 M
确定吗?[y/N]: y
下载软件包:
zstd-1.5.0-2.fc35.x86_64.rpm 1.0 MB/s | 639 kB 00:00
------------------------------------------------------------------------------------------------------------------------------------------------------
总计 409 kB/s | 639 kB 00:01
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
准备中 : 1/1
安装 : zstd-1.5.0-2.fc35.x86_64 1/1
运行脚本: zstd-1.5.0-2.fc35.x86_64 1/1
验证 : zstd-1.5.0-2.fc35.x86_64 1/1
已安装:
zstd-1.5.0-2.fc35.x86_64
完毕!
[root@fedora linux-rust]#
[root@fedora linux-rust]# make install
sh ./arch/x86/boot/install.sh 5.16.0-rc3 \
arch/x86/boot/bzImage System.map "/boot"
[root@fedora linux-rust]#
②、如下报错:
CALL scripts/atomic/check-atomics.sh
RUSTC L rust/core.o
make[1]: *** [rust/Makefile:349:rust/core.o] 错误 137
make: *** [Makefile:1267:prepare0] 错误 2
make[1]: *** [rust/Makefile:349:rust/core.o] 错误 137,这个错误一般是没有交换区导致的编译失败,可以手动添加交换区:
[yg-vm ~]# free -h
total used free shared buff/cache available
内存: 1.9Gi 1.1Gi 529Mi 153Mi 301Mi 529Mi
交换: 0B 0B 0B
[yg-vm ~]#
[yg-vm ~]# dd if=/dev/zero of=/swapfile bs=1k count=2048000
记录了2048000+0 的读入
记录了2048000+0 的写出
2097152000字节(2.1 GB,2.0 GiB)已复制,7.39818 s,283 MB/s
[yg-vm ~]#
[yg-vm ~]# mkswap /swapfile
mkswap: /swapfile: insecure permissions 0644, fix with: chmod 0600 /swapfile
正在设置交换空间版本 1,大小 = 2 GiB (2097147904 个字节)
无标签,UUID=e9f4e3a3-4d8d-49af-9307-8f880b6d4d20
[yg-vm ~]#
[yg-vm ~]#
[yg-vm ~]#
[yg-vm ~]# swapon /swapfile
swapon: /swapfile:不安全的权限 0644,建议使用 0600。
[yg-vm ~]# free -h
total used free shared buff/cache available
内存: 1.9Gi 1.1Gi 65Mi 153Mi 763Mi 520Mi
交换: 2.0Gi 0B 2.0Gi
[yg-vm ~]#
然后再执行make install即可。
③、我在manjaro linux上编译内核时,出现下面报错:
[yg-vm linux-rust]# make install
sh ./arch/x86/boot/install.sh 5.16.0-rc3-MANJARO \
arch/x86/boot/bzImage System.map "/boot"
Cannot find LILO.
[yg-vm linux-rust]#
Cannot find LILO.于是我打开vim ./arch/x86/boot/install.sh脚本,看到这个报错是在脚本的最后出现,其实此时内核已经编译安装完成了,可以看下/boot下已经生成了新内核相关文件,所以此报错可以忽略。
六、生成initramfs文件系统
对于Fedora及其衍生系统RHEL/CentOS/Oracle Linux、Debian/Ubuntu,在上面make阶段,initramfs都会自动生成。
针对Manjaro/Arch linux系统,编译安装完内核后,还需要手动生成initramfs文件系统
可以使用mkinitcpio工具来生成:
①、将前面编译安装新生成vmlinuz重命名为带版本号的容易标识的名称
[yg-vm linux-rust]# ls -tlh /boot/
总用量 124M
-rw-r--r-- 1 root root 5.7M 12月 4 18:16 System.map
-rw-r--r-- 1 root root 8.6M 12月 4 18:16 vmlinuz
-rw-r--r-- 1 root root 5.7M 12月 4 14:40 System.old
-rw-r--r-- 1 root root 8.6M 12月 4 14:40 vmlinuz.old
drwxr-xr-x 6 root root 4.0K 12月 4 02:00 grub
-rw-r--r-- 1 root root 29M 12月 4 02:00 initramfs-5.10-x86_64-fallback.img
-rw-r--r-- 1 root root 7.9M 12月 4 02:00 initramfs-5.10-x86_64.img
-rw-r--r-- 1 root root 9.1M 12月 4 02:00 vmlinuz-5.10-x86_64
-rw-r--r-- 1 root root 30M 12月 4 01:22 initramfs-5.4-x86_64-fallback.img
-rw-r--r-- 1 root root 8.4M 12月 4 01:22 initramfs-5.4-x86_64.img
-rw-r--r-- 1 root root 7.1M 12月 4 01:22 vmlinuz-5.4-x86_64
-rw-r--r-- 1 root root 22 11月 13 04:24 linux510-x86_64.kver
-rw-r--r-- 1 root root 22 11月 13 04:24 linux54-x86_64.kver
drwxr-xr-x 2 root root 4.0K 10月 18 01:01 memtest86+
-rw-r--r-- 1 root root 4.6M 6月 9 02:31 intel-ucode.img
[yg-vm linux-rust]# mv /boot/vmlinuz /boot/vmlinuz-5.16.0-rc3-x86_64
[yg-vm linux-rust]#
②、参考本机的preset文件,创建一个新内核的preset文件。
[yg-vm linux-rust]# cd /etc/mkinitcpio.d/
[yg-vm mkinitcpio.d]# ls
linux510.preset linux54.preset
[yg-vm mkinitcpio.d]# cat linux510.preset
# mkinitcpio preset file for the 'linux510' package
ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-5.10-x86_64"
PRESETS=('default' 'fallback')
#default_config="/etc/mkinitcpio.conf"
default_image="/boot/initramfs-5.10-x86_64.img"
#default_options=""
#fallback_config="/etc/mkinitcpio.conf"
fallback_image="/boot/initramfs-5.10-x86_64-fallback.img"
fallback_options="-S autodetect"
[yg-vm mkinitcpio.d]#
[yg-vm mkinitcpio.d]#
[yg-vm mkinitcpio.d]# cp linux510.preset linux516.preset
然后将新拷贝的linux516.preset文件里,vmlinuz-5.10-x86_64、initramfs-5.10-x86_64.img、initramfs-5.10-x86_64-fallback.img改为新版本内核的相关文件名,我这里是把5.10-x86_64都改成5.16.0-rc3-x86_64即可,之后执行:
[yg-vm mkinitcpio.d]# mkinitcpio -p linux516.preset
/usr/bin/mkinitcpio:行268: /etc/mkinitcpio.d/linux516.preset.preset: 没有那个文件或目录
==> ERROR: Failed to load preset: `/etc/mkinitcpio.d/linux516.preset.preset'
[yg-vm mkinitcpio.d]#
此时报错说找不到linux516.preset.preset,可见mkinitcpio命令,自动将-p后的文件加了preset后缀了,此时只需把linux516.preset的后缀去掉即可:
[yg-vm mkinitcpio.d]# cp linux516.preset linux516
然后重新mkinitcpio即可:
[yg-vm mkinitcpio.d]# mkinitcpio -p linux516
==> Building image from preset: /etc/mkinitcpio.d/linux516.preset: 'default'
-> -k /boot/vmlinuz-5.16.0-rc3-x86_64 -c /etc/mkinitcpio.conf -g /boot/initramfs-5.16.0-rc3-x86_64.img
==> Starting build: 5.16.0-rc3-MANJARO
-> Running build hook: [base]
-> Running build hook: [udev]
-> Running build hook: [autodetect]
-> Running build hook: [modconf]
-> Running build hook: [block]
-> Running build hook: [keyboard]
-> Running build hook: [keymap]
loadkeys: Unable to open file: cn: No such file or directory
-> Running build hook: [consolefont]
==> WARNING: consolefont: no font found in configuration
-> Running build hook: [filesystems]
-> Running build hook: [fsck]
==> Generating module dependencies
==> Creating gzip-compressed initcpio image: /boot/initramfs-5.16.0-rc3-x86_64.img
==> Image generation successful
==> Building image from preset: /etc/mkinitcpio.d/linux516.preset: 'fallback'
-> -k /boot/vmlinuz-5.16.0-rc3-x86_64 -c /etc/mkinitcpio.conf -g /boot/initramfs-5.16.0-rc3-x86_64-fallback.img -S autodetect
==> Starting build: 5.16.0-rc3-MANJARO
-> Running build hook: [base]
-> Running build hook: [udev]
-> Running build hook: [modconf]
-> Running build hook: [block]
==> WARNING: Possibly missing firmware for module: xhci_pci
-> Running build hook: [keyboard]
-> Running build hook: [keymap]
loadkeys: Unable to open file: cn: No such file or directory
-> Running build hook: [consolefont]
==> WARNING: consolefont: no font found in configuration
-> Running build hook: [filesystems]
-> Running build hook: [fsck]
==> Generating module dependencies
==> Creating gzip-compressed initcpio image: /boot/initramfs-5.16.0-rc3-x86_64-fallback.img
==> Image generation successful
[yg-vm mkinitcpio.d]#
此时大功告成。
七、更新grub配置
一般上面编译完成后,在新版本的linux发行版中,都会自动将最新编译的高版本内核加入到启动项里的,不放心的话,还是手动修改下grub2 boot loader启动配置:
1、Fedora/RHEL/CentOS/Oracle Linux
# grub2-mkconfig -o /boot/grub2/grub.cfg
# grubby --set-default /boot/vmlinuz-5.6.9
修改后可以查看下是否修改成功:
# grubby --default-kernel
# grubby --default-index
# grubby --info=ALL
2、Debian/Ubuntu linux
# update-initramfs -c -k new_kernel
# update-grub
3、Arch Linux/Manjaro
[yg-vm mkinitcpio.d]# update-grub
正在生成 grub 配置文件 ...
找到主题:/usr/share/grub/themes/manjaro/theme.txt
找到 Linux 镜像:/boot/vmlinuz-5.16.0-rc3-x86_64
找到 initrd 镜像:/boot/intel-ucode.img /boot/initramfs-5.16.0-rc3-x86_64.img
Found initrd fallback image: /boot/initramfs-5.16.0-rc3-x86_64-fallback.img
找到 Linux 镜像:/boot/vmlinuz-5.10-x86_64
找到 initrd 镜像:/boot/intel-ucode.img /boot/initramfs-5.10-x86_64.img
Found initrd fallback image: /boot/initramfs-5.10-x86_64-fallback.img
找到 Linux 镜像:/boot/vmlinuz-5.4-x86_64
找到 initrd 镜像:/boot/intel-ucode.img /boot/initramfs-5.4-x86_64.img
Found initrd fallback image: /boot/initramfs-5.4-x86_64-fallback.img
警告: 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.
Found memtest86+ image: /boot/memtest86+/memtest.bin
完成
[yg-vm mkinitcpio.d]#
八、重启系统生效
执行如下命令,重启系统:
# reboot
或者
# init 6
重启系统时,如果能看到开机界面,此时在内核启动项那里已经可以看到新编译的内核了。
启动后,使用命令查看当前内核版本:
# uname -a
参考链接:How to build and install your own Linux kernel - LQWiki
更多推荐
所有评论(0)