Linux核心编译 与 管理

本文详细介绍了Linux内核定制的过程,包括核心功能的选择、模块化驱动程序的编译,以及如何实现系统级别的功能扩展。通过具体实例展示了如何通过编译内核源码来满足特定硬件需求,以及如何将驱动程序编译为模块,从而在不更新整个内核的情况下增加新功能。此外,文章还介绍了如何管理核心模块,包括安装、卸载以及与核心的兼容性问题。最后,文章强调了内核编译的重要性及其可能的目的,旨在提高系统性能、硬件兼容性和功能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

核心【kernel】

核心是整个操作系统的最底层,他负责了整个硬件的驱动,以及提供各种系统所需要的核心功能,包括防火墙机制、是否支持 LVM 戒 Quota 等文件系统等等,

MBR内的loader加载核心档案来驱动整个系统的硬件,也就是说如果你的核心不认识某个最新的硬件,那么该硬件也就无法被驱动,你当然也就无法使用该硬件

你所希望计算机帮你达成的各项工作,都需要透过【核心】的帮助才行,当然,如果你想要达成的工作是核心所没有提供的

那么自然就没有办法透过核心来控制计算机使他工作

举例,如果你想要某个网络功能(例如核心防火墙机制),但是你的核心偏偏忘记加进去这项功能,无论你如何设定该网络套件,都没用,也就是说你想要让计算机进行

的工作,都必须要【核心有支持】才可以,这个标准在Windows或Linux这几个操作系统上都相同,如果有一个全新的硬件,目前核心不支持,无论你用什么系统,这个硬件

都没有用的,此时就需要来编译核心

核心其实就是系统上面的一个档案而已,这个档案包括驱动主机各个硬件的侦测程序与驱动模块,这个核心通常放置在/boot/vmlinuz

不过也不见得, 因为一部主机上面可以拥有多个核心档案,只是开机的时候仅能选择一个来加载而已。 甚至我们也可以在一个 distribution 上面放置多个核心,然后以这些核心来做成

多重引导

核心模块 (kernel module) 的用途

核心档案包含了硬件侦测与驱动模块,现在硬件更新的速度太快,我们的核心比较旧,但是我换了新的硬件,这个核心无法支持,此时我们的Linux很早之前就开始

使用所谓的模块化设定了,亦即将一些不常用的类似驱动程序的咚咚独立出核心,编译成为模块,然后,核心可以在系统正常运作的过程中加载

这个模块到核心的支持,这样以来,我在不需要更新核心的前提下,只要编译出适当的核心模块,并且加载他,我的Linux就可以使用这个硬件啦

模块放在/lib/modules/$(uname -r)/kernel/ 

自制核心 - 核心编译

核心其实是一个档案,那么这个档案是透过原始码编译而成的,因为核心是直接被读入到主存储器当中的,所以当然要将他编译

成为系统可以认识的数据才行,我们必须要得到核心的原始码,Tarball安装方式提到的编译概念来达成核心的编译才行

关于驱动程序

硬件的驱动程序可以被编译成为核心模块,所以在不改变核心的前提下驱动你的新硬件

除了BIOS之外,核心是操作系统中最早被加载到内存的咚咚,他包含了所有可以让硬件与软件工作的信息,

核心的编译重点在于【你想要你的LInux做些什么】,如果没有必要的工作,就干脆不要加在你的核心当中,这样才能让你的Linux跑得更稳,更顺畅

这也是为什么我们要编译核心的最主要原因了

核心编译的可能目的

新功能的需求:  原本核心太过臃肿:  与硬件搭配的稳定性:  其他需求 (如嵌入式系统):

核心的版本,http://www.kernel.org 下载最新的 2.6.xx 版本的核心来尝试编译

核心原始码的取得方式:

既然核心是个档案,要制作这个档案给系统使用则需要编译,既然要有编译,当然就要有原始吗,原始吗可以通过你的distributions去

挑选的核心原始吗主要有

原本distribution提供的核心原始码档案

