Linux内核的编译、安装、调试

这篇具有很好参考价值的文章主要介绍了Linux内核的编译、安装、调试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

编译安装内核

下载内核

Linux内核下载The Linux Kernel Archives

安装依赖

sudo apt-get install gcc g++ libncurses5-dev build-essential kernel-package libssl-dev libc6-dev bin86 flex bison qttools5-dev libelf-dev

更改.config

#拷贝现有ubuntu的.config至编译内核的目录
cp -v /boot/config-$(uname -r) .config
make menuconfig
  1. 打开.config更改CONFIG_SYSTEM_TRUSTED_KEYS CONFIG_SYSTEM_REVOCATION_KEYS
CONFIG_SYSTEM_TRUSTED_KEYS=''
CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=2048
CONFIG_SYSTEM_REVOCATION_KEYS=""
  1. 更改CONFIG_DEBUG_INFO_BTF
CONFIG_DEBUG_INFO_BTF=n
  1. 注释掉CONFIG_X86_X32
#CONFIG_X86_X32=y

编译内核

#基于文本选单的配置界面,字符终端下推荐使用
make menuconfig

make -j$(nproc)

make all

# 编译模块
make -j$(nproc) modules

安装

首先安装模块

这里加上INSTALL_MOD_STRIP=1是为了避免内核启动时卡在 loading initial ramdisk

sudo make INSTALL_MOD_STRIP=1 modules_install

安装内核

make bzImage
sudo make install

更改引导

sudo update-initramfs -c -k 5.10.0

更改grub

修改文件

sudo vi /etc/default/grub
#GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=10

更新

sudo update-grub

重启

reboot

GRUB页面选择Advanced options for Ubuntu

Linux内核的编译、安装、调试

选择需要启动的内核版本

Linux内核的编译、安装、调试

Linux内核的编译、安装、调试

安装新内核之前的内核版本

Linux内核的编译、安装、调试

安装新内核之后

若重启未看到选择内核的页面参考

其他操作

清理内核源目录

# make mrproper会删除配置的.config以及其他备份
sudo make mrproper
# make clean会删除编译过程中生成的中间文件和内核镜像文件
sudo make clean

卸载安装的内核

获取所有安装的内核版本

dpkg --get-selections | grep linux

选择要卸载的版本,卸载下列安装包

sudo apt remove linux-image-<版本>-generic
sudo apt remove linux-headers-<版本>
sudo apt remove linux-headers-<版本>-generic
sudo apt remove linux-modules-<版本>-generic

卸载源码版本

sudo rm /boot/vmlinuz-5.10.0
sudo rm /boot/initrd.img-5.10.0
sudo rm /boot/System.map-5.10.0
sudo rm /boot/config-5.10.0
sudo rm -rf /lib/modules/5.10.0

更新启动引导

sudo update-grub

修改内核配置菜单实现对新加入内核源码的控制

  1. 将源码拷贝到内核对应的文件夹下

  2. 为配置界面添加控制新加入源代码的内容

    在加入源码的目录下创建Kconfig文件,便添加相应控制内容

  3. 修改上层Kconfig文件,包含新加入源码的Kconfig文件。

  4. 修改Makefile文件

  5. 修改上一级目录的Makefile

make[1]: *** No rule to make target 'debian/canonical-certs.pem', needed by 'certs/x509_certificate_list'.  Stop.
make: *** [Makefile:1868: certs] Error 2

解决方法(104) how to fix the error "No rule to make target ‘debian canonical certs pem’, needed by 'certs x509 cer - YouTube:

nano .config
查找到debian/canonical-certs.pem和debian/canonical-revoked-certs.pem字符串删除
BTF: .tmp_vmlinux.btf: pahole (pahole) is not available

解决方法

sudo apt install dwarves

常见问题

1. Module.symvers is missing

WARNING: Symbol version dump "Module.symvers" is missing.
         Modules may not have dependencies or modversions.
         You may get many unresolved symbol warnings.

执行

make modules_prepare

