[Feelings & Sharing] 如何编译 Linux 内核
Tofloor
poster avatar
180******29
deepin
2021-02-03 05:30
Author

曾经有一段时间,升级 Linux 内核让很多用户打心里有所畏惧。在那个时候,升级内核包含了很多步骤,也需要很多时间。现在,内核的安装可以轻易地通过像 apt 这样的包管理器来处理。通过添加特定的仓库,你能很轻易地安装实验版本的或者指定版本的内核(比如针对音频产品的实时内核)。

考虑一下,既然升级内核如此容易,为什么你不愿意自行编译一个呢?这里列举一些可能的原因:

  • 你想要简单了解编译内核的过程
  • 你需要启用或者禁用内核中特定的选项,因为它们没有出现在标准选项里
  • 你想要启用标准内核中可能没有添加的硬件支持
  • 你使用的发行版需要你编译内核
  • 你是一个学生,而编译内核是你的任务

不管出于什么原因,懂得如何编译内核是非常有用的,而且可以被视作一个通行权。当我第一次编译一个新的 Linux 内核,然后尝试从它启动,我从中(系统马上就崩溃了,然后不断地尝试和失败)感受到一种特定的兴奋。

既然这样,让我们来实验一下编译内核的过程。我将使用 深度liunx  20.1来进行演示。在运行了一次常规的 sudo apt upgrade 之后,当前安装的内核版本是 5.8.14。我想要升级内核版本到 5.10.12, 让我们小心地开始吧。

警告:强烈建议你在虚拟机里实验这个过程。基于虚拟机,你总能创建一个快照,然后轻松地从任何问题中回退出来。不要在产品机器上使用这种方式升级内核,除非你知道你在做什么。

下载内核

我们要做的第一件事是下载内核源码。在 https://www.kernel.org/找到你要下载的所需内核的源码。找到 源码之后,使用如下命令(我以 5.10.12 RC2 内核为例) 来下载源码文件:   https://www.kernel.org/

  1. wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.12.tar.xz
  2. ctrl+z 停止下载

安装需要的环境

为了编译内核,我们首先得安装一些需要的环境。这可以通过一个命令来完成:

  1. sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison
  2. 务必注意:你将需要至少 12 GB 的本地可用磁盘空间来完成内核的编译过程。因此你必须确保有足够的空间。
  3. 解压源码

  4. 在新下载的内核所在的文件夹下,使用该命令来解压内核:
    1. tar xvzf linux-5.10.12-rc2.tar.gz
    2. 使用命令 cd linux-5.10.12-rc2 进入新生成的文件夹。
    3. 配置内核

    4. 在正式编译内核之前,我们首先必须配置需要包含哪些模块。实际上,有一些非常简单的方式来配置。使用一个命令,你能拷贝当前内核的配置文件,然后使用可靠的 menuconfig 命令来做任何必要的更改。使用如下命令来完成:
    1. cp /boot/config-$(uname -r) .config
    2. 现在你有一个配置文件了,输入命令 make menuconfig。该命令将打开一个配置工具,它可以让你遍历每个可用模块,然后启用或者禁用你需要或者不需要的模块。
    3. 很有可能你会禁用掉内核中的一个重要部分,所以在 menuconfig 期间小心地一步步进行。如果你对某个选项不确定,不要去管它。或者更好的方法是使用我们拷贝的当前运行的内核的配置文件(因为我们知道它可以工作)。一旦你已经遍历了整个配置列表(它非常长),你就准备好开始编译了。
    4. 输入 make -j4 V=s (-j4 后面是线程数。第一次编译推荐用单线程)即可开始编译你要的内核了。
    5. make modules

      如:make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules

      直接make,不加任何参数,就是make all,包含make modules。

      make modules是单独编译模块,驱动被配置成M的都是modules,modules不会被编译进内核image,需要单独安装到rootfs。

    6. 编译和安装

    7. 现在是时候去实际地编译内核了。第一步是使用 make 命令去编译(多线程编译输入 make -j4 V=s (-j4 后面是线程数。第一次编译推荐用单线程)即可开始编译你要的内核了)。调用 make 命令有时候有很多问题。这些问题取决于你将升级的现有内核以及升级后的内核和编译的环境,因此你得预留大量的时间。
    8. 可以用如下的命令安装那些之前启用的模块:
      1. make modules_install或(不是管理员登陆用 sudo make modules_install)
      2. make modules_install

        是把编译好的模块拷贝到系统目录下(一般是/lib/modules/)。

        也可自己指定ko安装路径:

        make ARCH=arm64 modules_install INSTALL_MOD_PATH=yourpath

        如:make ARCH=arm64 modules_install INSTALL_MOD_PATH="modules_install_path"

         

        在交叉编译的情况下,需要将ko模块安装到rootfs。

      3. 这个命令将耗费一些时间,所以要么坐下来看着编译输出,或者去做些其他事(因为编译期间不需要你的输入)。可能的情况是,你想要去进行别的任务(除非你真的喜欢看着终端界面上飞舞而过的输出)。
      4. 现在我们使用这个命令来安装内核:
        1. sudo make install(不是管理员加sudo)
        2. 又一次,另一个将要耗费大量可观时间的命令。事实上,make install 命令将比 make modules_install 命令花费更多的时间。
        3. 启用内核作为引导

        4. 一旦 make install (make install (安装内核二进制映像, 生成并安装boot初始化文件系统映像文件))命令完成了,就是时候将内核启用来作为引导。使用这个命令来实现:
          1. sudo update-initramfs -c -k 5.10.12-rc2
          2. 当然,你需要将上述内核版本号替换成你编译完的。当命令执行完毕后,使用如下命令来更新 grub:
            1. sudo update-grub
            2. 现在你可以重启系统并且选择新安装的内核了。
            3. 你已经编译了一个 Linux 内核!它是一项耗费时间的活动;但是,最终你的 Linux 发行版将拥有一个定制的内核,同时你也将拥有一项被许多 Linux 管理员所倾向忽视的重要技能。
 
