当前位置:   article > 正文

编译linux内核源码(适用Fedora/RHEL/CentOS/Oracle Linux /Debian/Ubuntu/Arch Linux/Manjaro)_linux内核源码编译

linux内核源码编译

目录

一、获取内核源码

二、安装编译内核依赖的工具

三、配置内核相关参数项

四、编译内核源码

五、安装新内核及其内核模块

六、生成initramfs文件系统

七、更新grub配置

八、重启系统生效


本文介绍如何编译linux源码,然后以编译后的新内核启动linux系统,可能在比较老的系统版本上编译会有问题。

一、获取内核源码

官网拉取所要编译的指定版本linux代码

官网:The Linux Kernel Archives

 或者从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

  1. # yum group install "Development Tools"
  2. # yum install ncurses-devel bison flex elfutils-libelf-devel openssl-devel

3、Fedora

  1. # dnf group install "Development Tools"
  2. # 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工具构建内核的话,会报错如下:

  1. BTF: .tmp_vmlinux.btf: pahole (pahole) is not available
  2. Failed to generate BTF for vmlinux
  3. Try to disable CONFIG_DEBUG_INFO_BTF
  4. 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选项多线程编译内核来加速内核编译,如:

  1. # j后面数字,可以设置成cpu个数
  2. # make -j4

如果使用LLVM/clang工具链编译,则可以:

  1. # make LLVM=1 -j4
  2. 或者
  3. # make CC=clang LD=ld.bfd -j4

注:此时可以干的别的,这个过程比较慢,普通机器一般会在小时级别。

五、安装新内核及其内核模块

1、通常情况下,编译没报错的话,此时可以安装新内核了,但是我们还是检查下arch/x86/boot/bzImage文件是否已经生成:

# ls arch/x86/boot/bzImage -lh

如果没生成,此时还需要执行:

# make bzImage

生成内核压缩镜像文件,此文件不生成的话,在后面make install的时候会报错:

  1. [root@fedora linux-rust]# make install
  2. sh ./arch/x86/boot/install.sh 5.16.0-rc3 \
  3. arch/x86/boot/bzImage System.map "/boot"
  4. *** Missing file: arch/x86/boot/bzImage
  5. *** You need to run "make" before "make install".
  6. make: *** [arch/x86/Makefile:262:install] 错误 1
  7. [root@fedora linux-rust]#

2、安装内核新生成的内核模块(驱动)

# make modules_install

3、安装生成新内核,这里可以有多种方法

 ①、执行make install命令,安装内核及其内核模块,这个命令会帮我们把新生成的内核相关文件拷贝到/boot下:

# make install

②、手动复制内核相关文件到/boot/目录下,主要是bzImage文件、system map文件

  1. # cp arch/x86/boot/bzImage /boot/new_bzImage_name
  2. # cp System.map /boot/new_system_map_name

执行没报错的话,会在/boot/下生成新内核镜像vmlinuz、initramfs及systemmap文件:

注:此阶段可能出现的报错问题:

①、如下报错:

  1. AS arch/x86/boot/compressed/efi_thunk_64.o
  2. OBJCOPY arch/x86/boot/compressed/vmlinux.bin
  3. RELOCS arch/x86/boot/compressed/vmlinux.relocs
  4. ZSTD22 arch/x86/boot/compressed/vmlinux.bin.zst
  5. /bin/sh:行1: zstd:未找到命令
  6. make[2]: *** [arch/x86/boot/compressed/Makefile:136:arch/x86/boot/compressed/vmlinux.bin.zst] 错误 127
  7. make[2]: *** 正在删除文件“arch/x86/boot/compressed/vmlinux.bin.zst”
  8. make[1]: *** [arch/x86/boot/Makefile:115:arch/x86/boot/compressed/vmlinux] 错误 2
  9. make: *** [arch/x86/Makefile:252:bzImage] 错误 2