事实上,各主要distributions在推出他们的产品时,其实都已经附上了核心原始吗了,可以去网上下载相关的核心SRPM的档案

由于CentOS一直在进行更新的动作,因此你也可以在update的目录下找到核心原始吗

取得最新的稳定版核心原始码

虽然使用distribution释出的核心source code来重新编译比较方便,但是,新硬件所需要的新驱动程序,也就无法籍由原本

的核心原始吗来编译,所以,如果想要更新驱动程序的立场来看,当然使用最新的核心可能会比较好

保留原本设定:利用 patch 升级核心原始码

其实每一次核心释出时,除了释出完整的核心压缩文件之外,也会释出【该版本与前一版本的差异性 patch 档案】

万一你想要由 2.6.27 升级到 2.6.30 的话,那么你就要下载patch-2.6.28, patch-2.6.29, patch-2.6.30 等档案,一一升级

核心原始码的解压缩/安装/观察

tar -jxvf linux-2.6.30.3.tar.bz2 -C /usr/src/kernels 解压缩核心原始吗的压缩包

核心原始吗下的此目录

在上述核心目录下含有哪些重要数据?

arch,block,crypto,Documentation,drivers等等的目录,可以去Documentation那个目录去瞧瞧正确的说明,对你的核心编译会更有帮助的

核心编译的前处理与核心功能选择

核心的目的在管理硬件与提供系统核心功能,因此你必须要先找到你的系统硬件,并且规划你的主机未来的任务

这样才能编译出适合你这部主机的核心,所以整个核心编译的重要工作就是在【挑选你想要的功能】

硬件环境检规与核心功能要求

透过 /proc/cpuinfo 及 lspci 观察

CPU:AMD 的 Athlon64 3000+ (旧式,不含虚拟化功能)

主板芯片组: ALi M1689 K8 北桥 及 M5249, M1563 南桥芯片 (较冷门的硬件)

显示适配器: AGP 8X 的 NVidia GeForce 6600LE

内存: 2.0GB 内存

硬盘: WD 2.5GB 硬盘,使用 ALi, ULi 5289 SATA 接口

电源控制器: ALi M7101 Power Management Controller (PMU)

网络卡: 3Com 3c905C-TX/TX-M (对外)

网络卡: Realtek Semiconductor RTL-8139/8139C/8139C+

透过这部主机,系统未来可以透过虚拟化功能来处理虚拟机,这部主机未来需要开启防火墙,www服务器功能,

FTP服务器功能,基本上,用途就是一部小型的服务器环境,大致需要这样的功能

保持干净原始码: make mrproper,这个命令用来去除掉那些编译过程的目标档案以及配置文件

这个动作会将你以前进行过的核心功能选择档案也删除掉,所以几乎只有第一次执行核心编译前才进行这个动作

其余的时刻,你想要删除前一次编译过程的残留数据,下达make clean,make clean 仅会删除类似目标文件之类的编译过程产生的中间档案,而

不会删除配置文件,既然我们是第一次进行编译,因此,请下达『make mrproper』

开始挑选核心功能: make XXconfig

 /boot/ 底下存在一个名为 config-xxx 的档案,那个档案其实就是核心功能列表文件,接下来的动作就是作出该档案

后面进行的编译动作,其实也就是透过这个档案来处理的,核心功能的挑选,最后会在/usr/src/kernels/linux-2.6.30.3/ 底下产生一个名为 .config 的隐藏档

这个档案就是 /boot/config-xxx 的档案啦,这个档案的建立可以有非常多的方法来建立这个档案

make menuconfig 最常使用的,是文本模式底下可以显示类似图形化接口的方式,

make oldconfig 透过使用已存在的./.config档案内容,使用该档案内的设定值为默认值,只将新版本核心内的新功能选项列出来让用户选择

可以简化功能的挑选过程,对于作为升级核心原始吗后的功能挑选来说,非常好用

make xconfig 透过以Qt为图形接口基础功能的图形化接口显示,需要具有X window的支持,例如KDE就是透过

Qt来设计X window,因此如果在KDE画面中,可以使用此选项

