如何现代的编译和安装内核

前言:本文是在阅读书目时找到了一篇非常高质量的文章。的原文是英文,现在我自己手头翻译了一下,发布到这里。

原文连接:How to compile a Linux kernel in the 21st century | Opensource.com

目录

更新内核的现代方法

安装内核模块

下载,并且安装一个驱动

编译(Compiling)或给kernel打补丁(Patching)

实际编译

内核


如何现代的编译和安装内核

在计算机领域,内核是处理与硬件通信和一般系统协调的底层软件。除了计算机主板上内置的一些初始固件外,当你启动计算机时,内核向上提供一种抽象,让应用层软件知道计算机有硬盘、屏幕、键盘和网卡。内核的工作还包括确保每个组件都有相同的运行时间(或多或少),以便图形、音频、文件系统和网络都能顺利运行,它们可以是同时运行的。

不过,对硬件支持的追求是持续性的,因为发布的硬件越多,内核就必须在代码中采用越多的东西,才能使硬件按预期运行。虽然很难获得准确的数字,但 Linux 内核在硬件兼容性方面肯定是名列前茅的。Linux 操作着无数的电脑和手机、业余爱好者和工业用途的嵌入式系统芯片(SoC)板、RAID 卡等等。

在 20 世纪(甚至 21 世纪初),Linux 用户在购买新硬件时,需要下载最新的内核源代码、编译并安装,以便获得设备支持。但最近,你很难找到一个自己编译内核的 Linux 用户,除非是为了好玩或通过高度专业化的定制硬件获利。现在,一般不需要自己编译 Linux 内核了。

以下是编译内核的原因,以及如何在需要时编译内核的快速教程。

更新内核的现代方法

无论你是买了一台全新的笔记本电脑,配备了炫目的新显卡或 WiFi 芯片组,还是刚把一台新打印机带回家,你的操作系统(称为 GNU+Linux 或简称 Linux,也是内核的名称)都需要一个驱动程序来打开与新组件(显卡、WiFi 芯片、打印机或其他)的通信通道。有时,当你插入一个新设备时,你的电脑似乎承认了它,这可能具有欺骗性。但千万别被骗了。有时这就是你所需要的,但有时你的操作系统只是使用通用协议来探测已连接的设备。

例如,你的电脑可能能够识别你的新网络打印机,但有时这只是因为打印机中的网卡被编程为识别自己的网络,以便获得 DHCP 地址。这并不一定意味着你的电脑知道向打印机发送什么指令才能打印出一页文本。事实上,你可能会说,计算机甚至并不真正 "知道 "该设备是一台打印机;它可能只是显示网络上有一台设备在一个特定的地址上,而该设备用一系列字符p-r-i-n-t-e-r来标识自己。人类的语言习惯对计算机来说毫无意义,它需要的是一个驱动程序。

内核开发人员、硬件制造商、技术支持人员和业余爱好者都知道,新硬件在不断推出。他们中的许多人都会直接向内核开发团队提交驱动程序,以便将其纳入 Linux。例如,Nvidia 显卡驱动程序通常被写入Nouveau内核模块,而且,由于 Nvidia 显卡很常见,这些代码通常会被包含在任何发布的通用内核中(如下载Fedora 或Ubuntu时获得的内核)。在 Nvidia 不常用的地方,例如嵌入式系统中,Nouveau 模块通常被排除在外。许多其他设备也有类似的模块:打印机有 Foomatic 和 CUPS 模块,无线网卡有 b43, ath9k, wl 模块,等等。

发行版倾向于在其 Linux 内核构建中尽可能多地包含这些模块,因为它们希望你能够连接设备并立即开始使用,而无需安装驱动程序。这在大多数情况下都会发生,尤其是现在许多设备供应商都在为他们销售的硬件提供 Linux 驱动程序开发资金,并将这些驱动程序直接提交给内核团队进行发布。

但有时,你运行的是六个月前安装的内核,而一周前刚上市的新设备令人兴奋。在这种情况下,你的内核可能没有该设备的驱动程序。好在很多时候,最近版本的内核中可能就有该设备的驱动程序,这意味着你只需更新正在运行的内核即可。

一般来说,这可以通过软件包管理器完成。例如,在 RHEL、CentOS 和 Fedora 上:

sudo dnf update kernel

对于Debian和 Ubuntu 上,首先需要查看的是系统内核的版本:

$ uname -r
6.5.0-41-generic

下一步就是查找更新的源:

