Linux 其实指的是核心。这个【核心(kernel)】是整个操作系统的最底层,他负责了整个硬件的驱动,以及提供各种系统所需的核心功能,包括防火墙机制、是否支持 LVM 或 Quota 等文件系统等等,这些都是核心所负责的。
要让计算机进行的工作,都必须要【核心有支持】才可以。
核心就是系统上面的一个文件而已,这个文件包含了驱动主机各项硬件的侦测程序与驱动模块。
开机流程分析中,这个文件被读入主存储器的时机,当系统读完 BIOS并加载MBR内的开机管理程序后,就能够加载核心到内存当中。然后核心开始侦测硬件,挂载根目录并取得核心模块来驱动所有的硬件,之后呼叫 systemd 就能够依序启动所有系统所需要的服务。
核心文件通常被放置成 /boot/vmlinuz-xxx 。一部主机上面可以拥有多个核心文件,只是开机的时候仅能选择一个来加载而已。甚至我们也可以在一个distribution 上面放置多个核心,然后以这些核心来做成多重引导。
核心模块(kernel module)的用途
将一些不常用的类似驱动程序的东西独立出核心,编译成为模块,然后,核心可以在系统正常运作的过程当中加载这个模块到核心的支持。如此一来,在不需要更动核心的前提之下,只要编译出适当的核心模块,并且加载他,Linux就可以使用这个硬件啦。
模块放在 /lib/modules /$(uname -r)/kernel/ 当中。
自制核心–核心编译
核心其实是一个文件,是透过原始码(source code)编译而成的。
因为核心是直接被读入到主存储器当中的,所以当然要将他编译成为系统可以认识的数据才行。也就是说,必须要取得核心的原始码,然后利用 Tarball 安装方式提到的编译概念来达成核心的编译才行。
硬件的驱动程序可以编译成为核心模块,所以可以在不改变核心的前提下驱动你的新硬件。
所有目前核心有支持的东西都给他编译进去我的核心中,就可以支持目前所有的硬件与可执行的工作。
Linux核心特色,与默认核心对终端用户的角色
Linux 的核心有几个主要的特色,除了【Kernel可以随时、随各人喜好而更动】之外,Kernel 的【版本更动次数太频繁】也是一个特点。
一般的用户,由于系统已经将核心编译的相当的适合一般使用者使用了,因此一般入门的使用者,基本上,不太需要编译核心。
核心编译的可能目的
编译核心的时机可以归纳为几大类:
1.新功能的需求:
需要的新的功能只在新的核心里面才有,那么为了获得这个功能,只好来重新编译我的核心了。
2.原本核心太过臃肿:
如果对于系统【稳定性】很要求,对于核心多编译了很多莫名其妙的功能而不太喜欢的时候,那么就可以重新编译核心来取消掉该功能;
3.与硬件搭配的稳定性:
由于原本 Linux核心大多是针对Intel 的 CPU来作开发的,所以如果 CPU是 AMD的系统时,有可能会让系统跑得【不太稳】。此外,核心也可能没有正确的驱动新的硬件,此时就得重新编译核心来让系统取得正确的模块才好。
4.其他需求(如嵌入式系统):
需要特殊的环境需求时,就得自行设计核心。
基本上,依据 distributions 去挑选的核心原始码来源主要有:
1.原本distribution提供的核心原始码文件;
2.取得最新的稳定版核心原始码;
3.保留原本设定:利用patch升级核心原始码;
核心目录下的重要数据:
透过 /proc/cpuinfo
及 lspci
观察:
了解了硬件相关的数据后,还得要处理一下核心原始码底下的残留文件才行。
假设是第一次编译,但是不清楚到底下载下来的原始码当中有没有保留目标文件(*.o)
以及相关的配置文件存在,此时我们可以透过底下的方式来处理掉这些【编译过程的目标文件以及配置文件】:
cd /usr/src/kernels/linux-3.10.89/
make mrproper
这个动作会将以前进行过的核心功能选择文件也删除掉,所以几乎只有第一次执行核心编译前才进行这个动作,其余的时刻,想要删除前一次编译过程的残留数据,只要下达:
make clean
因为 make clean 仅会删除类似目标文件之类的编译过程产生的中间文件,而不会删除配置文件.
/boot/ 底下存在一个名为 config-xxxv的文件其实就是核心功能列表文件。
核心功能的挑选,最后会在 /usr/src/kernels/linux-3.10.89/ 底下产生一个名为.config 的隐藏档,这个文件就是 /boot/config-xxx 的文件。
可以透过非常多的方法来建立这个文件:
make menuconfig:
最常使用的,是文本模式底下可以显示类似图形接口的方式,不需要启动X Window就能够挑选核心功能选单;
make oldconfig:
透过使用已存在的 ./.config
文件内容,使用该文件内的设定值为默认值,只将新版本核心内的新功能选项列出让用户选择,可以简化核心功能的挑选过程;
make xconfig:
透过以Qt为图形接口基础功能的图形化接口显示,需要具有X window 的支持;
make gconfig
透过以 Gtk 为图形接口基础功能的图形化接口显示,需要具有 Xwindow 的支持。
make config:
最旧式的功能挑选方法,每个项目都以条列式一条一条的列出让你选择,如果设定错误只能够再次选择;
透过既有的设定来处理核心项目与功能的选择
以 CentOS7 的核心功能为底,然后来细部微调:
cp /boot/config-3.10.0-229.11.1.e17.x86_64 .config
make menuconfig 核心功能挑选选单示意图:
General setup
与Linux最相关的程序互动、核心版本说明、是否使用发展中程序代码等信息都在这里设定的。这里的项目主要都是针对核心与程序之间的相关性来设计的,基本上,保留默认值即可。
不要随便取消底下的任何一个项目,因为可能会造成某些程序无法被同时执行的困境。
loadable module + block layer
要让核心能够支持动态的核心模块,那么底下的第一个设定就得要启动才行。至于第二个 block layer 则预设是启动的,也可以进入该项目的细项设定,选择其中认为需要的功能即可。
CPU的类型与功能选择
进入【Processor type and features】后,挑选主机的实际CPU形式。
电源管理功能
如果选择了【Power management and ACPI options】之后,就会进入系统的电源管理机制中。其实电源管理机制还需要搭配主板以及CPU的相关省电功能,才能够实际达到省电的效率。
一些总线(bus)的选项
这个【Bus options (PCI etc.)】项目则与总线有关:分为最常见的 PCI 与 PCI-express 的支持,还有笔记本电脑常见的 PCMCIA插卡。要记住的是,那个PCIE 的界面务必要选取,不然新显示适配器可能会捉不到。
编译后执行档的格式
选择【Executable file formats / Emulations】底下的选项必须要勾选才行。因为是给Linux核心运作执行文件之用的数据。
核心的网络功能
这个【Networking support】项目是相当重要的选项,因为他还包含了防火墙相关的项目。由于防火墙是在启动网络之后再设定即可,所以绝大部分的内容都可以被编译成为模块,而且也建议编成模块,有用到再载入到核心即可。
各项装置的驱动程序
进入【Device Drivers】这个是所有硬件装置的驱动程序库。很多数据都与硬件有关。核心推出时的默认值是比较符合一般状态的,所以很多数据其实保留默认值就可以编的很不错了。
文件系统的支援
文件系统的支持也是很重要的一项核心功能。因为如果不支持某个文件系统,那么 Linux kernel 就无法认识,当然也就无法使用。
核心黑客、信息安全、密码应用
再接下来有个【Kernel hacking】的项目,那是与核心开发者比较有关的部分,这部分建议保留默认
值即可,应该不需要去修改他。除非想要进行核心方面的研究。然后底下有个【Security Options】,是属于信息安全方面的设定,包括 SELinux 这个细部权限强化模块也在这里编入核心的,这个部份只要记得 SELinux 作为默认值,且务必要将 NSA SELinux 编进核心即可,其他的细部请保留默认值。
另外还有【Cryptographic API】这个密码应用程序编程接口工具选项,以前的默认加密机制为MD5,近年来则改用了SHA 这种机制。不过, 反正预设已经将所有的加密机制编译进来了,所以也是可以保留默认值,都不需要额外修改就是了。
虚拟化与函式库
可以透过虚拟化技术在一部主机上面同时启动多个操作系统来运作,这就是所谓的虚拟化。
Linux核心已经主动的纳入虚拟化功能,而 Linux 认可的虚拟化使用的机制为 KVM (Kernel base VirtualMachine)。至于常用的核心函式库也可以全部编为模块。
核心与核心模块需要先编译起来,而编译的过程其实非常简单:
常见的在 /boot/ 底下的核心文件,都是经过压缩过的核心文件,因此,比较常用的是 modules与 bzImage这两个,其中 bzImage 第三个字母是英文大写的Ⅰ。 bzImage 可以制作出压缩过后的核心,也就是一般拿来进行系统开机的信息。所以,基本上会进行的动作是:
-j 4
:系统上面四个CPU 核心同时进行编译。
最后制作出来的数据是被放置在 /usr/src/kernels/linux-3.10.89/ 这个目录下,还没有被放到系统的相关路径中。
在上面的编译过程当中,如果有发生任何错误的话,很可能是由于核心项目的挑选选择的不好,可能需要重新以 make menuconfig 再次的检查一下相关设定。如果还是无法成功的话,那么或许将原本的核心数据内的 .config 文件,复制到核心原始文件目录下,然后据以修改,应该就可以顺利的编译出你的核心了。
最后注意到,下达了make bzImage后,最终的结果应该会像这样:
可以发现核心已经编译好而且放置在 /usr/src/kernels/linux-3.10.89/arch/x86/boot/bzImage 里面了~这个就是核心文件。
安装模块前有个地方得要知道模块是放置到 /lib/modules/$(uname -r) 目录下的,那如果同一个版本的模块被反复编译后来安装时,会产生冲突。
有两个解决方法:
1.先将旧的模块目录更名,然后才安装核心模块到目标目录去;
2.在 make menuconfig 时,那个 General setup 内的 Local version 修改成新的名称。
核心文件放置在 /usr/src/kernels/linux-3.10.89/arch/x86/boot/bzImage ,但是其实系统核心理论上都是摆在 /boot 底下,且为 vmlinuz开头的档名。
一部主机是可以做成多重引导系统的。
与 grub1 不一样,grub2 建议不要直接修改配置文件,而是透过让系统自动侦测来处理 grub.efg 这个配置文件的内容。所以,在处理核心文件时,可能就得要知道核心文件的命名规则比较好。
移动核心到/boot且保留旧核心文件
保留旧核心最大的好处是可以确保系统能够顺利开机。因为核心虽然被编译成功了但是并不保证刚刚挑选的核心项目完全适合于目前这部主机系统,可能有某些地方我们忘记选择了,这将导致新核心无法顺利驱动整个主机系统,更差的情况是,主机无法成功开机成功。此时,如果保留旧的核心,若新核心测试不通过,就用旧核心来启动。
核心文件通常以vmlinuz为开头,接上核心版本为依据的档名格式,因此可以这样做看看:
建立相对应的Initial Ram Disk (initrd)
由于的系统使用SATA磁盘,加上刚刚 SATA 磁盘支持的功能并没有直接编译到核心去,所以要使用initramfs 来加载才行。
使用如下的方法来建立 initramfs:
dracut -v /boot linitramfs-3.10.89vbird.img 3.10.89vbird
编辑开机选单(grub)
得要依据核心版本来处理档名,接下来就直接使用 grub2-mkconfig 来处理 grub2开机选单设定即可:
grub2-mkconfig -o /boot/grub2/grub.cfg
因为预设较新版本的核心会放在最前面成为默认的开机选单项目,所以得要确认上述的结果中,一个被发现的核心为你刚刚编译好的核心文件才对。否则等一下开机可能就会出现使用旧核心机的问题。
重新以新核心开机、测试、修改
如果上述的动作都成功后,接下来就是重新启动并选择新核心来启动系统。如果系统顺利启动之后,使用uname -a
会出现类似底下的数据:
核心所支持的功能当中,有直接编译到核心内部的,也有使用外挂模块的,外挂模块可以简单的想成就是驱动程序。些核心模块依据不同的版本,被分别放置到 /lib/modules/$(uname -r)/kernel/ 目录中,各个硬件的驱动程序则是放置到/lib/modules/$(uname -r)/kernel/drivers/当中。
由于核心原本就有提供很多的核心工具给硬件开发商来使用,而硬件开发商也需要针对核心所提供的功能来设计他们的驱动程序模块,因此,如果想要自行使用硬件开发商所提供的模块来进行编译时,就需要使用到核心所提供的原始档当中,所谓的头文件案(header include file)来取得驱动模块所需要的一些函式库或标头的定义。
因此如果想要自行编译核心模块时,就得要拥有核心原始码。
核心原始码可能放置在/usr/src/底下,早期的核心原始码被要求一定要放置到/usr/src/linux/目录下,不过,如果有多个核心在一个Linux系统当中,而且使用的原始码并不相同时,。。。
所以,在 2.6版以后,核心以 /lib/modules/S(uname -r)/build 及 /lib/modules/$(uname -r)/source 这两个连结档来指向正确的核心原始码放置目录。
由于核心模块的编译其实与核心原本的原始码有点关系的,因此如果需要重新编译模块时,除了make, gcc 等主要的编译软件工具外,还需要的就是 kernel-devel 这个软件
如果想要在预设的核心底下新增模块的话,那么就得要找到 kernel 的 SRPM 文件了,将该文件给他安装,并且取得source code 后,才能够顺利的编译。
很多时候,可能由于核心默认的核心驱动模块所提供的功能不满意,或者是硬件开发商所提供的核心模块具有更强大的功能,又或者该硬件是新的,所以预设的核心并没有该硬件的驱动模块时,只好自行由硬件开发商处取得驱动模块,然后自行编译。
如果硬件开发商有提供驱动程序的话,那么真的很好解决,直接下载该原始码,重新编译,将他放置到核心模块该放置的地方后就能够使用了。
当自行编译模块时,若核心有更新(例如利用自动更新机制进行在线更新)时,则须要重新编译该模块一次。
利用旧有的核心原始码进行编译
如果发现忘记加入某个模块功能了,仅是重新编译模块的话,先到目前的核心原始码所在目录下达 make menuconfig ,然后将 NTFS 的选项设定成为模块,之后直接下达:
make fs/ntfs/
那么 ntfs 的模块(ntfs.ko)就会自动的被编译出来了。然后将该模块复制到 /lib/modules/3.10.89vbird/kernel/fs/ntsf/ 目录下,再执行 depmod -a
,就可以在原来的核心底下新增某个想要加入的模块功能。
《鸟哥的Linux私房菜-基础篇》学习笔记
基础篇就到这儿了,大部分都是书上摘抄过来,过了一遍书,感觉有点用,但没什么用,但多少能对 Linux 有一定的了解。。。。。