2. No rule to make target ‘debian/canonical-certs.pem‘, needed by ‘certs/x509_certificate_list‘

可以修改config:

vim .config

修改CONFIG_SYSTEM_TRUSTED_KEYS,将其置空: CONFIG_SYSTEM_TRUSTED_KEYS=""也可能需要设置CONFIG_SYSTEM_REVOCATION_KEYS为空。

3. FAILED:load BTF from vmlinux:No such file or directory

vim .config

修改CONFIG_DEBUG_INFO_BTF,将其置n

4. 安装完内核之后无法显示GRUB用以选择内核启动

进入命令行之后执行

sudo vi /etc/default/grub

注释掉

# GRUB_TIMEOUT_STYLE=hidden

修改

GRUB_TIMEOUT=10

GRUB_COMLINE_LINUX_DEFAULT="text"

Linux内核的编译、安装、调试

执行

sudo update-grub

Linux内核的编译、安装、调试

5. 内核启动卡在loading initial ramdisk

编译内核过程中,当安装内核模块时未使用

INSTALL_MOD_STRIP=1

标注,会导致initrd文件过大,Ubuntu 20.04所用的Grub 2.04无法支持过大的initrd文件(如500M),导致内核启动时卡在“loading initial ramdisk”(Can’t allocate initrd)

可行的办法:

安装模块时加上INSTALL_MOD_STRIP=1

sudo make INSTALL_MOD_STRIP=1 modules_install

6. sign-file: : No such file or directory

报错信息:

Linux内核的编译、安装、调试

解决方法:

.configCONFIG_MODULE_SIG_KEY="cert/signing_key.pem"恢复后解决。

CONFIG_MODULE_SIG_KEY="cert/signing_key.pem"

7. zstd: not found