$ sudo apt update
$ sudo apt search linux-image

我们看看结果如何

linux-image-5.15.0-76-lowlatency/jammy-updates,jammy-security 5.15.0-76.83 amd64
linux-image-6.8.0-1008-azure/jammy-updates,jammy-security 6.8.0-1008.8~22.04.1 amd64
linux-image-6.8.0-1008-azure-fde/jammy-updates,jammy-security 6.8.0-1008.8~22.04.1 amd64
linux-image-6.8.0-1008-nvidia/jammy-updates,jammy-security 6.8.0-1008.8~22.04.1 amd64
linux-image-azure-edge/jammy-updates,jammy-security 6.8.0-1008.8~22.04.1 amd64
linux-image-azure-fde-edge/jammy-updates,jammy-security 6.8.0-1008.8~22.04.1 amd64
linux-image-nvidia-6.8/jammy-updates,jammy-security 6.8.0-1008.8~22.04.1 amd64
linux-image-nvidia-hwe-22.04-wip/jammy-updates,jammy-security 6.8.0-1008.8~22.04.1 amd64
linux-image-uc-6.8.0-1008-nvidia/jammy-updates,jammy-security 6.8.0-1008.8~22.04.1 amd64
linux-image-unsigned-5.15.0-76-lowlatency/jammy-updates,jammy-security 5.15.0-76.83 amd64
linux-image-unsigned-6.8.0-1008-azure/jammy-updates,jammy-security 6.8.0-1008.8~22.04.1 amd64Linux kernel image for version 6.8.0 on 64 bit x86 SMP
linux-image-unsigned-6.8.0-1008-nvidia/jammy-updates,jammy-security 6.8.0-1008.8~22.04.1 amd64Linux kernel image for version 6.8.0 on 64 bit x86 SMP

我们可以找最新的6.8的内核

sudo apt install linux-image-6.8.0

下载完成,下一步就是简单的重启就行。

安装内核模块

有时,发行版并不希望用户经常使用某个设备(或者至少不希望设备驱动程序出现在 Linux 内核中)。Linux 采用模块化方式处理驱动程序,因此发行版可以提供单独的驱动程序包,即使驱动程序没有编译到内核中,内核也可以加载这些驱动程序包。这很有用,不过当内核中不包含驱动程序,但在启动过程中需要使用,或者内核从模块化驱动程序下更新时,情况就会变得复杂。第一个问题由 initrd(初始 RAM 磁盘)解决,不在本文讨论范围之内,第二个问题由名为 kmod 的系统解决。

下面,我们一个 Nvidia 驱动程序作为例子:

kmod 系统能确保内核更新时,同时安装的所有模块化驱动程序也得到更新。如果你手动安装驱动程序,就会错过 kmod 提供的自动化功能,因此只要有 kmod 软件包,你就应该选择安装。例如,虽然 Nvidia 驱动程序作为 Nouveau 驱动程序内置于内核中,但 Nvidia 官方驱动程序仅由 Nvidia 发布。你可以通过访问网站、下载 .run 文件并运行其提供的 shell 脚本来手动安装 Nvidia 品牌的驱动程序,但在安装新内核后,你必须重复同样的过程,因为没有任何信息会告诉你的软件包管理器你手动安装了内核驱动程序。由于显卡由 Nvidia 驱动,手动更新 Nvidia 驱动程序通常意味着你必须在终端上执行更新,因为没有正常运行的显卡驱动程序就没有显卡。

Nvidia configuration application

当然,我们如果下载的是Nvidia的模块驱动,我们可以直接以挂载module的方式,在更新系统的时候把驱动更新了。

Fedora系列的:

$ sudo dnf install kmod-nvidia

在Debian系列的

sudo apt update
$ sudo apt install nvidia-kernel-common nvidia-kernel-dkms nvidia-glx nvidia-xconfig nvidia-settings nvidia-vdpau-driver vdpau-va-driver

当然这仅仅只是一个例子,但是如果你正在下载英伟达显卡驱动,你必须将Nouveau的驱动拉入黑名单。更加具体的需要查看你的发行版的文档,以获取最佳的安装步骤。

下载,并且安装一个驱动

并非所有东西都包含在内核中,也并非所有其他东西都可以作为内核模块使用。在某些情况下,你必须下载由硬件供应商编写和捆绑的特殊驱动程序,而在其他情况下,你有驱动程序却没有配置驱动程序选项的前端。