Reply Favorite View the author
All Replies
SamLukeYes
deepin
2021-02-03 05:39
#1

怕什么,直接实体机上啊,反正旧内核又不会被覆盖,出了问题选择旧内核启动就是了

Reply View the author
清怨
deepin
2021-02-03 05:47
#2

怕什么,就算不知道内核不会覆盖这一回事,那最起码每次的系统更新都会有备份的呀,你直接在启动时点恢复到xxxx年xx月xx日x午xx:xx不得了吗?

Reply View the author
caoayu
deepin
2021-02-03 06:10
#3

怕什么,timeshift一把梭

Reply View the author
随便逛逛
deepin
2021-02-03 06:15
#4

这是小浣熊部队又出现了吗...很久没看到了...

Reply View the author
lcw0268
deepin
2021-02-03 07:23
#5

楼主这样容易误导新手,单进程编译,那时间不是一般的长。

Reply View the author
Comments
kearney
2021-02-15 06:47
请教下大佬这个线程数在编译时设置为多少好一点呢? 我查多线程的最佳线程数的时候通常有两种说法: 1. cpu支持多少线程就设多少 2. 1的双倍
zerofancy
2021-02-04 01:31
啊,原来有多线程这回事,我当时在学校学操作系统的时候老师教的就是直接make……
zanyrain
deepin
2021-02-03 17:59
#6

make bindeb-pkg 它不香吗?

Reply View the author
1***[email protected]
deepin
2021-02-03 17:59
#7

这玩意能编译好几个小时

Reply View the author
Anysets
deepin
2021-02-03 21:38
#8
lcw0268

楼主这样容易误导新手,单进程编译,那时间不是一般的长。

是我没错了,上次编译内核忘了开多线程,编译了3个多小时,最后报了个错,当场心态就崩了哈哈哈哈哈

Reply View the author
Anysets
deepin
2021-02-03 21:41
#9
It has been deleted!
ca******[email protected]
deepin
2021-02-11 18:32
#10

这些编译命令不是问题,能做好配置才是硬道理

Reply View the author
kearney
deepin
2021-02-16 17:31
#11

emm,内核为什么选择kernel.org的呢??而不是deepin或者debian维护的内核呢??

Reply View the author