Linux编译内核步骤

内核的安装可以轻易地通过像 apt 这样的包管理器来处理。通过添加特定的仓库,你能很轻易地安装实验版本的或者指定版本的内核(比如针对音频产品的实时内核)。apt安装的内核是发行版并且是已经编译好的?这里下载的不是发行版并且是源码?是这样吗?求大佬告知。

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

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

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

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

一、下载linux内核源码到/usr/src/

1.下载最新版本的内核

进入 Linux 内核官网 https://www.kernel.org/ 下载 Linux 内核 , 点击右侧 黄色的 " Latest Release "

在这里插入图片描述

在这里插入图片描述

按钮 , 下载最新的 Linux 内核发布版本 ;

在这里插入图片描述

最新版的 Linux 内核有 122MB ;

在这里插入图片描述

2.下载指定版本的内核

目标 : 下载5.6.14版本的 Linux 内核 ;

  • 主版本号 :5
  • 此版本号 :6
  • 小版本号 ( 修改次数 ) :14

在 Linux 内核 官网 https://www.kernel.org/ 页面中 , 点击 https://www.kernel.org/pub/ 链接 ,

在这里插入图片描述

进入 Linux 内核 public 页面 , 进入 https://mirrors.edge.kernel.org/pub/ 页面 ,

在这里插入图片描述

点击 linux 目录 , 进入 https://mirrors.edge.kernel.org/pub/linux/ 页面 ,

在这里插入图片描述

点击 kernel 链接 , 进入 https://mirrors.edge.kernel.org/pub/linux/kernel/ 页面 ,

在这里插入图片描述

选择 v5.x 版本 , 进入 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/ 页面 , 在该界面中可以直接下载 linux-5.6.14.tar.gz 文件 , 这就是5.6.14版本 Linux 内核源码 ;

在这里插入图片描述

3.git获取

从Git仓库克隆是一种更灵活更高效的方法,适合于想要获取新版本或历史的Linux内核源码,并且可以跟踪更新和修改的用户。具体操作如下:

1. 打开终端,切换到你想要存放Linux内核源代码的目录下,例如/usr/src/。

2. 输入以下命令,从Git仓库克隆Linux内核源代码:

3. git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

4. 克隆完成后,你就可以在该目录下看到一个名为linux的文件夹,这就是Linux内核源代码的根目录。

5. 切换到某个特定版本的Linux内核源码,输入该命令,查看所有可用的标签(tag):git tag

6. 切换到你想要的标签,例如v5.15.7:git checkout v5.15.7

7. 跟踪新的更新和修改,输入该命令,切换到主分支(master):git checkout master

8. 拉取新的提交(commit):git pull。

4.Linux内核版本号的含义

5.6.14版本为例 :

  • 主版本号 :5
  • 次版本号 :6
  • 小版本号 ( 修改次数 ) :14

版本稳定性 :

  • 稳定版本 : 次版本号为偶数 , 说明该版本的 Linux 内核是可以使用的稳定版本 ,
  • 不稳定版本 : 如果次版本号为奇数 , 说明在该版本中 , 添加了新的模块 , 不能保证稳定性 , 如

5.7.14就是不稳定版本 。

5.查看当前使用的内核版本

① 使用uname命令是一种简单快捷的方法,适合于想要快速查看当前运行中的Linux内核版本的用户。具体操作如下:

打开终端,输入以下命令,查看当前运行中的Linux内核版本:

uname -r

输出结果类似于以下内容:

5.15.7-200.fc35.x86_64

当前运行的Linux内核版本是5.15.7,编译配置为200.fc35.x86_64。不同的发行版可能有不同的配置和后缀,但是前面的数字部分是通用的,表示Linux内核的主版本号、次版本号和修订号。

② 查看/proc/version文件是一种更详细更完整的方法,适合于想要查看当前运行中的Linux内核版本以及编译信息的用户。具体操作如下:

打开终端,输入以下Linux常用命令,查看/proc/version文件的内容:

cat /proc/version

输出结果类似于以下内容:

Linux version 5.15.7-200.fc35.x86_64 (mockbuild@bkernel01.iad2.fedoraproject.org) (gcc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1), GNU ld version 2.37-10.fc35) #1 SMP Wed Dec 8 14:29:02 UTC 2021