惠普打印机和 Wacom 绘图板就是两个常见的例子。如果你买的是惠普打印机,那么你可能拥有可以与打印机通信的通用驱动程序。你甚至可以打印。但通用驱动程序可能无法提供针对你的型号的专门选项,如双面打印、拼版、纸盘选择等。HPLIP(HP Linux 成像和打印系统)提供了管理作业、调整打印选项、选择适用纸盘等选项。

HPLIP 通常捆绑在软件包管理器中;只需搜索 "hplip "即可。

HPLIP in action

同样,Wacom 平板电脑(数字艺术家的主要插画平板电脑)的驱动程序通常包含在内核中,但微调设置的选项(如压力灵敏度和按钮功能)只能通过 GNOME 默认包含的图形控制面板访问,但在 KDE 中可作为额外软件包 kde-config-tablet 安装。

可能还有一些相对罕见的情况——内核中没有驱动程序,但以 RPM 或 DEB 文件的形式提供 kmod 版本的驱动模块,你可以通过软件包管理器下载并安装。

编译(Compiling)或给kernel打补丁(Patching)

即使在未来乌托邦的 21 世纪,也有一些厂商对开放源代码的理解不够深刻,无法提供可安装的驱动程序。有时,这些公司会提供驱动程序的源代码,但希望你下载代码、修补内核、编译并手动安装。

这种发布模式与在 kmod 系统外安装打包驱动程序有同样的缺点:内核更新会破坏驱动程序,因为每次更换新内核时,都必须手动将其重新集成到内核中。

令人欣慰的是,这种情况已经很少见了,因为 Linux 内核团队已经做得很好,他们大声恳求公司与他们沟通,而且公司也终于接受了开源不会很快消失的事实。但仍有一些新奇或超专业的设备只提供内核补丁。

官方对如何编译内核有特定的发行版偏好,以便让软件包管理器参与升级系统中如此重要的部分。软件包管理器种类繁多,无法一一列举;举例来说,以下是 Fedora 上的 rpmdev 或 Debian 上的 build-essential 和 devscripts 等工具的幕后工作。

一般的步骤如下:

uname -r

在大多数情况下,如果您还没有升级内核,那么升级内核是安全的。毕竟,你的问题有可能在最新版本中得到解决。如果你尝试了,但没有成功,那么你应该下载你正在运行的内核的源代码。大多数发行版都为此提供了专门的命令,但要手动下载,你可以在 kernel.org 上找到源代码。

您还必须下载内核所需的补丁。有时,这些补丁与内核版本有关,因此要谨慎选择。

将源代码和补丁文件放在 /usr/src/linux 中是一种传统做法,至少在人们经常编译自己的内核时是这样。

根据需要解压缩内核源代码和补丁文件:

$ cd /usr/src/linux
$ bzip2 --decompress linux-5.2.4.tar.bz2
$ cd  linux-5.2.4
$ bzip2 -d ../patch*bz2

这里的补丁文件可能会有若干指引步骤来指导你如何来给内核。打补丁,但是通常的他们会被设计。在你的代码层次数上的顶层开始执行。

$ patch -p1 < patch*example.patch

一旦你的内核代码被打上了补丁,你可以尝试用你电脑的旧的配置文件来准备对内核配置进行补丁。

$ make oldconfig

make oldconfig指令完成两个重要的目的,它继承了你当前内核的配置,以及它允许你去配置新的选项,这些新的选项则是通过补丁而被引入的。

你也有可能需要运行make menuconfig ,他们是受这样的一些包进行支持的 :ncurses-based, menu-driven等。菜单可能会让人应接不暇,但由于它是以你的旧配置为基础启动的,你可以查看菜单,禁用那些你知道自己没有、预计也不需要的硬件模块。另外,如果你知道自己拥有某些硬件,但发现当前配置中不包含这些硬件,你可以选择将其作为模块或直接内置到内核中。从理论上讲,这并不是必须的,因为如果没有丢失的补丁,你当前的内核应该是不错的,而且你应用的补丁可能已经激活了所有必要的选项,不管是什么设备促使你首先为内核打上补丁。

接下来,编译内核及其模块:

$ make bzImage
$ make modules

采取如此的行动将会给你生成一个这样的文件,它是可以被启动内核的文件的压缩版本。我们保留旧的内核压缩版本,然后把新的内核压缩文件放到/boot目录下