此时,只需安装zstd,然后重新执行make install即可:

  1. [root@fedora linux-rust]# dnf install zstd
  2. 上次元数据过期检查:1:57:52 前,执行于 20211207日 星期二 084453秒。
  3. 依赖关系解决。
  4. ======================================================================================================================================================
  5. 软件包 架构 版本 仓库 大小
  6. ======================================================================================================================================================
  7. 安装:
  8. zstd x86_64 1.5.0-2.fc35 fedora 639 k
  9. 事务概要
  10. ======================================================================================================================================================
  11. 安装 1 软件包
  12. 总下载:639 k
  13. 安装大小:1.9 M
  14. 确定吗?[y/N]: y
  15. 下载软件包:
  16. zstd-1.5.0-2.fc35.x86_64.rpm 1.0 MB/s | 639 kB 00:00
  17. ------------------------------------------------------------------------------------------------------------------------------------------------------
  18. 总计 409 kB/s | 639 kB 00:01
  19. 运行事务检查
  20. 事务检查成功。
  21. 运行事务测试
  22. 事务测试成功。
  23. 运行事务
  24. 准备中 : 1/1
  25. 安装 : zstd-1.5.0-2.fc35.x86_64 1/1
  26. 运行脚本: zstd-1.5.0-2.fc35.x86_64 1/1
  27. 验证 : zstd-1.5.0-2.fc35.x86_64 1/1
  28. 已安装:
  29. zstd-1.5.0-2.fc35.x86_64
  30. 完毕!
  31. [root@fedora linux-rust]#
  32. [root@fedora linux-rust]# make install
  33. sh ./arch/x86/boot/install.sh 5.16.0-rc3 \
  34. arch/x86/boot/bzImage System.map "/boot"
  35. [root@fedora linux-rust]#

②、如下报错:

  1. CALL scripts/atomic/check-atomics.sh
  2. RUSTC L rust/core.o
  3. make[1]: *** [rust/Makefile:349:rust/core.o] 错误 137
  4. make: *** [Makefile:1267:prepare0] 错误 2

make[1]: *** [rust/Makefile:349:rust/core.o] 错误 137,这个错误一般是没有交换区导致的编译失败,可以手动添加交换区:

  1. [yg-vm ~]# free -h
  2. total used free shared buff/cache available
  3. 内存: 1.9Gi 1.1Gi 529Mi 153Mi 301Mi 529Mi
  4. 交换: 0B 0B 0B
  5. [yg-vm ~]#
  6. [yg-vm ~]# dd if=/dev/zero of=/swapfile bs=1k count=2048000
  7. 记录了2048000+0 的读入
  8. 记录了2048000+0 的写出
  9. 2097152000字节(2.1 GB,2.0 GiB)已复制,7.39818 s,283 MB/s
  10. [yg-vm ~]#
  11. [yg-vm ~]# mkswap /swapfile
  12. mkswap: /swapfile: insecure permissions 0644, fix with: chmod 0600 /swapfile
  13. 正在设置交换空间版本 1,大小 = 2 GiB (2097147904 个字节)
  14. 无标签,UUID=e9f4e3a3-4d8d-49af-9307-8f880b6d4d20
  15. [yg-vm ~]#
  16. [yg-vm ~]#
  17. [yg-vm ~]#
  18. [yg-vm ~]# swapon /swapfile
  19. swapon: /swapfile:不安全的权限 0644,建议使用 0600
  20. [yg-vm ~]# free -h
  21. total used free shared buff/cache available
  22. 内存: 1.9Gi 1.1Gi 65Mi 153Mi 763Mi 520Mi
  23. 交换: 2.0Gi 0B 2.0Gi
  24. [yg-vm ~]#

然后再执行make install即可。