make gconfig 透过Gtk为图形化接口基础功能的图形化接口显示,需要有X window的支持,例如GNOME就是透过

Gtk来设计的X window,因此如果在GNOME画面中,可以使用此项

make config 最旧式的功能挑选方法,每个项目都以一条一条的列出让你选择,如果设定错误只能够再次选择,很不人性化

make menuconfig比较常用,如果是升级原始吗并且需要重新编译,那么使用make oldconfig会比较合适

执行make menuconfig会出现画面

基本上只要有上下左右的箭头,空格键,Enter键这六个按键,

『肯定』核心一定要的功能,直接编译进核心内;

『可能在未来会用到』的功能,那么尽量编译成为模块;

『不知道那个东西要干嘛的,看 help 也看不懂』的话,那么就保留默认值,或者将他编译成为模块;

各项内容包括:

General setup 与 Linux 最相关的程序互动、核心版本说明,这里的项目主要都是针对核心与程序之间的相关性来设计的,基本上保留默认值

loadable module + block layer 要让你的核心能够支持动态的核心模块,那么底下的第一个设定就要启动才行,至于第二个block layer则预设是启动的,也可以设定细部设定

CPU 的类型不功能选择  进入『Processor type and features』后,请挑选你主机的实际CPU形式

电源管理功能  如果选择了『Power management and ACPI options』之后,就会进入系统的电源管理机制中,其实电源管理机制还需要搭配主板与cpu的相关省电功能

才能达到省电的效率

一些总线 (bus) 的选项,这个项目与总线有关,分为最常见的PCI与PCI-express的支持,还有笔记本电脑常见的PCMCIA插卡

编译后执行档的格式  选择『Executable file formats / Emulations』会见到如下选项,底下的选项必须要勾选才行,是给Linux核心运作执行文件之用的数据,与编译行为有关

核心的网络功能

这个『Networking support』项目是相当重要的选项,它还包含了防火墙相关的设定,iptables设定,由于防火墙是在启动网络之后再设定,所以绝大部分的内容都可以被编译

成为模块,而且建议你编译成为模块,有用到时再载入到核心即可

各项装置的驱动程序  进入『Device Drivers』这个是所有硬件装置的驱动程序库,这里面的数据就与你主机的硬件有绝对的关系,

底下则与 Firmware Drivers 有关!基本上,都保留默认值就好了!

文件系统的支援  文件系统的支持也是很重要的一项核心功能,如果不支持某个文件系统,那么我们的Linux Kernel就无法认识,当然也就无法使用,例如Quota,NTFS等等

特殊的filesystem

核心黑客、信息安全、密码应用  再接下来有个『Kernel hacking』的项目 ,那是与核心开发者比较有关的部分,这部分建议保留默认值即可,

虚拟化与凼式库 虚拟化是非常热门的一个议题,因为计算机能力太强,所以时常闲置在那边,此时,可以透过虚拟化技术在一部主机上面同时启动多个操作系统来运作,

这就是所谓的虚拟化,Linux核心已经主动的纳入虚拟化功能,而Linux认可的虚拟化使用的机制位KVM,至于常用的核心函式库也可以全部编译成模块

最后,还有底下这两个项目,这两个项目与核心功能无关,但是与挑选时的配置文件案有关:

刚刚所做的设定离开时选择SAVE,那么这些项目通通会记录到目前这个目录下的.config档案内,也可以使用Save Configuration 项目来将刚刚做完的设定储存成另外的档案

在下次在其他版本的核心作选择时,直接以Load来将这个档案的设定项目读入

核心的编译与安装

之前将最复杂的核心功能选择完毕后,接下来就是进行这些核心,核心模块的编译了,编译完成后,当然要使用,如果使用新核心,就要考虑grub这个咚咚

编译核心与核心模块

make vmlinux <==未经压缩的核心

make modules <==仅核心模块

make bzImage <==经压缩过的核心(预设)

make all <==进行上述的三个劢作