$ sudo mv /boot/vmlinuz /boot/vmlinuz.nopatch
$ sudo cat arch/x86_64/boot/bzImage > /boot/vmlinuz
$ sudo mv /boot/System.map /boot/System.map.stock
$ sudo cp System.map /boot/System.map

目前为止你已经给内核打上补丁,并且将之完成构建以及相关的模块,你已经成功的安装了内核,但是你并没有安装模块,所以我们需要做最后的步骤。

$ sudo make modules_install

在新的内核已经就位以及它的模块也被安装完成,最后一步就是更新我们的bootloader,这样的话我们的电脑将会加载这些新的内核。这一步就是告知GRUB启动器内核的位置。

$ sudo grub2-mkconfig
实际编译

当然,现在没人会执行这些手动命令。取而代之的是,你可以参考发行版的说明,使用发行版维护者使用的开发者工具集修改内核。该工具集可能会创建一个包含所有补丁的新安装包,提醒软件包管理器进行升级,并为你更新引导加载器。

内核

操作系统和内核是很神秘的东西,但要了解它们是基于什么组件构建的并不难。下一次,当你得到一项似乎无法在 Linux 上运行的技术时,深吸一口气,调查驱动程序的可用性,然后选择阻力最小的途径。Linux 比以往任何时候都要简单,包括内核。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/38586.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++知识点总结全系列 (05):IO 类的详细总结和分析

1、基类 istream 和 ostream (1)istream A.What 输入流的抽象类&#xff0c;是所有输入流类的基类 B.Why&#xff08;输入流的作用&#xff09; 用于从数据源&#xff08;如文件、标准输入设备等&#xff09;读取数据 (2)ostream A.What 输出流的抽象类&#xff0c;是所有输…

grpc学习golang版( 六、服务器流式传输 )

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 第五章 多proto文件示例 第六章 服务器流式传输 第七章 客户端流式传输 第八章 双向流示例 文章目录 一、前言二、定义proto文件三、拷贝任意文件进项目四、编写serve…

复制完若依后,idea没有maven窗口

右击项目 添加框架 添加maven框架就可以了

大数据开发中的数据倾斜问题

数据倾斜是大数据开发中常见的性能瓶颈&#xff0c;了解其原因并采取有效的解决方案对系统性能至关重要。本文将从数据倾斜的影响、解决方法及示例代码等方面进行详细讨论。 目录 1. 数据倾斜的影响2. 解决数据倾斜的方法调整分区键预聚合倾斜处理逻辑 3. 进一步解决数据倾斜的…

vue3.0 + vant实现下拉刷新上拉加载

在vue中使用vant组件库有个van-pull-refresh下拉组件&#xff0c;配合van-list列表组件实现页面的下拉刷新和上拉加载&#xff0c;原理简单&#xff0c;适用场景在列表页面内容展示。 下拉刷新 PullRefresh 实现下拉刷新的效果。 PullRefresh组件中的searchRefreshing属性&…

51单片机嵌入式开发:STC89C52环境配置到点亮LED

STC89C52环境配置到点亮LED 1 环境配置1.1 硬件环境1.2 编译环境1.3 烧录环境 2 工程配置2.1 工程框架2.2 工程创建2.3 参数配置 3 点亮一个LED3.1 原理图解读3.2 代码配置3.3 演示 4 总结 1 环境配置 1.1 硬件环境 硬件环境采用“华晴电子”的MINIEL-89C开发板&#xff0c;这…

安卓app开发-基础-本地环境安装android studio且配置参数

安卓app开发-基础-本地环境安装android studio且配置参数&#xff01;今天为大家介绍一下&#xff0c;如何在自己本地电脑安装android ,studio和启动一个简单的java版本的项目。 第一步&#xff0c;去下面的地址&#xff0c;下载一个安装文件。 地址&#xff1a;AndroidDevToo…

root密码忘了怎么办(从系统引导过程解决)

目录 1.Linux系统密码忘记 2.系统引导过程 2.1 systemd 2.2 GRUB和GRUB2 2.3 运行级别 3.修复MBR扇区故障和GRUB引导故障 3.1 MBR扇区故障 3.2 GRUB引导故障 1.Linux系统密码忘记 我们在生活中经常遇到这类困扰&#xff0c;就是某个账号还是账户密码忘了&#xff0c;这…

Docker的理解

Docker的理解 Docker为什么用Docker&#xff1f;1.提升系统资源利用率2.更快速的交付和部署3.高效的部署和扩容4.更简单的管理 Docker核心技术Docker镜像Docker容器Docker仓库 Docker实现原理Linux NamespaceCgroupUnion FS Docker的应用场景1.微服务架构2.持续集成3.快速部署和…