ZSTD22  arch/x86/boot/compressed/vmlinux.bin.zst
/bin/sh: 1: zstd: not found
make[2]: *** [arch/x86/boot/compressed/Makefile:134: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

解决方法

在配置内核时更改Kernel compression modeLZMA

General setup  --->
	Kernel compression mode (LZMA)  --->

保存后重新编译安装即可。

单独编译Linux内核的某一个模块

找到对应的模块文件夹,找到需要编译的文件,确认编译的config文件

make CONFIG_INFINIBAND=m -C <源码> M=<模块文件夹> modules

qemu+gdb调试linux内核

安装qemu

sudo apt install qemu

配置调试版内核

对内核进行调试需要解析符号信息,所以得编译一个调试版内核。

cd linux-5.15
make menuconfig

这里需要开启内核参数CONFIG_DEBUG_INFOCONFIG_GDB_SCRIPTS。GDB提供了Python接口来扩展功能,内核基于Python接口实现了一系列辅助脚本,简化内核调试,开启CONFIG_GDB_SCRIPTS参数就可以使用了。

Kernel hacking  --->
    [*] Kernel debugging
    Compile-time checks and compiler options  --->
        [*] Compile the kernel with debug info
        [*]   Provide GDB scripts for kernel debugging

构建initramfs根文件系统

Linux系统启动阶段,boot loader加载完内核文件vmlinuz后,内核紧接着需要挂载磁盘根文件系统,但如果此时内核没有相应驱动,无法识别磁盘,就需要先加载驱动,而驱动又位于/lib/modules,得挂载根文件系统才能读取,这就陷入了一个两难境地,系统无法顺利启动。于是有了initramfs根文件系统,其中包含必要的设备驱动和工具,boot loader加载initramfs到内存中,内核会将其挂载到根目录/,然后运行/init脚本,挂载真正的磁盘根文件系统。

这里借助BusyBox构建极简initramfs,提供基本的用户态可执行程序。

编译BusyBox,配置CONFIG_STATIC参数,编译静态版BusyBox,编译好的可执行文件busybox不依赖动态链接库,可以独立运行,方便构建initramfs。

cd busybox-1.28.0
make menuconfig
Settings  --->
    [*] Build static binary (no shared libs)
make -j 20
make install

会安装在_install目录:

ls _install
bin  linuxrc  sbin  usr

创建initramfs,其中包含BusyBox可执行程序、必要的设备文件、启动脚本init。这里没有内核模块,如果需要调试内核模块,可将需要的内核模块包含进来。init脚本只挂载了虚拟文件系统procfssysfs,没有挂载磁盘根文件系统,所有调试操作都在内存中进行,不会落磁盘。

mkdir initramfs
cd initramfs
cp ../_install/* -rf ./
mkdir dev proc sys
sudo cp -a /dev/{null, console, tty, tty1, tty2, tty3, tty4} ./dev/
rm linuxrc
vim init
chmod a+x init
ls
bin   dev  init  proc  sbin  sys   usr

init文件的内容

#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo -e "\nBoot took $(cut -d' ' -f1 /proc/uptime) seconds\n"
exec /bin/sh

打包initramfs

find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.cpio.gz

调试

cd busybox-xxx
qemu-system-x86_64 -s -kernel /path/to/vmlinux -initrd initramfs.cpio.gz -nographic -append "console=ttyS0"
  • -s-gdb tcp::1234的缩写,监听1234端口,在GDB中通过target remote localhost:1234连接;
  • -kernel 指定编译好的调试内核vmlinux路径;
  • initrd 指定制作好的initramfs
  • -nographic取消图形输出窗口,试qemu成简单的命令行程序。
  • -append "console=ttyS0"将输出重定向到console,将会显示在标准输出stdio。

启动后的根目录

/ ls
bin   dev  init  proc  root  sbin  sys   usr

参考

使用QEMU和GDB调试Linux内核 | Consen

Linux下使用内核源码单独编译某一模块 - tycoon3 - 博客园 (cnblogs.com)

内核错误: No rule to make target ‘debian/canonical-certs.pem‘, needed by ‘certs/x509_certificate_list‘_no rule to make target 'debian/canonical-certs.pem_蓝天居士的博客-CSDN博客

Linux 内核 下载 编译 安装 2021 ubuntu_yaoxinJJJ的博客-CSDN博客

内核Module.symvers文件揭秘 - Linux内核编程 | 宅学部落 (zhaixue.cc)

如何编译安装Linux内核 - LightningStar - 博客园 (cnblogs.com)

ubuntu上更新和卸载Linux内核 - 广漠飘羽 - 博客园 (cnblogs.com)

关于Ubuntu内核(更新和卸载内核、取消自动更新) · Issue #1 · chiwent/blog (github.com)

自行编译内核,启动内核卡在“loading initial ramdisk”_启动卡在initrd_奇妙之二进制的博客-CSDN博客

linux——编译内核(ubuntu18.04+linux-5.6.4)

编译内核 make modules_install报错SSL error:02001002:system library:fopen:No such file or directory_ssl: error:02001002_酱山楂的博客-CSDN博客

中文翻译 — The Linux Kernel documentation Linux内核中文文档。

[arch/x86/boot/compressed/vmlinux.bin.lzma] Error 1_sustwct的博客-CSDN博客


🚍
🥙
🍥文章来源地址https://www.toymoban.com/news/detail-510472.html

到了这里,关于Linux内核的编译、安装、调试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • VScode 调试 linux内核

    这里调试的 linux 内核是通过 Linux+SD卡(rootfs)运行的内核 编辑 /home/tyustli/.gdbinit 文件,参考 【GDB】 .gdbinit 文件 在 linux 源码项目的根目录新建 .gdbinit 文件 先启动 linux 内核,让其等待 GDB 连接 在编译 linux 的当前路径输入 如果没有设置 /home/tyustli/.gdbinit 文件,那么对应的命令为

    2024年02月07日
    浏览(43)
  • 【linux内核】Debian内核编译

    列出 Debian 内各种版本的核心软件包 apt安装软件包 编译内核源码 安装内核 更新grub 参考: 8.10. 编译内核 (debian.org) Debian编译内核教程 - 时光旅行的懒猫 - 博客园 (cnblogs.com) 内核编译方法-tony_ayuan-ChinaUnix博客

    2024年02月17日
    浏览(49)
  • 内核实验(四):Qemu调试Linux内核,实现NFS挂载

    在文章《内核实验(三)……》中,通过挂载虚拟分区,解决了Host和虚拟机文件交换的问题,但依旧比较麻烦。为了提升效率,必须解决NFS挂载共享文件夹的问题。如能实现,则直接在虚拟机上挂载服务端的NFS目录,即可实时交换文件,大大提升效率! 关于Qemu虚拟机挂载

    2024年02月02日
    浏览(36)
  • Linux内核基础篇——printk调试

    很多内核开发者喜欢的调试工具是printk,在Linux内核中,使用printk()函数来打印信息,它与C库的printf()函数类似。 printk()与printf()的一个重要区别是: printk()提供输出等级 。内核会根据这个等级来判断是否在终端或者串口中输出。 路径: include/linux/kern_levels.h Linux内核为printk定

    2024年02月13日
    浏览(41)
  • 【Linux】驱动内核调试,是需要几板斧的

    目录 前言: 一、基础打印工具  (1)printk---最常用 ①Log Buffer: ②Console: ③RAM Console: (2)动态打印 ①动态打印与printk之间的区别联系 ②动态打印常用的例子 ③动态打印转为printk正常打印  (3)dump_stack---分析源码的利器 (4)操作寄存器命令---硬件测试 ①devmem---系统层

    2024年02月05日
    浏览(42)
  • 调试linux内核(1): 环境准备和原理介绍

    现在流行的开源项目经历了长时间的开发, 积累了大量的代码, 想要一行一行地阅读代码去学习开源项目, 需要的时间成本是巨大的. 所以, 我们也需要用一种高效的方式去\\\"阅读\\\"代码. 计算机科学发展到现在, 产生了很多高效成熟的工具, 调试器就是其中之一(扯句题外话, 那些大

    2024年02月14日
    浏览(39)
  • linux内核分析编译体验

    linux-2.6.22.6 下载地址 https://mirrors.edge.kernel.org/pub/linux/kernel/v2.6/ linux-2.6.22.6_jz2440.patch下载地址 https://download.csdn.net/download/zjq_5586288/10438800?utm_source=bbsseo cd /home/li/kernel_learn/linux-2.6.22.6 patch -p1 …/linux-2.6.22.6_jz2440.patch 三种方式 (1)make menuconfig (2)使用默认配置(defconfig)在上面

    2023年04月11日
    浏览(40)
  • 树莓派Linux内核编译

    树莓派内核源代码保存在GitHub上github.com/raspberrypi/linux,可以看做是Linux主线内核代码的一个分支。树莓派内核源代码是从Linux主线的长期维护的稳定版本加上树莓派特有的改动形成的。树莓派的内核更新可以通过apt命令自动更新到最新的稳定版本。但是如果你需要使用到最新

    2024年02月08日
    浏览(47)
  • 调试linux内核(2): poll系统调用的实现

    linux内核为用户态进程提供了一组IO相关的系统调用: select/poll/epoll, 这三个系统调用功能类似, 在使用方法和性能等方面存在一些差异. 使用它们, 用户态的进程可以\\\"监控\\\"自己感兴趣的文件描述符, 当这些文件描述符的状态发生改变时, 比如可读或者可写了, 内核会通知进程去处

    2024年02月11日
    浏览(36)
  • 编译tiny4412 Linux 内核

    工作环境 Ubuntu 22 交叉编译器 4.5.1 解压Linux内核源码,进入目录 将官方配置完好的defconfig文件作为配置文件 由于内核版本较低,需要下载低版本的gcc,选择下载gcc-9与g+±9 将gcc g++版本都切换为9 切换后可以通过 gcc -v 查看是否切换成功 进入Linux目录,执行make编译 出现错误 C

    2024年02月11日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包