表示当前运行中的Linux内核版本是5.15.7,编译配置200.fc35.x86_64,编译器gcc 11.2.1,链接器GNU ld 2.37,编译时间2021年12月8日14:29:02。

③dmesg(dmesg | grep "Linux version")命令

6.解压源码到/usr/src/中

在新下载的内核所在的文件夹下,使用该命令来解压内核:

tar xvzf linux-4.17-rc2.tar.gz -C /usr/src

使用命令 cd linux-4.17-rc2 进入新生成的文件夹。

Re:【Linux 内核】编译 Linux 内核 ① ( 下载指定版本的 Linux 内核源码 | Linux 内核版本号含义 | 主版本号 | 次版本号 | 小版本号 | 稳定版本 )-腾讯云开发者社区-腾讯云

二、安装所需要的环境

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

sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison

三、配置内核代码

在编译内核之前,我们可以对内核源代码进行配置。配置的目的主要是确定哪些模块会编译到内核当中。

①进入源代码目录

cd linux-5.9.6 

②从当前机器的启动目录拷贝配置信息到源代码目录。这步操作的意思是我们编译内核的配置采用用当前环境一致的配置。

cp -v /boot/config-$(uname -r) .config 

 然后执行./.config,

也可以选择最快的原版的配置(默认)方式

        root@shana:/usr/src/linux-source-2.6.22# make oldconfig

③也可以通过如下命令启动配置界面

make menuconfig 

该命令将打开一个配置工具(图 1),它可以让你遍历每个可用模块,然后启用或者禁用你需要或者不需要的模块。下面是打开的配置界面。可以看出里面包含所有的内核组件,包括文件系统,网络,IO栈,虚拟化和设备驱动等等。如果你不熟悉,可以不做任何修改。

很有可能你会禁用掉内核中的一个重要部分,所以在 menuconfig 期间小心地一步步进行。如果你对某个选项不确定,不要去管它。或者更好的方法是使用我们拷贝的当前运行的内核的配置文件(因为我们知道它可以工作)。一旦你已经遍历了整个配置列表(它非常长),你就准备好开始编译了。 

四、编译和安装内核

①通过如下命令就可以编译内核了

make
make -j 10

上面参数是并发数量,通常可以是CPU核心数的2倍。好像容易出问题。

②安装那些之前启用的模块

sudo make modules_install 

执行结束之后,会在/lib/modules下生成新的目录/lib/modules/2.6.32.10-generic/,其中的build就是内核树。在以后编译模块时要用到。

③安装内核

sudo make install

④启用内核作为引导

一旦 make install 命令完成了,就是时候将内核启用来作为引导。使用这个命令来实现:

sudo update-initramfs -c -k 4.17-rc2

当然,你需要将上述内核版本号替换成你编译完的。当命令执行完毕后,使用如下命令来更新 grub:

sudo update-grub

现在你可以重启系统并且选择新安装的内核了。

注:一下两个链接是如何切换内核的方法,没有试过。可以试试告诉我哪个好用。

ubuntu如何进行切换内核版本全教程_ubuntu切换内核版本-CSDN博客

编译运行Linux内核(切换Linux内核版本) - 知乎

Re:Linux内核编译很简单,6步编译一个自己的内核-linux内核编译方法 

如何编译 Linux 内核 - 知乎

五、编译2.6.32.10内核源码时遇到的一些问题

1.error: code model kernel does not support PIC mode

这是由于不支持地址无关模式,在 Makefile这段的最后加上-fno-pie即可

 344 KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
 345                    -fno-strict-aliasing -fno-common \
 346                    -Werror-implicit-function-declaration \
 347                    -Wno-format-security \
 348                    -fno-delete-null-pointer-checks -fno-pie

或者调查后发现删除删除该模块目录下的.cache.mk文件就好了,重新make即可

2.fatal error: linux/compiler-gcc7.h: No such file or directory

原因: Linux2.6属于老版本内核, 与新版gcc不适配, 直接原因是没有这个文件,只有gcc4和gcc3,于是另外再安装gcc4, 注意无需卸载gcc7, 切换即可

linux下gcc、g++不同版本的安装和切换