DP V2.1a标准学习

一、说明 DP是DisplayPort的简写,是视频电子标准协会(VESA)标准化的数字式视频接口标准,可用于板内芯片之间的连接,也可用于输出接口连接外部设备。DisplayPort是一种基于数据包的可扩展协议,用于传输视频和音频数据。DisplayPort 具有高度可扩展性,并具有保持向后兼容…

【一步一步了解Java系列】:对这个系列的总结以及对缺漏内部类知识的补充

看到这句话的时候证明&#xff1a;此刻你我都在努力 加油陌生人 br />个人主页&#xff1a;Gu Gu Study专栏&#xff1a;一步一步了解Java 喜欢的一句话&#xff1a; 常常会回顾努力的自己&#xff0c;所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者&#xf…

《昇思25天学习打卡营第27天 | 昇思MindSporeShuffleNet图像分类》

27天 本节学习了ShuffleNet图像分类 ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一样主要应用在移动端&#xff0c;模型的设计目标就是利用有限的计算资源来达到最好的模型精度。设计核心是引入了两种操作&#xff1a;Pointwis…

【Python机器学习】模型评估与改进——分组交叉验证

分组交叉验证是非常常见的一种交叉验证策略&#xff0c;它适用于数据中的分组高度相关时。比如我们想构建一个从人脸图片中识别情感的系统&#xff0c;并且收集了100个人的照片的数据集&#xff0c;其中每个人都进行了多次拍摄&#xff0c;分别展示了不同的情感。我们的目标是构…

使用gradle上传maven工件到新版maven central仓库central.sonatype.com

本文主要用到的插件是sonatype-uploader, 该插件主要功能是上传依赖文件夹到中央仓库。 该文件夹的生成也十分简单&#xff0c;不用担心。 前言 最近在研究maven插件的时候发现发布的网站发生了变化&#xff0c;使用之前的一些插件没能满足我发布依赖的需求&#xff0c;也可…

数据结构与算法笔记:实战篇 - 剖析Redis常用数据类型对应的数据结构

概述 从本章开始&#xff0c;就进入实战篇的部分。这部分主要通过一些开源醒目、经典系统&#xff0c;真枪实弹地教你&#xff0c;如何将数据结构和算法应用到项目中。所以这部分的内容&#xff0c;更多的是知识点的回顾&#xff0c;相对于基础篇和高级篇&#xff0c;其实这部…

fastapi swagger在线接口文档报错

fastapi swagger在线接口文档报错 1、报错信息 Unable to render this definition The provided definition does not specify a valid version field. Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: “2.0” and those …

【收藏】SaaS运营方法论:寻找合适的合作伙伴的四大方法

一、使用关键字研究工具查找您所在行业的相关博客、频道和网站 但是&#xff0c;根据你的业务规模和性质&#xff0c;如果你需要主动出击寻找合适的推广伙伴&#xff0c;而不仅限于让潜在合作伙伴找你&#xff0c;你可以使用关键字研究工具。 实话实说&#xff0c;最好的联盟营…

告别手工录入,企业财务凭证同步迈入智能新时代!

一、客户介绍 某金融租赁股份有限公司作为一家领先的金融租赁企业&#xff0c;一直秉持着创新驱动、服务至上的经营理念。随着业务的快速发展&#xff0c;该公司在财务管理和凭证管理方面遇到了新的挑战。为了更好地提升工作效率&#xff0c;降低运营成本&#xff0c;该公司决…

Spring两大核心思想 IoC和AoP

目录 ✨ 一、什么是IoC 1、定义 &#x1f38a; 2、IoC思想 &#x1f38a; 3、优势 &#x1f38a; 4、对象的管理 &#x1f38a; 存对象&#xff1a;Component 取对象&#xff1a;AutoWired ✨二、什么是DI 1、定义 &#x1f38a; 2、IoC和DI的关系&#x1f38a; 可…

嵌入式Linux系统编程 — 5.7 Linux系统中proc文件系统

目录​​​​​​​ 1 proc文件系统简介 2 proc 文件系统的使用 2.1 使用 cat 命令读取 2.2 使用 read()函数读取 1 proc文件系统简介 /proc 文件系统&#xff0c;也称为进程信息文件系统&#xff08;Process Information file system&#xff09;&#xff0c;是一种在 Li…