③、我在manjaro linux上编译内核时,出现下面报错:

  1. [yg-vm linux-rust]# make install
  2. sh ./arch/x86/boot/install.sh 5.16.0-rc3-MANJARO \
  3. arch/x86/boot/bzImage System.map "/boot"
  4. Cannot find LILO.
  5. [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重命名为带版本号的容易标识的名称

  1. [yg-vm linux-rust]# ls -tlh /boot/
  2. 总用量 124M
  3. -rw-r--r-- 1 root root 5.7M 124 18:16 System.map
  4. -rw-r--r-- 1 root root 8.6M 124 18:16 vmlinuz
  5. -rw-r--r-- 1 root root 5.7M 124 14:40 System.old
  6. -rw-r--r-- 1 root root 8.6M 124 14:40 vmlinuz.old
  7. drwxr-xr-x 6 root root 4.0K 124 02:00 grub
  8. -rw-r--r-- 1 root root 29M 124 02:00 initramfs-5.10-x86_64-fallback.img
  9. -rw-r--r-- 1 root root 7.9M 124 02:00 initramfs-5.10-x86_64.img
  10. -rw-r--r-- 1 root root 9.1M 124 02:00 vmlinuz-5.10-x86_64
  11. -rw-r--r-- 1 root root 30M 124 01:22 initramfs-5.4-x86_64-fallback.img
  12. -rw-r--r-- 1 root root 8.4M 124 01:22 initramfs-5.4-x86_64.img
  13. -rw-r--r-- 1 root root 7.1M 124 01:22 vmlinuz-5.4-x86_64
  14. -rw-r--r-- 1 root root 22 1113 04:24 linux510-x86_64.kver
  15. -rw-r--r-- 1 root root 22 1113 04:24 linux54-x86_64.kver
  16. drwxr-xr-x 2 root root 4.0K 1018 01:01 memtest86+
  17. -rw-r--r-- 1 root root 4.6M 69 02:31 intel-ucode.img
  18. [yg-vm linux-rust]# mv /boot/vmlinuz /boot/vmlinuz-5.16.0-rc3-x86_64
  19. [yg-vm linux-rust]#

②、参考本机的preset文件,创建一个新内核的preset文件。

  1. [yg-vm linux-rust]# cd /etc/mkinitcpio.d/
  2. [yg-vm mkinitcpio.d]# ls
  3. linux510.preset linux54.preset
  4. [yg-vm mkinitcpio.d]# cat linux510.preset
  5. # mkinitcpio preset file for the 'linux510' package
  6. ALL_config="/etc/mkinitcpio.conf"
  7. ALL_kver="/boot/vmlinuz-5.10-x86_64"
  8. PRESETS=('default' 'fallback')
  9. #default_config="/etc/mkinitcpio.conf"
  10. default_image="/boot/initramfs-5.10-x86_64.img"
  11. #default_options=""
  12. #fallback_config="/etc/mkinitcpio.conf"
  13. fallback_image="/boot/initramfs-5.10-x86_64-fallback.img"
  14. fallback_options="-S autodetect"
  15. [yg-vm mkinitcpio.d]#
  16. [yg-vm mkinitcpio.d]#
  17. [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即可,之后执行:

  1. [yg-vm mkinitcpio.d]# mkinitcpio -p linux516.preset
  2. /usr/bin/mkinitcpio:行268: /etc/mkinitcpio.d/linux516.preset.preset: 没有那个文件或目录
  3. ==> ERROR: Failed to load preset: `/etc/mkinitcpio.d/linux516.preset.preset'
  4. [yg-vm mkinitcpio.d]#

此时报错说找不到linux516.preset.preset,可见mkinitcpio命令,自动将-p后的文件加了preset后缀了,此时只需把linux516.preset的后缀去掉即可:

[yg-vm mkinitcpio.d]# cp linux516.preset linux516

然后重新mkinitcpio即可:

  1. [yg-vm mkinitcpio.d]# mkinitcpio -p linux516
  2. ==> Building image from preset: /etc/mkinitcpio.d/linux516.preset: 'default'
  3. -> -k /boot/vmlinuz-5.16.0-rc3-x86_64 -c /etc/mkinitcpio.conf -g /boot/initramfs-5.16.0-rc3-x86_64.img
  4. ==> Starting build: 5.16.0-rc3-MANJARO
  5. -> Running build hook: [base]
  6. -> Running build hook: [udev]
  7. -> Running build hook: [autodetect]
  8. -> Running build hook: [modconf]
  9. -> Running build hook: [block]
  10. -> Running build hook: [keyboard]
  11. -> Running build hook: [keymap]
  12. loadkeys: Unable to open file: cn: No such file or directory
  13. -> Running build hook: [consolefont]
  14. ==> WARNING: consolefont: no font found in configuration
  15. -> Running build hook: [filesystems]
  16. -> Running build hook: [fsck]
  17. ==> Generating module dependencies
  18. ==> Creating gzip-compressed initcpio image: /boot/initramfs-5.16.0-rc3-x86_64.img
  19. ==> Image generation successful
  20. ==> Building image from preset: /etc/mkinitcpio.d/linux516.preset: 'fallback'
  21. -> -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
  22. ==> Starting build: 5.16.0-rc3-MANJARO
  23. -> Running build hook: [base]
  24. -> Running build hook: [udev]
  25. -> Running build hook: [modconf]
  26. -> Running build hook: [block]
  27. ==> WARNING: Possibly missing firmware for module: xhci_pci
  28. -> Running build hook: [keyboard]
  29. -> Running build hook: [keymap]
  30. loadkeys: Unable to open file: cn: No such file or directory
  31. -> Running build hook: [consolefont]
  32. ==> WARNING: consolefont: no font found in configuration
  33. -> Running build hook: [filesystems]
  34. -> Running build hook: [fsck]
  35. ==> Generating module dependencies
  36. ==> Creating gzip-compressed initcpio image: /boot/initramfs-5.16.0-rc3-x86_64-fallback.img
  37. ==> Image generation successful
  38. [yg-vm mkinitcpio.d]#

此时大功告成。

七、更新grub配置

一般上面编译完成后,在新版本的linux发行版中,都会自动将最新编译的高版本内核加入到启动项里的,不放心的话,还是手动修改下grub2 boot loader启动配置:

1、Fedora/RHEL/CentOS/Oracle Linux

  1. # grub2-mkconfig -o /boot/grub2/grub.cfg
  2. # grubby --set-default /boot/vmlinuz-5.6.9

修改后可以查看下是否修改成功:

  1. # grubby --default-kernel
  2. # grubby --default-index
  3. # grubby --info=ALL

2、Debian/Ubuntu linux

  1. # update-initramfs -c -k new_kernel
  2. # update-grub

3、Arch Linux/Manjaro

  1. [yg-vm mkinitcpio.d]# update-grub
  2. 正在生成 grub 配置文件 ...
  3. 找到主题:/usr/share/grub/themes/manjaro/theme.txt
  4. 找到 Linux 镜像:/boot/vmlinuz-5.16.0-rc3-x86_64
  5. 找到 initrd 镜像:/boot/intel-ucode.img /boot/initramfs-5.16.0-rc3-x86_64.img
  6. Found initrd fallback image: /boot/initramfs-5.16.0-rc3-x86_64-fallback.img
  7. 找到 Linux 镜像:/boot/vmlinuz-5.10-x86_64
  8. 找到 initrd 镜像:/boot/intel-ucode.img /boot/initramfs-5.10-x86_64.img
  9. Found initrd fallback image: /boot/initramfs-5.10-x86_64-fallback.img
  10. 找到 Linux 镜像:/boot/vmlinuz-5.4-x86_64
  11. 找到 initrd 镜像:/boot/intel-ucode.img /boot/initramfs-5.4-x86_64.img
  12. Found initrd fallback image: /boot/initramfs-5.4-x86_64-fallback.img
  13. 警告: os-prober will be executed to detect other bootable partitions.
  14. Its output will be used to detect bootable binaries on them and create new boot entries.
  15. Found memtest86+ image: /boot/memtest86+/memtest.bin
  16. 完成
  17. [yg-vm mkinitcpio.d]#

八、重启系统生效

执行如下命令,重启系统:

  1. # reboot
  2. 或者
  3. # init 6

重启系统时,如果能看到开机界面,此时在内核启动项那里已经可以看到新编译的内核了。

启动后,使用命令查看当前内核版本:

# uname -a

参考链接:How to build and install your own Linux kernel - LQWiki

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/99340
推荐阅读
相关标签
  

闽ICP备14008679号