我们常见的在/boot/底下的核心档案,是经过压缩后的核心档案, bzImage可以制作出压缩过的核心,也就是一般我们拿来进行系统开机的信息,

基本上我们会进行的动作是:

make clean <==先清除暂存档

make bzImage <==先编译核心

make modules <==再编译模块

最后制作出来的数据是被放置在/usr/src/kernels/linux-2.6.30.3/ 这个目彔下,还没有被放到系统的相关路径中,

可以发现你的核心已经编译好而且放置在 /usr/src/kernels/linux-2.6.30.3/arch/x86/boot/bzImage 里面~那个就是我们的核心档案

最重要就是他啦!我们等一下就会安装到这个档案,然后就是编译模块的部分~ make modules 进行完毕后,就等着安装啦

实际安装模块

我们知道模块是放置到 /lib/modules/$(uname -r) 目彔下的,那如果同一个版本的模块被反复编译后来安装,会不会产生冲突,第一次编译完成且安装妥当后,发现有个小细节

想要重新处理,因此又要重新编译,那两个版本一模一样,模块放置的目录会一样,此时会产生冲突了

解决方法:

先将旧的模块目彔更名,然后才安装核心模块到目标目彔去;

在 make menuconfig 时,那个 General setup 内的 Local version 修改成新的名称。建讧使用这个方式

模块处理妥当后,准备进行核心的安装了

开始安装新核心与多重核心选单 (grub)

现在我们知道核心档案放置在 /usr/src/kernels/linux-2.6.30.3/arch/x86/boot/bzImage,但是其实系统核心理论上是摆在/boot底下,且为vmlinuz开头的档名,此外

我们也晓得一部主机是可以做成多重引导系统的,我们将同时保留旧版的核心,并且新增新版的核心在我们的主机上面

移动核心到 /boot 且保留旧核心档案

保留旧核心的好处是,确保系统能够顺利开机,新版的核心虽然编译成功了,但是不保证我们刚刚挑选的核心项目完全适合于目前这部主机系统,导致主机无法开机成功

而保留了旧的核心,若新核心测试不通过,就用旧核心来启动,新核心可以这样:

cp /usr/src/kernels/linux-2.6.30.3/arch/x86/boot/bzImage  /boot/vmlinuz-2.6.30.3vbird <==实际核心

cp /usr/src/kernels/linux-2.6.30.3/.config  /boot/config-2.6.30.3vbird <==建讧配置文件也复制备份

建立相对应的 Initial Ram Disk (initrd),由于系统使用SATA磁盘,加上刚刚SATA磁盘支持的功能并没有直接编译到核心去,所以当然要使用initrd来加载才行,使用如下的

方法建立initrd

mkinitrd -v /boot/initrd-2.6.30.3vbird.img 2.6.30.3vbird

编辑开机选单 (grub)

vim /boot/grub/menu.lst

default=0
timeout=10
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
#hiddenmenu
title CentOS (2.6.18-128.2.1.el5xen)
root (hd0,0)
kernel /boot/xen.gz-2.6.18-128.2.1.el5
module /boot/vmlinuz-2.6.18-128.2.1.el5xen ro root=LABEL=/ rhgb
quiet
module /boot/initrd-2.6.18-128.2.1.el5xen.img
title CentOS testing kernel from vbird
root (hd0,0)
kernel /boot/vmlinuz-2.6.30.3vbird ro root=LABEL=/ rhgb
initrd /boot/initrd-2.6.30.3vbird.img

新曾上述的特殊字体到你的配置文件中,另外, 你会发现上头的default并没有修改到你最新的那个核心选单上,因为要先测试新核心是否能顺利开机

额外(单一)核心模块编译

现在的核心所支持的功能当中,有直接编译到核心内部的,也有使用外挂模块的,外挂模块可以简单的想成是驱动程序,模块放置在/lib/modules/$(uname -r)/kernel/ 目彔中

各个硬件的驱动程序则是放置到/lib/modules/$(uname -r)/kernel/drivers/,换个角度,如果刚刚自己编译的数据中,有些驱动程序忘记编译成为模块了,那是否需要重新进行