①可以通过如下命令查看当前安装的版本:

ll /usr/bin/gcc*

②安装gcc4.8

sudo apt install gcc-4.8 gcc-4.8-multilib g++-4.8 g++-4.8-multilib

③使用update-alternatives设置gcc和g++:

update-alternatives是ubuntu系统中专门维护系统命令链接符的工具,通过它可以很方便的设置系统默认使用哪个命令、哪个软件版本。 其中405070是优先级数值可以自己设定,--slave能保证gcc和g++保持相同的版本。

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 50 --slave /usr/bin/g++ g++ /usr/bin/g++-7

④使用如下命令选择gcc的版本:

sudo update-alternatives --config gcc

可以看到当前gcc默认的版本是gcc-7,下面我们修改为gcc-4.8,直接选择编号即可。

$ sudo update-alternatives --config gcc
There are 3 choices for the alternative gcc (providing /usr/bin/gcc).

  Selection    Path              Priority   Status
------------------------------------------------------------
* 0            /usr/bin/gcc-7     70        auto mode
  1            /usr/bin/gcc-4.8   40        manual mode
  2            /usr/bin/gcc-5     50        manual mode
  3            /usr/bin/gcc-7     70        manual mode

Press <enter> to keep the current choice[*], or type selection number: 1
update-alternatives: using /usr/bin/gcc-4.8 to provide /usr/bin/gcc (gcc) in manual mode

⑤验证是否成功

gcc -v/g++ -v

⑥删除某个gcc版本

sudo update-alternatives --remove gcc /usr/bin/gcc-4.5

再使用apt-remove删除即可

Re:linux下gcc、g++不同版本的安装和切换-腾讯云开发者社区-腾讯云

3.安装gcc4.8时出现E:Package make has no installation candidate

ubuntu20.04的默认软件源没有这个gcc4.8的包,加入即可

则在/etc/apt/sources.list中添加以下两个源

deb http://dk.archive.ubuntu.com/ubuntu/ xenial main
deb http://dk.archive.ubuntu.com/ubuntu/ xenial universe

然后更新即可。

sudo apt-get update
sudo apt-get upgrade

Re:Ubuntu18安装gcc-4.8_ubuntu安装gcc4.8-CSDN博客

bash - GCC version 4.9 has no installation candidate - Stack Overflow

How to resolve the error : 'Package gcc-8 has no installation candidate' ? I'm trying to install it by sudo-apt install gcc-8 - Ask Ubuntu

4. gcc: error: elf_x86_64: No such file or directory

错误原因:
由于gcc 4.6不再支持linker-style架构。
解决办法:
将arch/x86/vdso/Makefile中,以VDSO——LDFLAGS_vso.lds开头所在行的“-m elf_x86_64”替换成“-m64”
将VDSO_LDFLAGS_vdso32.lds开头所在行的“-m elf_x86”替换成“-m32”。

确保当前路径是在内核目录中,然后执行命令:

vim usr/src/linux-2.6.32.10/arch/x86/vdso/Makefile

,在Makefile中搜索elf_x86_64,然后把"-m elf_x86_64"替换为"-m64";接着在Makefile中搜索elf_i386,然后把"-m elf_i386"替换为"-m32",保存退出,问题解决了。接着继续编译,就可以了。

Re:elf_i386或elf_x86_64:没有那个文件或目录 解决方法 | 说好一起走

5.make[1]: *** [kernel/timeconst.h] Error 255

根据提示将相应文件中的相应行的 defined()删除即可。

将kernel/timeconst.pl中第373行的defined()去掉只留下@val就可以了。

6.重复的成员'page'错误 

在编译Linux-2.6.33内核时,出现的了一个错误就是:重复的成员‘page’,这个是由于gcc的版本较高造成的。 

a、按照错误的指示,错误的代码是在drivers/net/igbvf/igbvf.h文件的第129行。

b、打开文件,看129行,代码为:struct page *page;再往上看,第124行,也有struct page *page;这行代码,这个结构定义在内部的一个结构体中。就是他的名字与129行的重复了,而4.6.3的编译器不支持这种方式的定义,我们修改129行的代码为struct page *pagep;保存退出。

Re:重复的成员'page'错误的解决方法 | 说好一起走

7.fatal error: linux/config.h: No such file or directory

進行內核模塊的編譯時,因為包含了#include <linux/config.h>,出現include的linux下沒有config.h這個文件錯誤提示:

fatal error: linux/config.h: No such file or directory

原因與解決方法:

現在較新的內核已經棄用了config.h,把這個文件新建上去即可。執行命令(注意路徑的不同):

$sudo vim /usr/src/linux-source-2.6.38/include/linux/config.h

輸入如下內容:

#ifndef _LINUX_CONFIG_H
#define _LINUX_CONFIG_H
#endif

保存後退出重新編譯,OK!

Re:Linux內核編譯錯誤fatal error: linux/config.h: No such file or_Linux內核

Re:https://www.cnblogs.com/QiQi-Robotics/p/15229668.html

Linux 编译内核问题汇总 | Lantern's 小站

六、加载内核模块时遇到的问题

1..c文件中有#include <linux/module.h>但编译时说找不到该文件

Ubuntu不自己带内核的源码的,需要你把内核源码下载解压到ur/src/里。

还有一种可能是找的头文件路径不对。

2.insmod: ERROR: could not insert module module.ko: Invalid parameters的几个原因

①insmod之后再次对该模块进行加载时会报错,这个主要是因为模块的printk打印的信息不能直接显示在终端上,可以使用 dmesg 查看自开机以来的信息就可以看到printk输出的信息了,使用dmesg | tail可以查看最后的几个消息。使用rmmod 可以移除安装了的模块。

②编译.ko时的内核版本与当前系统运行的内核版本不一致;编译模块时选择的Linux头文件目录与当前运行的系统版本不匹配,使用命令:uname -r查看当前运行的内核版本,然后选择正确的Linux头文件路径,也可以下载和机器内核对应的Linux源码,这样指定Linux头文件目录到指定的源码目录就行了。即修改.ko所在路径中的makefile的KERNELDIR为当前系统的内核版本的头文件路径,或者将当前系统内核切换为编译ko文件时使用的内核版本。

③生成的模块名字不能以module命名,改成其他名字就好了

3.ubuntu没有/var/log/messages系统日志文件

 在ubuntu系统中,有时候,我们需要通过journalctl -xe来查看服务启动日志,但是这个日志打印不全,所以还是需要通过/var/log/messages这个文件来看。

    在一些新的ubuntu系统中,这个文件是不存在的,我们需要设置,修改文件/etc/rsyslog.d/50-default.conf

    我们可以看到,为什么messages文件在/var/log目录下没有,因为被注释掉了,我们根据需要开启,或者新增一行配置即可:

*.info;mail.none;authpriv.none;cron.none        /var/log/messages

   保存该配置文件,然后无需重启系统,只需要重启rsyslog这个服务即可。

systemctl restart rsyslog.service

 我们最后来看看效果:

    ​ 

    最后成功开启了messages日志文件,我们也看到了系统日志。以后查看详细的日志都可以在这里面查看。 

Re:ubuntu系统没有/var/log/messages系统日志文件解决办法_ubuntu messages-CSDN博客

七、关于内核树

1.系统自带的内核树

有时,安装的系统已经自带了Linux内核树,足够用来编译驱动程序了。

自带的内核树通常位于

/lib/modules/<系统内核版本>/build

其中,系统内核版本可以用uname -r来查看

$ uname -r
5.11.0-41-generic

2.环境配置

 初次配置内核树要先安装一些必要的环境

sudo apt-get build-dep linux linux-image-$(uname -r)

如果报错Error :: You must put some ‘source‘ URIs in your sources.list,请参照这里

除了上面的环境之外,还要安装这

sudo apt-get install libncurses-dev gawk flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf dwarves

 3.构建内核和安装模块

为了防止make中的make modules_install环节失败, 请先运行下面的命令

sudo scripts/config --set-str SYSTEM_TRUSTED_KEYS ""

最后,把模块安装到/lib/modules/$(uname -r)目录(由内核的makefile指定路径)

Re:

【Linux内核树】五步构建_安装内核源码树以及编译-CSDN博客

https://www.cnblogs.com/oracleloyal/p/5382920.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值