上述的动作,又或者想要使用硬件厂商释出的新驱动程序,那该如何,此时需要利用核心原始吗来自行编译出核心模块

那核心原始码我们知道他是可能放置在 /usr/src/ 底下,早期的核心原始吗被要求一定要放置到 /usr/src/linux/ 目彔下,不过,如果你有多个核心在一个Linux系统当中,而且使用

的原始吗不相同,在2.6版之后,核心使用比较有趣的方法来设计他的原始吗放置目录,那就是 /lib/modules/$(uname -r)/build 及 /lib/modules/$(uname -r)/source 这两个链接

档来指向正确的核心原始吗放置目录,如果我们刚刚由kernel 2.6.30.3 建立的核心模块来说,那么他的核心模块目彔底下有什么咚咚

比较有趣的除了那两个连接档之外,还有那个modules.dep档案,这个档案记录了核心模块的相依属性的地方,依据该档案我们可以使用modprobe这个指令来加载模块,至于

核心原始吗提供的头文件,上面的案例当中,则是放置到/usr/src/kernels/linux-2.6.30.3/include/ 目录中,当然就是籍由build/source这两个链接档来取得目录所在的

由于核心模块的编译其实与核心原本的原始吗有点关系,因此需要重新编译模块时,除了make gcc等主要的编译软件工具,还要有kernel-devel这个软件,记得一定要安装

而如果想要在预设的核心底下新增模块的话,那么就要找到kernel的SRPM档案了,该档案给他安装,并且取得source code,才能够顺利的编译

单一模块编译

两个情况,我的默认核心忘记加入某个功能,而且该功能可以编译成为模块,不过预设核心也没有将该项编译成为模块,结果该功能不能使用

                    如果Linux核心原始吗没有某个硬件的驱动程序,但开发该硬件的厂商有提供给Linux使用的驱动程序原始吗,那么该如何将该功能编译进核心模块

其实就是取得原始吗后,重新编译成为可以加载的模块,不过,需要有make gcc以及核心所提供的include头问家与函式库

如果开发商有提供该硬件的驱动程序,那么直接下载原始吗,重新编译,将它放置到核心模块该放置的地方后就能够使用了

下载后去读一读INSTALL/README,然后找一个makefile,就能够编译了

# 1. 将档案解压缩:

cd /usr/local/src

ar -jxvf /root/r8168-8.013.00.tar.bz2

cd r8168-8.013.00/

# 2. 开始进行编译与安装:

make clean modules

ll src/*.ko <==建立底下的模块文件!

make install

4. 更新模块相依属性!

depmod -a

这样就可以将模块编译起来,并且还可以将他直接放置到核心模块目录中,同时以depmod将模块建立

相关性,未来就能够利用modprobe来直接取用,但是当自行编译模块时,若你的核心有更新,则你必须要重新编译该模块一次

重复上面的步骤,因为这个模块仅针对目前的核心来编译的

利用旧有的核心原始码进行编译

如果后来你忘记加入某个模块功能了,我们先到目前的核心原始吗所在目录下达make menuconfig,然后将ntfs的选项设定成为模块

直接下达 make fs/ntfs/

那么ntfs的模块(ntfs.ko)就会自动的被编译出来,然后将该模块复制到/lib/modules/2.6.30.3vbird/kernel/fs/ntsf/ 目彔下,再执行depmod -a,就可以在原来

的核心底下新增某个想要加入的模块功能

核心模块管理

核心与核心模块是分不开的,至于驱动程序模块在编译的时候,更是与核心的原始吗功能分不开,因此,你必须要了解到:核心,核心模块,驱动程序模块,核心原始吗与

头文件案的相关性,然后才有办法了解到为何编译驱动程序的时候老是需要找到核心的原始吗才能够顺利编译,然后也才会知道,为何当核心更新之后,自己之前所编译的

核心模块会失效

此外,与核心模块有相关的,还有那个常被使用的modprobe指令,以及开机的时候会读取到的模块定义数据文件/etc/modprobe.conf




























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值