24.8 参考资料与延伸阅读
最后更新于:2022-04-01 22:17:54
## 24.8 参考资料与延伸阅读
* [[1]](#ac1)通过在 /usr/src/kernels/linux-3.10.89 下面的 README 以及“ make help ”可以得到相当多的解释
* 核心编译的功能:可以用来测试 CPU 性能喔!因为 compile 非常耗系统资源!
2002/05/29:第一次完成
2003/02/11:重新编排与加入 FAQ
2004/06/11:原本的 2.4.xx 版本核心被移动到 [此处](http://linux.vbird.org/linux_basic/0540kernel/0540kernel-2.4.18.php)
2005/11/15:原本的模块管理已经先移动到[开机流程管理](../Text/index.html#kernel)那一篇啰!
2005/12/05:经过将近一个月,呵呵!终于给他整理出来这一篇了~真难得~
2007/06/27:增加了 initrd 的简单说明,详细还是得看 loader 那一章。
2009/07/21:将基于 FC4 所撰写的文章移动到[此处](http://linux.vbird.org/linux_basic/0540kernel/0540kernel-fc4.php)
2009/08/03:原本的 KDE/GNOME 使用的发动机写错了! KDE 用 Qt ,而 GNOME 是用 Gtk !非常感谢 Chua Tze An 兄提供的指正!
2009/09/18:加入两个简单的题目,给大家思考一下而已。
2015/09/23:将基于 CentOS 5 的旧的版本移动到[这里](http://linux.vbird.org/linux_basic/0540kernel/0540kernel-centos5.php)。
';
24.7 本章习题
最后更新于:2022-04-01 22:17:52
## 24.7 本章习题
( 要看答案请将鼠标移动到“答:”下面的空白处,按下左键圈选空白处即可察看)
* 简单说明核心编译的步骤为何?
1. 先下载核心源代码,可以从 http://www.kernel.org 或者是 distributions 的 SRPM 来着手;
2. 以下以 Tarball 来处理,解开源代码到 /usr/src/kernels 目录下;
3. 先进行旧数据删除的动作:“make mrproper”;
4. 开始挑选核心功能,可以利用“make menuconfig”、“make oldconfig”、“make gconfig”等等;
5. 清除过去的中间暂存盘数据:“make clean”
6. 开始核心文件与核心模块的编译:“make bzImage”、“make modules”
7. 开始核心模块的安装:“make modules_install”
8. 开始核心文件的安装,可以使用的方式有:“make install”或者是通过手动的方式复制核心文件到 /boot/ 当中;
9. 创建 initramfs 文件;
10. 使用 grub2-mkconfig 修改 /boot/grub2/grub.cfg 文件;
* 如果你利用新编译的核心来操作系统,发现系统并不稳定,你想要移除这个自行编译的核心该如何处理?
1. 重新开机,并使用旧的稳定的核心开机!
2. 此时才可以将新版核心模块删除: rm -rf /lib/modules/3.10.89vbird
3. 删除掉 /boot 里面的新核心: rm /boot/vmlinuz-3.10.89vbird /boot/initramfs-3.10.89vbird.img ...
4. 重建 grub.cfg: grub2-mkconfig -o /boot/grub2/grub.cfg
';
24.6 重点回顾
最后更新于:2022-04-01 22:17:50
## 24.6 重点回顾
* 其实核心就是系统上面的一个文件而已,这个文件包含了驱动主机各项硬件的侦测程序与驱动模块;
* 上述的核心模块放置于:/lib/modules/$(uname -r)/kernel/
* “驱动程序开发”的工作上面来说,应该是属于硬件发展厂商的问题
* 一般的使用者,由于系统已经将核心编译的相当的适合一般使用者使用了,因此一般入门的使用者,基本上,不太需要编译核心
* 编译核心的一般目的:新功能的需求、原本的核心太过臃肿、与硬件搭配的稳定性、其他需求(如嵌入式系统)
* 编译核心前,最好先了解到您主机的硬件,以及主机的用途,才能选择好核心功能;
* 编译前若想要保持核心源代码的干净,可使用 make mrproper 来清除暂存盘与配置文件;
* 挑选核心功能与模块可用 make 配合:menuconfig, oldconfig, xconfig, gconfig 等等
* 核心功能挑选完毕后,一般常见的编译过程为:make bzImage, make modules
* 模块编译成功后的安装方式为: make modules_install
* 核心的安装过程中,需要移动 bzImage 文件、创建 initramfs 文件、重建 grub.cfg 等动作;
* 我们可以自行由硬件开发商之官网下载驱动程序来自行编译核心模块!
';
24.5 以最新核心版本编译 CentOS 7.x 的核心
最后更新于:2022-04-01 22:17:47
## 24.5 以最新核心版本编译 CentOS 7.x 的核心
如果你跟鸟哥一样,曾经为了某些缘故需要最新的 4.x.y 的核心版本来实作某些特定的功能时,那该如何是好?没办法,只好使用最新的核心版本来编译啊! 你可以依照上面的程序来一个一个处理,没有问题~不过,你也可以根据 ELRepo 网站提供的 SRPM 来重新编译打包喔! 当然你可以直接使用 ELRepo 提供的 CentOS 7.x 专属的核心来直接安装。
下面我们使用 ELRepo 网站提供的 SRPM 文件来实作核心编译。而要这么重新编译的原因是,鸟哥需要将 VFIO 的 VGA 直接支持的核心功能打开! 因此整个程序会变成类似这样:
1. 先从 ELRepo 网站下载不含源代码的 SRPM 文件,并且安装该文件
2. 从 www.kernel.org 网站下载满足 ELRepo 网站所需要的核心版本来处理
3. 修改核心功能
4. 通过 SRPM 的 rpmbuild 重新编译打包核心
就让我们来测试一下啰!(注意,鸟哥使用的是 2015/10/20 当下最新的 4.2.3 这一版的核心。由于核心版本的升级太快,因此在你实作的时间, 可能已经有更新的核心版本了。此时你应该要前往 ELRepo 查阅最新的 SRPM 之后,再决定你想使用的版本喔!)
```
1\. 先下载 ELRepo 上面的 SRPM 文件!同时安装它:
[root@study ~]# wget http://elrepo.org/linux/kernel/el7/SRPMS/kernel-ml-4.2.3-1.el7.elrepo.nosrc.rpm
[root@study ~]# rpm -ivh kernel-ml-4.2.3-1.el7.elrepo.nosrc.rpm
2\. 根据上述的文件,下载正确的核心源代码:
[root@study ~]# cd rpmbuild/SOURCES
[root@study SOURCES]# wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.2.3.tar.xz
[root@study SOURCES]# ll -tr
.....(前面省略).....
-rw-r--r--. 1 root root 85523884 Oct 3 19:58 linux-4.2.3.tar.xz # 核心源代码
-rw-rw-r--. 1 root root 294 Oct 3 22:04 cpupower.service
-rw-rw-r--. 1 root root 150 Oct 3 22:04 cpupower.config
-rw-rw-r--. 1 root root 162752 Oct 3 22:04 config-4.2.3-x86_64 # 主要的核心功能
3\. 修改核心功能设置:
[root@study SOURCES]# vim config-4.2.3-x86_64
# 大约在 5623 行找到下面这一行,并在下面新增一行设置值!
# CONFIG_VFIO_PCI_VGA is not set
CONFIG_VFIO_PCI_VGA=y
[root@study SOURCES]# cd ../SPECS
[root@study SPECS]# vim kernel-ml-4.2.spec
# 大概在 145 左右找到下面这一行:
Source0: ftp://ftp.kernel.org/pub/linux/kernel/v4.x/linux-%{LKAver}.tar.xz
# 将它改成如下的模样:
Source0: linux-%{LKAver}.tar.xz
4\. 开始编译并打包:
[root@study SPECS]# rpmbuild -bb kernel-ml-4.2.spec
# 接下来会有很长的一段时间在进行编译行为,鸟哥的机器曾经跑过两个小时左右才编译完!
# 所以,请耐心等候啊!
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-ml-4.2.3-1.el7.centos.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-ml-devel-4.2.3-1.el7.centos.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-ml-headers-4.2.3-1.el7.centos.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/perf-4.2.3-1.el7.centos.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/python-perf-4.2.3-1.el7.centos.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-ml-tools-4.2.3-1.el7.centos.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-ml-tools-libs-4.2.3-1.el7.centos.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-ml-tools-libs-devel-4.2.3-1.el7.centos.x86_64.rpm
```
如上表最后的状态,你会发现竟然已经有 kernel-ml 的软件包产生了!接下来你也不需要像手动安装核心一样,得要一个一个项目移动到正确的位置去, 只要使用 yum install 新的核心版本,就会有 4.2.3 版的核心在你的 CentOS 7.x 当中了耶!相当神奇!
```
[root@study ~]# yum install /root/rpmbuild/RPMS/x86_64/kernel-ml-4.2.3-1.el7.centos.x86_64.rpm
[root@study ~]# reboot
[root@study ~]# uname -a
Linux study.centos.vbird 4.2.3-1.el7.centos.x86_64 #1 SMP Wed Oct 21 02:31:18 CST 2015 x86_64
x86_64 x86_64 GNU/Linux
```
这样就让我们的 CentOS 7.x 具有最新的核心啰!与核心官网相同版本咧~够帅气吧!
';
24.4 额外(单一)核心模块编译
最后更新于:2022-04-01 22:17:45
## 24.4 额外(单一)核心模块编译
我们现在知道核心所支持的功能当中,有直接编译到核心内部的,也有使用外挂模块的,外挂模块可以简单的想成就是驱动程序 啦!那么也知道这些核心模块依据不同的版本,被分别放置到 /lib/modules/$(uname -r)/kernel/ 目录中,各个硬件的驱动程序则是放置到 /lib/modules/$(uname -r)/kernel/drivers/ 当中!换个角度再来思考一下,如果刚刚我自己编译的数据中,有些驱动程序忘记编译成为模块了,那是否需要重新进行上述的所有动作? 又如果我想要使用硬件厂商释出的新驱动程序,那该如何是好?
### 24.4.1 编译前注意事项
由于我们的核心原本就有提供很多的核心工具给硬件开发商来使用, 而硬件开发商也需要针对核心所提供的功能来设计他们的驱动程序模块,因此, 我们如果想要自行使用硬件开发商所提供的模块来进行编译时,就需要使用到核心所提供的原始文件当中, 所谓的头文件案 (header include file) 来取得驱动模块所需要的一些函数库或标头的定义啦! 也因此我们常常会发现到,如果想要自行编译核心模块时,就得要拥有核心源代码嘛!
那核心源代码我们知道他是可能放置在 /usr/src/ 下面,早期的核心源代码被要求一定要放置到 /usr/src/linux/ 目录下,不过,如果你有多个核心在一个 Linux 系统当中,而且使用的源代码并不相同时, 呵呵~问题可就大了!所以,在 2.6 版以后,核心使用比较有趣的方法来设计他的源代码放置目录, 那就是以 /lib/modules/$(uname -r)/build 及 /lib/modules/$(uname -r)/source 这两个链接文件来指向正确的核心源代码放置目录。如果以我们刚刚由 kernel 3.10.89vbird 创建的核心模块来说, 那么他的核心模块目录下面有什么咚咚?
```
[root@study ~]# ll -h /lib/modules/3.10.89vbird/
lrwxrwxrwx. 1 root root 30 Oct 20 14:27 build -> /usr/src/kernels/linux-3.10.89
drwxr-xr-x. 11 root root 4.0K Oct 20 14:29 kernel
-rw-r--r--. 1 root root 668K Oct 20 14:29 modules.alias
-rw-r--r--. 1 root root 649K Oct 20 14:29 modules.alias.bin
-rw-r--r--. 1 root root 5.8K Oct 20 14:27 modules.builtin
-rw-r--r--. 1 root root 7.5K Oct 20 14:29 modules.builtin.bin
-rw-r--r--. 1 root root 208K Oct 20 14:29 modules.dep
-rw-r--r--. 1 root root 301K Oct 20 14:29 modules.dep.bin
-rw-r--r--. 1 root root 316 Oct 20 14:29 modules.devname
-rw-r--r--. 1 root root 81K Oct 20 14:27 modules.order
-rw-r--r--. 1 root root 131 Oct 20 14:29 modules.softdep
-rw-r--r--. 1 root root 269K Oct 20 14:29 modules.symbols
-rw-r--r--. 1 root root 339K Oct 20 14:29 modules.symbols.bin
lrwxrwxrwx. 1 root root 30 Oct 20 14:27 source -> /usr/src/kernels/linux-3.10.89
```
比较有趣的除了那两个链接文件之外,还有那个 modules.dep 文件也挺有趣的, 那个文件是记录了核心模块的相依属性的地方,依据该文件,我们可以简单的使用 modprobe 这个指令来载入模块呢!至于核心源代码提供的头文件,在上面的案例当中, 则是放置到 /usr/src/kernels/linux-3.10.89/include/ 目录中,当然就是借由 build/source 这两个链接文件来取得目录所在的啦!^_^
由于核心模块的编译其实与核心原本的源代码有点关系的,因此如果你需要重新编译模块时, 那除了 make, gcc 等主要的编译软件工具外,你还需要的就是 kernel-devel 这个软件!记得一定要安装喔!而如果你想要在默认的核心下面新增模块的话,那么就得要找到 kernel 的 SRPM 文件了! 将该文件给他安装,并且取得 source code 后,才能够顺利的编译喔!
### 24.4.2 单一模块编译
想像两个情况:
* 如果我的默认核心忘记加入某个功能,而且该功能可以编译成为模块,不过, 默认核心却也没有将该项功能编译成为模块,害我不能使用时,该如何是好?
* 如果 Linux 核心源代码并没有某个硬件的驱动程序 (module) ,但是开发该硬件的厂商有提供给 Linux 使用的驱动程序源代码,那么我又该如何将该项功能编进核心模块呢?
很有趣对吧!不过,在这样的情况下其实没有什么好说的,反正就是 “去取得源代码后,重新编译成为系统可以载入的模块”啊!很简单,对吧!^_^! 但是,上面那两种情况的模块编译行为是不太一样的,不过,都是需要 make, gcc 以及核心所提供的 include 头文件与函数库等等。
* 硬件开发商提供的额外模块
很多时候,可能由于核心默认的核心驱动模块所提供的功能你不满意,或者是硬件开发商所提供的核心模块具有更强大的功能, 又或者该硬件是新的,所以默认的核心并没有该硬件的驱动模块时,那你只好自行由硬件开发商处取得驱动模块,然后自行编译啰!
如果你的硬件开发商有提供驱动程序的话,那么真的很好解决,直接下载该源代码,重新编译, 将他放置到核心模块该放置的地方后就能够使用了!举个例子来说,鸟哥在 2014 年底帮厂商制作一个服务器的环境时, 发现对方喜欢使用的磁盘阵列卡 (RAID) 当时并没有被 Linux 核心所支持,所以就得要帮厂商针对该磁盘阵列卡来编译成为模块啰! 处理的方式,当然就是使用磁盘阵列卡官网提供的驱动程序来编译啰!
* Highpoint 的 RocketRAID RR640L 驱动程序:
[http://www.highpoint-tech.com/USA_new/series_rr600-download.htm](http://www.highpoint-tech.com/USA_new/series_rr600-download.htm)
虽然你可以选择“RHEL/CentOS 7 x86_64”这个已编译的版本来处理,不过因为我们的核心已经做成自订的版本, 变成 3.10.89vbird 这样,忘记加上 x86_64 的版本名,会导致该版本的自动安装脚本失败!所以,算了!我们自己来重新编译吧! 因此,请下载“Open Source Driver”的版本喔!同时,鸟哥假设你将下载的文件放置到 /root/raidcard 目录内喔!
```
# 1\. 将文件解压缩并且开始编译:
[root@study ~]# cd /root/raidcard
[root@study raidcard]# ll
-rw-r--r--. 1 root root 501477 Apr 23 07:42 RR64xl_Linux_Src_v1.3.9_15_03_07.tar.gz
[root@study raidcard]# tar -zxvf RR64xl_Linux_Src_v1.3.9_15_03_07.tar.gz
[root@study raidcard]# cd rr64xl-linux-src-v1.3.9/product/rr64xl/linux/
[root@study linux]# ll
-rw-r--r--. 1 dmtsai dmtsai 1043 Mar 7 2015 config.c
-rwxr-xr-x. 1 dmtsai dmtsai 395 Dec 27 2013 Makefile # 要有这家伙存在才行!
[root@study linux]# make
make[1]: Entering directory `/usr/src/kernels/linux-3.10.89'
CC [M] /root/raidcard/rr64xl-linux-src-v1.3.9/product/rr64xl/linux/.build/os_linux.o
CC [M] /root/raidcard/rr64xl-linux-src-v1.3.9/product/rr64xl/linux/.build/osm_linux.o
.....(中间省略).....
LD [M] /root/raidcard/rr64xl-linux-src-v1.3.9/product/rr64xl/linux/.build/rr640l.ko
make[1]: Leaving directory `/usr/src/kernels/linux-3.10.89'
[root@study linux]# ll
-rw-r--r--. 1 dmtsai dmtsai 1043 Mar 7 2015 config.c
-rwxr-xr-x. 1 dmtsai dmtsai 395 Dec 27 2013 Makefile
-rw-r--r--. 1 root root 1399896 Oct 21 00:59 rr640l.ko # 就是产生这家伙!
# 2\. 将模块放置到正确的位置去!
[root@study linux]# cp rr640l.ko /lib/modules/3.10.89vbird/kernel/drivers/scsi/
[root@study linux]# depmod -a # 产生模块相依性文件!
[root@study linux]# grep rr640 /lib/modules/3.10.89vbird/modules.dep
kernel/drivers/scsi/rr640l.ko: # 确定模块有在相依性的配置文件中!
[root@study linux]# modprobe rr640l
modprobe: ERROR: could not insert 'rr640l': No such device
# 要测试载入一下才行,不过,我们实际上虚拟机没有这张 RAID card,所以出现错误是正常的啦!
# 3\. 若开机过程中就得要载入此模块,则需要将模块放入 initramfs 才行喔!
[root@study linux]# dracut --force -v --add-drivers rr640l \
> /boot/initramfs-3.10.89vbird.img 3.10.89vbird
[root@study linux]# lsinitrd /boot/initramfs-3.10.89vbird.img | grep rr640
```
通过这样的动作,我们就可以轻易的将模块编译起来,并且还可以将他直接放置到核心模块目录中, 同时以 depmod 将模块创建相关性,未来就能够利用 modprobe 来直接取用啦! 但是需要提醒你的是,当自行编译模块时, 若你的核心有更新 (例如利用自动更新机制进行线上更新) 时,则你必须要重新编译该模块一次, 重复上面的步骤才行!因为这个模块仅针对目前的核心来编译的啊!对吧!
* 利用旧有的核心源代码进行编译
如果你后来发现忘记加入某个模块功能了,那该如何是好?其实如果仅是重新编译模块的话, 那么整个过程就会变的非常简单!我们先到目前的核心源代码所在目录下达 make menuconfig , 然后将 NTFS 的选项设置成为模块,之后直接下达:
> make fs/ntfs/
那么 ntfs 的模块 (ntfs.ko) 就会自动的被编译出来了! 然后将该模块复制到 /lib/modules/3.10.89vbird/kernel/fs/ntsf/ 目录下, 再执行 depmod -a ,呵呵~就可以在原来的核心下面新增某个想要加入的模块功能啰~ ^_^
### 24.4.3 核心模块管理
核心与核心模块是分不开的,至于驱动程序模块在编译的时候,更与核心的源代码功能分不开~ 因此,你必须要先了解到:核心、核心模块、驱动程序模块、核心源代码与头文件案的相关性, 然后才有办法了解到为何编译驱动程序的时候老是需要找到核心的源代码才能够顺利编译! 然后也才会知道,为何当核心更新之后,自己之前所编译的核心模块会失效~
此外,与核心模块有相关的,还有那个很常被使用的 modprobe 指令, 以及开机的时候会读取到的模块定义数据文件 /etc/modprobe.conf , 这些数据你也必须要了解才行~相关的指令说明我们已经在[第十九章](../Text/index.html)内谈过了, 你应该要自行前往了解喔! ^_^
';
24.3 核心的编译与安装
最后更新于:2022-04-01 22:17:43
## 24.3 核心的编译与安装
将最复杂的核心功能选择完毕后,接下来就是进行这些核心、核心模块的编译了!而编译完成后,当然就是需要使用噜~ 那如何使用新核心呢?就得要考虑 grub 这个玩意儿啦!下面我们就来处理处理:
### 24.3.1 编译核心与核心模块
核心与核心模块需要先编译起来,而编译的过程其实非常简单,你可以先使用“ make help ”去查阅一下所有可用编译参数, 就会知道有下面这些基本功能:
```
[root@study linux-3.10.89]# make vmlinux <==未经压缩的核心
[root@study linux-3.10.89]# make modules <==仅核心模块
[root@study linux-3.10.89]# make bzImage <==经压缩过的核心(默认)
[root@study linux-3.10.89]# make all <==进行上述的三个动作
```
我们常见的在 /boot/ 下面的核心文件,都是经过压缩过的核心文件,因此,上述的动作中比较常用的是 modules 与 bzImage 这两个,其中 bzImage 第三个字母是英文大写的 I 喔!bzImage 可以制作出压缩过后的核心, 也就是一般我们拿来进行系统开机的信息啰!所以,基本上我们会进行的动作是:
```
[root@study linux-3.10.89]# make -j 4 clean <==先清除暂存盘
[root@study linux-3.10.89]# make -j 4 bzImage <==先编译核心
[root@study linux-3.10.89]# make -j 4 modules <==再编译模块
[root@study linux-3.10.89]# make -j 4 clean bzImage modules <==连续动作!
```
上述的动作会花费非常长的时间,编译的动作依据你选择的项目以及你主机硬件的性能而不同。此外,为啥要加上 -j 4 呢? 因为鸟哥的系统上面有四个 CPU 核心,这几个核心可以同时进行编译的行为,这样在编译时速度会比较快!如果你的 CPU 核心数 (包括超线程) 有多个, 那这个地方请加上你的可用 CPU 数量吧!
最后制作出来的数据是被放置在 /usr/src/kernels/linux-3.10.89/ 这个目录下,还没有被放到系统的相关路径中喔!在上面的编译过程当中,如果有发生任何错误的话, 很可能是由于核心项目的挑选选择的不好,可能你需要重新以 make menuconfig 再次的检查一下你的相关设置喔! 如果还是无法成功的话,那么或许将原本的核心数据内的 .config 文件,复制到你的核心原始文件目录下, 然后据以修改,应该就可以顺利的编译出你的核心了。最后注意到,下达了 make bzImage 后,最终的结果应该会像这样:
```
Setup is 16752 Bytes (padded to 16896 Bytes).
System is 4404 kB
CRC 30310acf
Kernel: arch/x86/boot/bzImage is ready (#1)
[root@study linux-3.10.89]# ll arch/x86/boot/bzImage
-rw-r--r--. 1 root root 4526464 Oct 20 09:09 arch/x86/boot/bzImage
```
可以发现你的核心已经编译好而且放置在 /usr/src/kernels/linux-3.10.89/arch/x86/boot/bzImage 里面啰~那个就是我们的核心文件!最重要就是他啦!我们等一下就会安装到这个文件哩! 然后就是编译模块的部分啰~ make modules 进行完毕后,就等着安装啦! ^_^
### 24.3.2 实际安装模块
安装模块前有个地方得要特别强调喔!我们知道模块是放置到 /lib/modules/$(uname -r) 目录下的,那如果同一个版本的模块被反复编译后来安装时,会不会产生冲突呢?举例来说,鸟哥这个 3.10.89 的版本第一次编译完成且安装妥当后,发现有个小细节想要重新处理,因此又重新编译过一次,那两个版本一模一样时, 模块放置的目录会一样,此时就会产生冲突了!如何是好?有两个解决方法啦:
* 先将旧的模块目录更名,然后才安装核心模块到目标目录去;
* 在 make menuconfig 时,那个 [General setup](../Text/index.html#general) 内的 Local version 修改成新的名称。
鸟哥建议使用第二个方式,因为如此一来,你的模块放置的目录名称就不会相同,这样也就能略过上述的目录同名问题啰! 好,那么如何安装模块到正确的目标目录呢?很简单,同样使用 make 的功能即可:
```
[root@study linux-3.10.89]# make modules_install
[root@study linux-3.10.89]# ll /lib/modules/
drwxr-xr-x. 7 root root 4096 Sep 9 01:14 3.10.0-229.11.1.el7.x86_64
drwxr-xr-x. 7 root root 4096 May 4 17:56 3.10.0-229.el7.x86_64
drwxr-xr-x. 3 root root 4096 Oct 20 14:29 3.10.89vbird # 这就是刚刚装好的核心模块!
```
看到否,最终会在 /lib/modules 下面创建起你这个核心的相关模块喔!不错吧!模块这样就已经处理妥当啰~ 接下来,就是准备要进行核心的安装了!哈哈!又跟 grub2 有关啰~
### 24.3.3 开始安装新核心与多重核心菜单 (grub)
现在我们知道核心文件放置在 /usr/src/kernels/linux-3.10.89/arch/x86/boot/bzImage ,但是其实系统核心理论上都是摆在 /boot 下面,且为 vmlinuz 开头的文件名。 此外,我们也晓得一部主机是可以做成多重开机系统的!这样说,应该知道鸟哥想要干嘛了吧? 对啦!我们将同时保留旧版的核心,并且新增新版的核心在我们的主机上面。
此外,与 grub1 不一样, grub2 建议我们不要直接修改配置文件,而是通过让系统自动侦测来处理 grub.cfg 这个配置文件的内容。 所以,在处理核心文件时,可能就得要知道核心文件的命名规则比较好耶!
* 移动核心到 /boot 且保留旧核心文件
保留旧核心有什么好处呢?最大的好处是可以确保系统能够顺利开机啦!因为核心虽然被编译成功了, 但是并不保证我们刚刚挑选的核心项目完全适合于目前这部主机系统, 可能有某些地方我们忘记选择了,这将导致新核心无法顺利驱动整个主机系统,更差的情况是, 你的主机无法成功开机成功!此时,如果我们保留旧的核心,呵呵!若新核心测试不通过,就用旧核心来启动啊!嘿嘿! 保证比较不会有问题嘛!另外,核心文件通常以 vmlinuz 为开头,接上核心版本为依据的文件名格式,因此可以这样做看看:
```
[root@study linux-3.10.89]# cp arch/x86/boot/bzImage /boot/vmlinuz-3.10.89vbird <==实际核心
[root@study linux-3.10.89]# cp .config /boot/config-3.10.89vbird <==建议配置文件也复制备份
[root@study linux-3.10.89]# chmod a+x /boot/vmlinuz-3.10.89vbird
[root@study linux-3.10.89]# cp System.map /boot/System.map-3.10.89vbird
[root@study linux-3.10.89]# gzip -c Module.symvers > /boot/symvers-3.10.89vbird.gz
[root@study linux-3.10.89]# restorecon -Rv /boot
```
* 创建相对应的 Initial Ram Disk (initrd)
还记得[第十九章谈过的 initramfs](../Text/index.html#grub_initrd) 这个玩意儿吧! 由于鸟哥的系统使用 SATA 磁盘,加上刚刚 SATA 磁盘支持的功能并没有直接编译到核心去,所以当然要使用 initramfs 来载入才行! 使用如下的方法来创建 initramfs 吧!记得搭配正确的核心版本喔!
```
[root@study ~]# dracut -v /boot/initramfs-3.10.89vbird.img 3.10.89vbird
```
* 编辑开机菜单 (grub)
前面的文件大致上都摆放妥当之后,同时得要依据你的核心版本来处理文件名喔!接下来就直接使用 grub2-mkconfig 来处理你的 grub2 开机菜单设置即可!让我们来处理处理先!
```
[root@study ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.89vbird # 应该要最早出现!
Found initrd image: /boot/initramfs-3.10.89vbird.img
.....(下面省略).....
```
因为默认较新版本的核心会放在最前面成为默认的开机菜单项目,所以你得要确认上述的结果中,第一个被发现的核心为你刚刚编译好的核心文件才对喔! 否则等一下开机可能就会出现使用旧核心开机的问题。现在让我们重新开机来测试看看啰!
* 重新以新核心开机、测试、修改
如果上述的动作都成功后,接下来就是重新开机并选择新核心来启动系统啦!如果系统顺利启动之后,你使用 uname -a 会出现类似下面的数据:
```
[root@study ~]# uname -a
Linux study.centos.vbird 3.10.89vbird #1 SMP Tue Oct 20 09:09:11 CST 2015 x86_64
x86_64 x86_64 GNU/Linux
```
包括核心版本与支持的硬件平台都是 OK 的!嘿嘿!那你所编译的核心就是差不多成功的啦! 如果运行一阵子后,你的系统还是稳定的情况下,那就能够将 default 值使用这个新的核心来作为默认开机啰! 这就是核心编译!那你也可以自己处理嵌入式系统的核心编译啰! ^_^
';
24.2 核心编译的前处理与核心功能选择
最后更新于:2022-04-01 22:17:40
## 24.2 核心编译的前处理与核心功能选择
什么?核心编译还要进行前处理?没错啦!事实上,核心的目的在管理硬件与提供系统核心功能,因此你必须要先找到你的系统硬件, 并且规划你的主机未来的任务,这样才能够编译出适合你这部主机的核心!所以,整个核心编译的重要工作就是在“挑选你想要的功能”。 下面鸟哥就以自己的一部主机软/硬件环境来说明,解释一下如何处理核心编译啰!
### 24.2.1 硬件环境检视与核心功能要求
鸟哥的一部主机硬件环境如下 (在虚拟机中,通过 /proc/cpuinfo 及 lspci 观察):
* CPU:Intel(R) Xeon(R) CPU E5-2650
* 主板芯片组: KVM 虚拟化仿真的主版 (Intel 440FX 相容)
* 显卡: Red Hat, Inc. QXL paravirtual graphic card
* 内存: 2.0GB 内存
* 硬盘: KVM Virtio 界面磁盘 40G (非 IDE/SATA/SAS 喔!)
* 网卡: Red Hat, Inc Virtio network device
硬件大致如上,至于这部主机的需求,是希望做为未来在鸟哥上课时,可以通过虚拟化功能来处理学生的练习用虚拟机。 这部主机也是鸟哥用来放置学校上课教材的机器,因此,这部主机的 I/O 需求须要好一点,未来还需要打开防火墙、 WWW 服务器功能、FTP 服务器功能等,基本上,用途就是一部小型的服务器环境啰。大致上需要这样的功能啦!
### 24.2.2 保持干净源代码: make mrproper
了解了硬件相关的数据后,我们还得要处理一下核心源代码下面的残留文件才行!假设我们是第一次编译, 但是我们不清楚到下面载下来的源代码当中有没有保留目标文件 (*.o) 以及相关的配置文件存在, 此时我们可以通过下面的方式来处理掉这些“编译过程的目标文件以及配置文件”:
```
[root@study ~]# cd /usr/src/kernels/linux-3.10.89/
[root@study linux-3.10.89]# make mrproper
```
请注意,这个动作会将你以前进行过的核心功能选择文件也删除掉, 所以几乎只有第一次执行核心编译前才进行这个动作,其余的时刻,你想要删除前一次编译过程的残留数据, 只要下达:
```
[root@study linux-3.10.89]# make clean
```
因为 make clean 仅会删除类似目标文件之类的编译过程产生的中间文件,而不会删除配置文件! 很重要的!千万不要搞乱了喔!好了,既然我们是第一次进行编译,因此,请下达“make mrproper”吧!
### 24.2.3 开始挑选核心功能: make XXconfig
不知道你有没有发现 /boot/ 下面存在一个名为 config-xxx 的文件?那个文件其实就是核心功能列表文件! 我们下面要进行的动作,其实就是作出该文件!而我们后续小节所要进行的编译动作,其实也就是通过这个文件来处理的! 核心功能的挑选,最后会在 /usr/src/kernels/linux-3.10.89/ 下面产生一个名为 .config 的隐藏文件, 这个文件就是 /boot/config-xxx 的文件啦!那么这个文件如何创建呢?你可以通过非常多的方法来创建这个文件! 常见的方法有:[[1]](#ps1)
* make menuconfig
最常使用的,是文字模式下面可以显示类似图形接口的方式,不需要启动 X Window 就能够挑选核心功能菜单!
* 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
最旧式的功能挑选方法,每个项目都以条列式一条一条的列出让你选择,如果设置错误只能够再次选择,很不人性化啊!
大致的功能选择有上述的方法,更多的方式可以参考核心目录下的 README 文件。鸟哥个人比较偏好 make menuconfig 这个项目啦!如果你喜欢使用图形接口, 然后使用鼠标去挑选所需要的功能时,也能使用 make xconfig 或 make gconfig ,不过需要有相关的图形接口支持! 如果你是升级核心源代码并且需要重新编译,那么使用 make oldconfig 会比较适当!
* 通过既有的设置来处理核心项目与功能的选择
如果你跟鸟哥一样懒,那可以这样思考一下。既然我们的 CentOS 7 已经有提供它的核心设置值,我们也只是想要修改一些小细节而已, 那么能不能以 CentOS 7 的核心功能为底,然后来细部微调其它的设置呢?当然可以啊!你只要这样做即可:
```
[root@study linux-3.10.89]# cp /boot/config-3.10.0-229.11.1.el7.x86_64 .config
# 上面那个版本请依据你自己的环境来填写~
```
接下来要开始调整啰!那么如何选择呢?以 make menuconfig 来说,出现的画面会有点像这样:
![鸟哥的图示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** 注意,你可能会被要求安装好多软件,请自行使用 yum 来安装喔!这里不再介绍了! 另外:“不要再使用 make mrproper ”喔!因为我们已经复制了 .config 啊!使用 make mrproper 会将 .config 删除喔!
![make menuconfig 核心功能挑选菜单示意图](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_57357381567a3.jpg)图24.2.1、make menuconfig 核心功能挑选菜单示意图
看到上面的图示之后,你会发现画面主要分为两大部分,一个是大框框内的反白光柱,另一个则是下面的小框框, 里面有 select, exit 与 help 三个选项的内容。这几个元件的大致用法如下:
* “左右方向键”:可以移动最下面的 <Select>, <Exit>, <Help>项目;
* “上下方向键”:可以移动上面大框框部分的反白光柱,若该行有箭头 (--->) 则表示该行内部还有其他细项需要来设置的意思;
* 选定项目:以“上下键”选择好想要设置的项目之后,并以“左右键”选择 <Select> 之后, 按下“ Enter ”就可以进入该项目去作更进一步的细部设置啰;
* 可挑选之功能:在细部项目的设置当中,如果前面有 [ ] 或 < > 符号时,该项目才可以选择, 而选择可以使用“空白键”来选择;
* 若为 [*] <*> 则表示编译进核心;若为 <M> 则表示编译成模块! 尽量在不知道该项目为何时,且有模块可以选,那么就可以直接选择为模块啰!
* 当在细项目选择 <Exit> 后,并按下 Enter ,那么就可以离开该细部项目啰!
基本上建议只要“上下左右的方向键、空白键、Enter”这六个按键就好了!不要使用 Esc ,否则一不小心就有可能按错的!另外,关于整个核心功能的选择上面,建议你可以这样思考:
* “肯定”核心一定要的功能,直接编译进核心内;
* “可能在未来会用到”的功能,那么尽量编译成为模块;
* “不知道那个东西要干嘛的,看 help 也看不懂”的话,那么就保留默认值,或者将他编译成为模块;
总之,尽量保持核心小而美,剩下的功能就编译成为模块,尤其是“需要考虑到未来扩充性”, 像鸟哥之前认为螃蟹卡就够我用的了,结果,后来竟然网站流量大增,鸟哥只好改换 3Com 的网卡。 不过,我的核心却没有相关的模块可以使用~因为.....鸟哥自己编译的核心忘记加入这个模块了。 最后,只好重新编译一次核心的模块,呵呵!真是惨痛的教训啊!
### 24.2.4 核心功能细项选择
由上面的图示当中,我们知道核心的可以选择的项目有很多啊!光是第一面,就有 17 个项目,每个项目内还有不同的细项!哇!真是很麻烦啊~每个项目其实都可能有 <Help> 的说明,所以,如果看到不懂的项目,务必要使用 Help 查阅查阅! 好了,下面我们就一个一个项目来看看如何选择吧!
![鸟哥的图示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** 在下面的案例中,因为鸟哥使用的是 CentOS 7.1 的核心配置文件来进行默认的设置, 所以基本上许多默认的设置都不用重新调整。下面只列出几个鸟哥认为比较重要的设置项目。其他更详细的核心功能项目,还请自行参考 help 的说明喔!
* General setup
与 Linux 最相关的程序互动、核心版本说明、是否使用发展中程序码等信息都在这里设置的。 这里的项目主要都是针对核心与程序之间的相关性来设计的,基本上,保留默认值即可! 不要随便取消下面的任何一个项目,因为可能会造成某些程序无法被同时执行的困境喔! 不过下面有非常多新的功能,如果你有不清楚的地方,可以按 <Help> 进入查阅,里面会有一些建议! 你可以依据 Help 的建议来选择新功能的启动与否!
```
(vbird) Local version - append to kernel release
[*] Automatically append version information to the version string
# 我希望我的核心版本成为 3.10.89.vbird ,那这里可以就这样设置!
Kernel compression mode (Bzip2) --->
# 建议选择成为 Bzip2 即可,因为压缩比较佳!
.....(其他保留默认值).....
<M> Kernel .config support
[ ] Enable access to .config through /proc/config.gz (NEW)
# 让 .config 这个核心功能列表可以写入实际的核心文件中!所以就不需要保留 .config 文件啰!
(20) Kernel log buffer size (16 => 64KB, 17 => 128KB)
# CentOS 7 增加了核心的登录文件容量!占用了 2 的 20 次方,大概用了 1MB 的容量!
.....(其他保留默认值).....
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
() Initramfs source file(s)
# 这是一定要的!因为要支持开机时载入 initail RAM disk 嘛!
[ ] Optimize for size
# 减低核心的文件大小,其实 gcc 参数使用 -Os 而不是 -O2。不过我们不是嵌入式系统,不太需要!
[ ] Configure standard kernel features (expert users) --->
[ ] Embedded system
# 上面两个在决定是否支持嵌入式系统呢?我们这里是台式机,所以这个不用选择了!
.....(其他保留默认值).....
```
* loadable module + block layer
要让你的核心能够支持动态的核心模块,那么下面的第一个设置就得要启动才行!至于第二个 block layer 则默认是启动的, 你也可以进入该项目的细项设置,选择其中你认为需要的功能即可!
```
[*] Enable loadable module support ---> <==下面为细项
--- Enable loadable module support
[*] Forced module loading
[*] Module unloading
[*] Forced module unloading # 其实鸟哥认为这个项目可能可以选择的!免得常常无法卸载模块!
[*] Module versioning support
[*] Source checksum for all modules
[*] Module signature verification
[ ] Require modules to be validly signed
[*] Automatically sign all modules
Which hash algorithm should modules be signed with? # 可以选择 SHA256 即可!
================================================================================
-*- Enable the block layer ---> <==看吧!默认就是已经选择了!下面为细项
-*- Block layer SG support v4
-*- Block layer SG support v4 helper lib
[*] Block layer data integrity support
[*] Block layer bio throttling support
Partition Types ---> # 至少下面的数个项目要选择!
[*] Macintosh partition map support
[*] PC BIOS (MSDOS partition tables) support
[*] Windows Logical Disk Manager (Dynamic Disk) support
[*] SGI partition support
[*] EFI GUID Partition support
.....(其他保留默认值).....
IO Schedulers ---> # 磁盘伫列的处理方式
<*> Deadline I/O scheduler # 鸟哥非常建议将此项目设置为核心功能!
<*> CFQ I/O scheduler
[*] CFQ Group Scheduling support
Default I/O scheduler (Deadline) ---> # 相当建议改为Deadline
```
* CPU 的类型与功能选择
进入“Processor type and features”后,请挑选你主机的实际 CPU 形式。鸟哥这里使用的是 Intel E5 的 CPU, 而且鸟哥的主机还有启动 KVM 这个虚拟化的服务 (在一部主机上面同时启动多个操作系统),因此,所以下面的选择是这样的:
```
.....(其他保留默认值).....
[*] Linux guest support ---> # 提供 Linux 虚拟化功能
[*] Enable paravirtualization code # 至少下面这几样一定要有选择才好!
[*] Paravirtualization layer for spinlocks
[*] Xen guest support
[*] KVM Guest support (including kvmclock)
[*] Paravirtual steal time accounting
.....(其他保留默认值).....
Processor family (Generic-x86-64) ---> # 除非你是旧系统,否则就用他!
[*] Enable Maximum number of SMP Processors and NUMA Nodes
[*] Multi-core scheduler support
Preemption Model (No Forced Preemption (Server) ---> # 调整成 server 喔!原本是 desktop
.....(其他保留默认值).....
Timer frequency (300 HZ) ---> # server 设置成 300 即可!
# 这个项目则与核心针对某个事件立即回应的速度有关。Server 用途可以调整到
# 300Hz 即可,如果是桌面电脑使用,需要调整高一点,例如 1000Hz 较佳!
.....(其他保留默认值).....
```
* 电源管理功能
如果选择了“Power management and ACPI options”之后,就会进入系统的电源管理机制中。 其实电源管理机制还需要搭配主板以及 CPU 的相关省电功能,才能够实际达到省电的效率啦! 不论是 Server 还是 Desktop 的使用,在目前电力不足的情况下,能省电就加以省电吧!
```
.....(其他保留默认值).....
[*] ACPI (Advanced Configuration and Power Interface) Support --->
# 对嵌入式系统来说,由于可能会增加核心容量故需要考虑考虑。至于 desktop/server 当然就选择啊
# 至于内容细项大致保持默认值即可
CPU Frequency scaling --->
# 决定 CPU 频率的一个重要项目,基本上的项目是 ondemand 与 performance 两者!
<M> CPU frequency translation statistics
[*] CPU frequency translation statistics details
Default CPUFreq governor (ondemand) ---> # 现在大家都建议用这个!
-*- 'performance' governor
<*> 'powersave' governor
<*> 'userspace' governor for userspace frequency scaling
-*- 'ondemand' cpufreq policy governor
<*> 'conservative' cpufreq governor
x86 CPU frequency scaling drivers --->
# 这个子项目内全部都是省电机制,能编成模块的全部选择!要加入核心的都加入就对了!
```
* 一些总线 (bus) 的选项
这个“Bus options (PCI etc.)”项目则与总线有关啦!分为最常见的 PCI 与 PCI-express 的支持,还有笔记本电脑常见的 PCMCIA 插卡啊!要记住的是,那个 PCI-E 的接口务必要选取!不然你的新显卡可能会捉不到!
```
[*] PCI support
[*] Support mmconfig PCI config space access
[*] PCI Express support
<*> PCI Express Hotplug driver
.....(其他在 PCI Express 下面的项目大多保留默认值).....
-*- Message Signaled Interrupts (MSI and MSI-X)
<*> PCI Stub driver # 如果要玩虚拟化,这个部份建议编进核心!
.....(其他保留默认值).....
```
* 编译后可执行文件的格式
选择“Executable file formats / Emulations”会见到如下选项。 下面的选项必须要勾选才行喔!因为是给 Linux 核心运行可执行文件之用的数据。通常是与编译行为有关啦!
```
-*- Kernel support for ELF binaries
[*] Write ELF core dumps with partial segments
<*> Kernel support for scripts starting with #!
<M> Kernel support for MISC binaries
[*] IA32 Emulation
<M> IA32 a.out support
[*] x32 ABI for 64-bit mode
# 因为我们的 CentOS 已经是纯 64 位的环境!所以个人建议这里还是要选择仿真 32 位的功能!
# 不然若有些比较旧的软件,恐怕会无法被你的系统所执行喔!
```
* 核心的网络功能
这个“Networking support”项目是相当重要的选项,因为他还包含了防火墙相关的项目!就是未来在服务器篇会谈到的防火墙 iptables 这个数据啊!所以,千万注意了!在这个设置项目当中,很多东西其实我们在基础篇还没有讲到, 因为大部分的参数都与网络、防火墙有关!由于防火墙是在启动网络之后再设置即可,所以绝大部分的内容都可以被编译成为模块,而且也建议你编成模块!有用到再载入到核心即可啊!
```
--- Networking support
Networking options --->
# 就是这个光啊!里面的数据全部都是重要的防火墙项目!尽量编成模块啰!
# 至于不晓得功能的部分,就尽量保留默认值即可!
# 下面的数据中,鸟哥只有列出原本没有选择,后来建议选择的部份
[*] Network packet filtering framework (Netfilter) --->
# 这个就是我们一直讲的防火墙部分!里面细项几乎全选择成为模块!
--- Network packet filtering framework (Netfilter)
Core Netfilter Configuration --->
<M> Transparent proxying support
================================================================================
[*] QoS and/or fair queueing ---> <==内容同样全为模块!
Network testing ---> <==保留成模块默认值
================================================================================
# 下面的则是一些特殊的网络设备,例如红外线啊、蓝牙啊!
# 如果不清楚的话,就使用模块吧!除非你真的知道不要该项目!
<M> Bluetooth subsystem support --->
# 这个是蓝牙支持,同样的,里面除了必选之外,其他通通挑选成为模块!
[*] Wireless --->
# 这个则是无线网络设备,里面保留默认值,但可编成模块的就选模块
<M> WiMAX Wireless Broadband support --->
# 新一代的无线网络,也请勾选成为模块!
<M> NFC subsystem support --->
# 跟卡片比较有关的芯片支持,建议编译成模块,内部数据也是编译成模块为佳!
```
* 各项设备的驱动程序
进入“Device Drivers”这个是所有硬件设备的驱动程序库!哇!光是看到里面这么多内容,鸟哥头都昏了~ 不过,为了你自己的主机好,建议你还是得要一个项目一个项目的去挑选挑选才行~ 这里面的数据就与你主机的硬件有绝对的关系了!
在这里面真的很重要,因为很多数据都与你的硬件有关。核心推出时的默认值是比较符合一般状态的, 所以很多数据其实保留默认值就可以编的很不错了!不过,也因为较符合一般状态, 所以核心额外的编译进来很多跟你的主机系统不符合的数据,例如网卡设备~ 你可以针对你的主板与相关硬件来进行编译。不过,还是要记得有“未来扩充性”的考虑! 之前鸟哥不是谈过吗,我的网卡由螃蟹卡换成 3Com 时,核心捉不到~ 因为...鸟哥并没有将 3Com 的网卡编译成为模块啊! @_@
```
# 大部分都保留默认值,鸟哥只是就比较重要的部份拿出来做说明而已!
<M> Serial ATA and Parallel ATA drivers ---> # 就是 SATA/IDE 磁盘!大多数选择为模块!
[*] Multiple devices driver support (RAID and LVM) ---> # 就是 LVM 与 RAID !要选要选!
-*- Network device support ---> # 网络方面的设备,网卡与相关媒体啦!
-*- Network core driver support
<M> Bonding driver support # 与网卡整合有关的项目!要选!
<M> Ethernet team driver support ---> # 与 bonding 差不多的功能!要选!
<M> Virtio network driver # 虚拟化的网卡驱动程序!要选!
-*- Ethernet driver support ---> # 以太网卡!里面的一堆 10G 卡要选!
<M> Chelsio 10Gb Ethernet support
<M> Intel(R) PRO/10GbE support
<M> PPP (point-to-point protocol) support# 与拨接有关的协定!
USB Network Adapters ---> # 当然全部编译为模块!
[*] Wireless LAN ---> # 无线网卡也相当重要!里面全部变成模块!
================================================================================
[ ] GPIO Support ---> # 若有需要使用类似树莓派、香蕉派才需要这东西!
<M> Multimedia support ---> # 多媒体设备,如影像撷取、广播声卡等等
Graphics support ---> # 显卡!如果是作为桌上型使用,这里就重要了!
<M> Sound card support ---> # 声卡,同样的,桌面电脑使用时,比较重要!
[*] USB support ---> # 就是 USB!下面几个内部的细项要注意是勾选的!
<*> xHCI HCD (USB 3.0) support
<*> EHCI HCD (USB 2.0) support
<*> OHCI HCD support
<*> UHCI HCD (most Intel and VIA) support
<M> InfiniBand support ---> # 较高阶的网络设备,速度通常达到 40Gb 以上!
<M> VFIO Non-Privileged userspace driver framework ---> # 作为 VGA passthrought 用!
[*] VFIO PCI support for VGA devices
[*] Virtualization drivers ---> # 虚拟化的驱动程序!
Virtio drivers ---> # 在虚拟机里面很重要的驱动程序项目!
[*] IOMMU Hardware Support ---> # 同样的与虚拟化相关性较高!
```
至于“ Firmware Drivers ”的项目,请视你的需求来选择~基本上就保留设置值即可!所以鸟哥这里就不显示啰!
* 文件系统的支持
文件系统的支持也是很重要的一项核心功能!因为如果不支持某个文件系统,那么我们的 Linux kernel 就无法认识,当然也就无法使用啦!例如 Quota, NTFS 等等特殊的 filesystem 。 这部份也是有够麻烦~因为涉及核心是否能够支持某些文件系统,以及某些操作系统支持的 partition table 项目。在进行选择时,也务必要特别的小心在意喔! 尤其是我们常常用到的网络操作系统 (NFS/Samba 等等),以及基础篇谈到的 Quota 等, 你都得要勾选啊!否则是无法被支持的。如果你有兴趣,也可以将 NTFS 的文件系统设置为可读写看看啰!
```
# 下面仅有列出比较重要及与默认值不同的项目而已喔!所以项目少很多!
<M> Second extended fs support # 默认已经不支持 ext2/ext3,这里我们将他加回来!
<M> Ext3 journalling file system support
[*] Default to 'data=ordered' in ext3 (NEW)
[*] Ext3 extended attributes (NEW)
[*] Ext3 POSIX Access Control Lists
<M> The Extended 4 (ext4) filesystem # 一定要有的支持
<M> Reiserfs support
<M> XFS filesystem support # 一定要有的支持!
[*] XFS Quota support
[*] XFS POSIX ACL support
[*] XFS Realtime subvolume support # 增加这一项好了!
<M> Btrfs filesystem support # 最好有支持!
[*] Quota support
<*> Quota format vfsv0 and vfsv1 support
<*> Kernel automounter version 4 support (also supports v3)
<M> FUSE (Filesystem in Userspace) support
DOS/FAT/NT Filesystems --->
<M> MSDOS fs support
<M> VFAT (Windows-95) fs support
(950) Default codepage for FAT # 要改成这样喔!中文支持!
(utf8) Default iocharset for FAT # 要改成这样喔!中文支持!
<M> NTFS file system support # 建议加上 NTFS 喔!
[*] NTFS write support # 让他可读写好了!
Pseudo filesystems ---> # 类似 /proc ,保留默认值
-*- Miscellaneous filesystems ---> # 其他文件系统的支持,保留默认值
[*] Network File Systems ---> # 网络文件系统!很重要!也要挑挑!
<M> NFS client support
<M> NFS server support
[*] NFS server support for NFS version 4
<M> CIFS support (advanced network filesystem, SMBFS successor)
[*] Extended statistics
[*] Provide CIFS client caching support
-*- Native language support ---> # 选择默认的语系
(utf8) Default NLS Option
<M> Traditional Chinese charset (Big5)
```
* 核心骇客、信息安全、密码应用
再接下来有个“Kernel hacking”的项目,那是与核心开发者比较有关的部分,这部分建议保留默认值即可, 应该不需要去修改他!除非你想要进行核心方面的研究喔。然后下面有个“ Security Options ”,那是属于信息安全方面的设置, 包括 SELinux 这个细部权限强化模块也在这里编入核心的!这个部份只要记得 SELinux 作为默认值,且务必要将 NSA SELinux 编进核心即可, 其他的细部请保留默认值。
另外还有“ Cryptographic API ”这个密码应用程序接口工具选项,以前的默认加密机制为 MD5,近年来则改用了 SHA 这种机制。 不过,反正默认已经将所有的加密机制编译进来了,所以也是可以保留默认值啦!都不需要额外修改就是了!
* 虚拟化与函数库
虚拟化是近年来非常热门的一个议题,因为计算机的能力太强,所以时常闲置在那边, 此时,我们可以通过虚拟化技术在一部主机上面同时启动多个操作系统来运行,这就是所谓的虚拟化。 Linux 核心已经主动的纳入虚拟化功能喔!而 Linux 认可的虚拟化使用的机制为 KVM (Kernel base Virtual Machine)。 至于常用的核心函数库也可以全部编为模块啰!
```
[*] Virtualization --->
--- Virtualization
<M> Kernel-based Virtual Machine (KVM) support
<M> KVM for Intel processors support
<M> KVM for AMD processors support
[*] Audit KVM MMU
[*] KVM legacy PCI device assignment support # 虽然已经有 VFIO,不过建议还是选起来!
<M> Host kernel accelerator for virtio net
================================================================================
Library routines --->
# 这部份全部保留默认值即可!
```
现在请回到如[图24.2.1](../Text/index.html#fig24.2.1) 的画面中,在下方设置处移动到“Save”的选项,点选该项目, 在出现的窗口中确认文件名为 .config 之后,直接按下“OK”按钮,这样就将刚刚处理完毕的选项给记录下来了。 接下来可以选择离开菜单画面,准备让我们来进行编译的行为啰。
要请你注意的是,上面的数据主要是适用在鸟哥的个人机器上面的, 目前鸟哥比较习惯使用原本 distributions 提供的默认核心,因为他们也会主动的进行更新, 所以鸟哥就懒的自己重编核心了~ ^_^
此外,因为鸟哥重视的地方在于“网络服务器与虚拟化服务器”上面,所以里头的设置少掉了相当多的个人桌上型 Linux 的硬件编译!所以,如果你想要编译出一个适合你的机器的核心, 那么可能还有相当多的地方需要来修正的!不论如何,请随时以 Help 那个选项来看一看内容吧!反正 Kernel 重编的概率不大!花多一点时间重新编译一次! 然后将该编译完成的参数文件储存下来,未来就可以直接将该文件叫出来读入了! 所以花多一点时间安装一次就好!那也是相当值得的!
';
24.1 编译前的任务:认识核心与取得核心源代码
最后更新于:2022-04-01 22:17:38
## 24.1 编译前的任务:认识核心与取得核心源代码
我们在[第一章](../Text/index.html)里面就谈过 Linux 其实指的是核心!这个“核心 (kernel)”是整个操作系统的最底层,他负责了整个硬件的驱动,以及提供各种系统所需的核心功能,包括防火墙机制、是否支持 LVM 或 Quota 等文件系统等等,这些都是核心所负责的!所以啰,在[第十九章](../Text/index.html)的开机流程中,我们也会看到 MBR 内的 loader 载入核心文件来驱动整个系统的硬件呢! 也就是说,如果你的核心不认识某个最新的硬件,那么该硬件也就无法被驱动,你当然也就无法使用该硬件啰!
### 24.1.1 什么是核心 (Kernel)
这已经是整个 Linux 基础的最后一篇了,所以,下面这些数据你应该都要“很有概念”才行~ 不能只是“好像有印象”~好了,那就复习一下核心的相关知识吧!
* Kernel
还记得我们在[第十章的 BASH shell](../Text/index.html) 提到过:计算机真正在工作的东西其实是“硬件”, 例如数值运算要使用到 CPU、数据储存要使用到硬盘、图形显示会用到显卡、音乐发声要有音效芯片、连接 Internet 可能需要网卡等等。那么如何控制这些硬件呢?那就是核心的工作了!也就是说,你所希望计算机帮你达成的各项工作, 都需要通过“核心”的帮助才行!当然啰,如果你想要达成的工作是核心所没有提供的, 那么你自然就没有办法通过核心来控制计算机使他工作啰!
举例来说,如果你想要有某个网络功能 (例如核心防火墙机制) ,但是你的核心偏偏忘记加进去这项功能, 那么不论你如何“卖力”的设置该网络套件,很抱歉!不来电!换句话说,你想要让计算机进行的工作,都必须要“核心有支持”才可以!这个标准不论在 Windows 或 Linux 这几个操作系统上都相同!如果有一个人开发出来一个“全新的硬件”,目前的核心不论 Windows 或 Linux 都不支持,那么不论你用什么系统,哈哈!这个硬件都是英雄无用武之地啦! 那么是否了解了“核心”的重要了呢?所以我们才需要来了解一下如何编译我们的核心啦!
那么核心到底是什么啊?其实核心就是系统上面的一个文件而已, 这个文件包含了驱动主机各项硬件的侦测程序与驱动模块。在[第十九章的开机流程分析](../Text/index.html)中,我们也提到这个文件被读入内存的时机, 当系统读完 BIOS 并载入 MBR 内的开机管理程序后,就能够载入核心到内存当中。然后核心开始侦测硬件, 挂载根目录并取得核心模块来驱动所有的硬件,之后调用 systemd 就能够依序启动所有系统所需要的服务了!
这个核心文件通常被放置成 /boot/vmlinuz-xxx ,不过也不见得, 因为一部主机上面可以拥有多个核心文件,只是开机的时候仅能选择一个来载入而已。 甚至我们也可以在一个 distribution 上面放置多个核心,然后以这些核心来做成多重开机呢!
* 核心模块 (kernel module) 的用途
既然核心文件都已经包含了硬件侦测与驱动模块,那么什么是核心模块啊?要注意的是, 现在的硬件更新速度太快了,如果我的核心比较旧,但我换了新的硬件,那么,这个核心肯定无法支持! 怎么办?重新拿一个新的核心来处理吗?开玩笑~核心的编译过程可是很麻烦的~
所以啰,为了这个缘故,我们的 Linux 很早之前就已经开始使用所谓的模块化设置了! 亦即是将一些不常用的类似驱动程序的咚咚独立出核心,编译成为模块,然后, 核心可以在系统正常运行的过程当中载入这个模块到核心的支持。如此一来, 我在不需要更动核心的前提之下,只要编译出适当的核心模块,并且载入他,呵呵!我的 Linux 就可以使用这个硬件啦!简单又方便!
那我的模块放在哪里啊?可恶!怎么会问这个傻问题呢?当然一定要知道的啦!就是 /lib/modules/$(uname -r)/kernel/ 当中啦!
* 自制核心 - 核心编译
刚刚上面谈到的核心其实是一个文件,那么这个文件怎么来的?当然是通过源代码 (source code) 编译而成的啊!因为核心是直接被读入到内存当中的,所以当然要将他编译成为系统可以认识的数据才行!也就是说, 我们必须要取得核心的源代码,然后利用[第二十一章 Tarball](../Text/index.html) 安装方式提到的编译概念来达成核心的编译才行啊!(这也是本章的重点啊! ^_^)
* 关于驱动程序 - 是厂商的责任还是核心的责任?
现在我们知道硬件的驱动程序可以编译成为核心模块,所以可以在不改变核心的前提下驱动你的新硬件。 但是,很多朋友还是常常感到困惑,就是 Linux 上面针对最新硬件的驱动程序总是慢了几个脚步, 所以觉得好像 Linux 的支持度不足!其实不可以这么说的,为什么呢?因为在 Windows 上面,对于最新硬件的驱动程序需求,基本上,也都是厂商提供的驱动程序才能让该硬件工作的, 因此,在这个“驱动程序开发”的工作上面来说,应该是属于硬件发展厂商的问题, 因为他要我们买他的硬件,自然就要提供消费者能够使用的驱动程序啦!
所以,如果大家想要让某个硬件能够在 Linux 上面跑的话,那么似乎可以发起一人一信的方式,强烈要求硬件开发商发展 Linux 上面的驱动程序!这样一来,也可以促进 Linux 的发展呢!
### 24.1.2 更新核心的目的
除了 BIOS (或 UEFI) 之外,核心是操作系统中最早被载入到内存的咚咚, 他包含了所有可以让硬件与软件工作的信息,所以,如果没有搞定核心的话, 那么你的系统肯定会有点小问题!好了,那么是不是将“所有目前核心有支持的东西都给他编译进去我的核心中, 那就可以支持目前所有的硬件与可执行的工作啦!”!
这话说的是没错啦,但是你是否曾经看过一个为了怕自己今天出门会口渴、会饿、会冷、会热、会被车撞、 会摔跤、会被性骚扰,而在自己的大包包里面放了大瓶矿泉水、便当、厚外套、短裤、防撞钢梁、止滑埝、 电击棒....等一大堆东西,结果却累死在半路上的案例吗?当然有!但是很少啦!我相信不太有人会这样做! (会这么做的人通常都已经在医院了~) 取而代之的是会看一下天气,冷了就只带外套, 热了就只带短衣、如果穿的漂亮一点又预计晚点回家就多带个电击棒、 出远门到没有便利商店的地方才多带矿泉水....
说这个干什么!对啦!就是要你了解到,核心的编译重点在于“你要你的 Linux 作什么?”,是啦!如果没有必要的工作,就干脆不要加在你的核心当中了!这样才能让你的 Linux 跑得更稳、更顺畅!这也是为什么我们要编译核心的最主要原因了!
* Linux 核心特色,与默认核心对终端用户的角色
Linux 的核心有几个主要的特色,除了“Kernel 可以随时、随各人喜好而更动”之外,Kernel 的“版本更动次数太频繁”也是一个特点!所以啰,除非你有特殊需求, 否则一次编译成功就可以啦!不需要随时保持最新的核心版本,而且也没有必要 (编译一次核心要粉久的ㄋㄟ!) 。
那么是否“我就一定需要在安装好了 Linux 之后就赶紧给他编译核心呢?”, 老实说,“并不需要的”!这是因为几乎每一个 distribution 都已经默认编译好了相当大量的模块了, 所以使用者常常或者可能会使用到的数据都已经被编译成为模块,也因此,呵呵! 我们使用者确实不太需要重新来编译核心!尤其是“一般的使用者, 由于系统已经将核心编译的相当的适合一般使用者使用了,因此一般入门的使用者,基本上, 不太需要编译核心”。
* 核心编译的可能目的
OK!那么鸟哥闲闲没事干跑来写个什么东西?既然都不需要编译核心还写编译核心的分享文章, 鸟哥卖弄才学呀?很抱歉,鸟哥虽然是个“不学有术”的混混,却也不会平白无故的写东西请您来指教~ 当然是有需要才会来编译核心啦!编译核心的时机可以归纳为几大类:
* 新功能的需求:
我需要新的功能,而这个功能只有在新的核心里面才有,那么为了获得这个功能,只好来重新编译我的核心了。例如 iptables 这个防火墙机制只有在 2.4.xx 以后的版本里面才有,而新开发的主板芯片组, 很多也需要新的核心推出之后,才能正常而且有效率的工作!
* 原本核心太过臃肿:
如果你是那种对于系统“稳定性”很要求的人,对于核心多编译了很多莫名其妙的功能而不太喜欢的时候, 那么就可以重新编译核心来取消掉该功能啰;
* 与硬件搭配的稳定性:
由于原本 Linux 核心大多是针对 Intel 的 CPU 来作开发的,所以如果你的 CPU 是 AMD 的系统时,有可能 (注意!只是有可能,不见得一定会如此) 会让系统跑得“不太稳!”。此外,核心也可能没有正确的驱动新的硬件,此时就得重新编译核心来让系统取得正确的模块才好。
* 其他需求 (如嵌入式系统):
就是你需要特殊的环境需求时,就得自行设计你的核心啰!( 像是一些商业的套装软件系统,由于需要较为小而美的操作系统, 那么他们的核心就需要更简洁有力了!)
![鸟哥的图示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** 话说,2014 年鸟哥为了要搞定 banana pi (一种单版计算机,或者可以称为手机的硬件拿来作 Linux 安装的硬件) 的 CPU 最高频率限制, 因为该限制是直接写入到 Linux 核心当中的,这时就只好针对该硬件的 Linux 核心,修改不到 10 行的程序码之后,重新编译! 才能将原本限制到 900MHz 的频率提升到 1.2GHz 哩!
另外,需要注意重新编译核心虽然可以针对你的硬件作最优化的步骤 (例如刚刚提到的 CPU 的问题!) ,不过由于这些最优化的步骤对于整体性能的影响是很小很小的, 因此如果是为了增加性能来编译核心的话,基本上,效益不大!然而,如果是针对“系统稳定性”来考虑的话, 那么就有充分的理由来支持你重新编译核心啰!
“如果系统已经运行很久了,而且也没有什么大问题, 加上我又不增加冷门的硬件设备,那么建议就不需要重新编译核心了”, 因为重新编译核心的最主要目的是“想让系统变的更稳!”既然你的 Linux 主机已经达到这个目的了,何必再编译核心?不过,就如同前面提到的, 由于默认的核心不见得适合你的需要,加上默认的核心可能并无法与你的硬件配备相配合, 此时才开始考虑重新编译核心吧!
![鸟哥的图示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** 早期鸟哥是强调最好重新编译核心的一群啦!不过,这个想法改变好久了~ 既然原本的 distribution 都已经帮我们考虑好如何使用核心了,那么, 我们也不需要再重新的编译核心啦!尤其是 distribution 都会主动的释出新版的核心 RPM 版本, 所以,实在不需要自己重新编译的!当然啦,如同前面提到的,如果你有特殊需求的话,那就另当别论噜! ^_^
由于“核心的主要工作是在控制硬件!”所以编译核心之前, 请先了解一下你的硬件配备,与你这部主机的未来功能!由于核心是“越简单越好!”所以只要将这部主机的未来功能给他编进去就好了! 其他的就不用去理他啦!
### 24.1.3 核心的版本
核心的版本问题,我们在[第一章](../Text/index.html#torvalds_team)已经谈论过, 目前 CentOS 7 使用的 3.10.x 版本为长期维护版本,不过理论上我们也可以升级到后续的主线版本上面!不会像以前 2.6.x 只能升级到 2.6.x 的后续版本, 而不能改成其他主线版本。不过这也只是“理论上”而已,因为目前许多的软件依旧与核心版本有关,例如那个虚拟化软件 qemu 之类的, 与核心版本之间是有搭配性的关系的,所以,除非你要一口气连同核心相依的软件通通升级,否则最好使用长期维护版本的最新版来处理较佳。
举例来说,CentOS 7 使用的是 3.10.0 这个长期版本,而目前 (2015/09) 这个 3.10 长期版本,最新的版本为 3.10.89,意思是说, 你最好是拿 3.10.89 来作为核心升级的依据,而不是拿最新的 4.2.1 来升级的意思。
虽然理论上还是拿自家长期维护版本的最新版本来处理比较好,不过鸟哥因为需要研究虚拟化的 PCI passthrough 技术, 确实也曾经在 CentOS 7.1 的系统中将 3.10.x 的版本升级到 4.2.3 这个版本上!这样才完成了 VGA 的 PCI passthrough 功能! 所以说,如果你真的想要使用较新的版本来升级,也不是不可以,只是后果会发生什么问题,就得要自行负责啰!
### 24.1.4 核心源代码的取得方式
既然核心是个文件,要制作这个文件给系统使用则需要编译,既然要有编译,当然就得要有源代码啊! 那么源代码怎么来?基本上,依据你的 distributions 去挑选的核心源代码来源主要有:
* 原本 distribution 提供的核心源代码文件
事实上,各主要 distributions 在推出他们的产品时,其实已经都附上了核心源代码了! 不过因为目前数据量太庞大,因此 SRPM 默认已经不给映射站下载了!主要的源代码都放置于下面的网站上:
* 全部的 CentOS 原始 SRPM:[http://vault.centos.org/](http://vault.centos.org/)
* CentOS 7.1 的 SRPM:[http://vault.centos.org/7.1.1503/](http://vault.centos.org/7.1.1503/)
CentOS 7.x 开始的版本中,其版本后面会接上释出的日期,因为 CentOS 7.1 是 2015/03 释出的,因此它的下载点就会是在 7.1.1503 啰!1503 指的就是 2015/03 的意思~ 你可以进入上述的网站后,到 updates 目录下,一层一层的往下找,就可以找到 kernel 相关的 SRPM 啰!
你或许会说:既然要重新编译,那么干嘛还要使用原本 distributions 释出的源代码啊?真没创意~ 话不是这么说,因为原本的 distribution 释出的源代码当中,含有他们设置好的默认设置值, 所以,我们可以轻易的就了解到当初他们是如何选择与核心及模块有关的各项设置项目的参数值, 那么就可以利用这些可以配合我们 Linux 系统的默认参数来加以修改,如此一来, 我们就可以“修改核心,调整到自己喜欢的样子”啰!而且编译的难度也会比较低一点!
* 取得最新的稳定版核心源代码
虽然使用 distribution 释出的核心 source code 来重新编译比较方便,但是,如此一来, 新硬件所需要的新驱动程序,也就无法借由原本的核心源代码来编译啊! 所以啰,如果是站在要更新驱动程序的立场来看,当然使用最新的核心可能会比较好啊!
Linux 的核心目前是由其发明者 Linus Torvalds 所属团队在负责维护的,而其网站在下面的站址上,在该网站上可以找到最新的 kernel 信息!不过,美中不足的是目前的核心越来越大了 (linux-3.10.89.tar.gz 这一版,这一个文件大约 105MB 了!),所以如果你的 ISP 连外很慢的话,那么使用台湾的映射站台来下载不失为一个好方法:
* [核心官网:http://www.kernel.org/](http://www.kernel.org/pub/linux/kernel/)
* [交大资科:ftp://linux.cis.nctu.edu.tw/kernel/linux/kernel/](ftp://linux.cis.nctu.edu.tw/kernel/linux/kernel/)
* [国高中心:ftp://ftp.twaren.net/pub/Unix/Kernel/linux/kernel/](ftp://ftp.twaren.net/pub/Unix/Kernel/linux/kernel/)
* 保留原本设置:利用 patch 升级核心源代码
如果 (1)你曾经自行编译过核心,那么你的系统当中应该已经存在前几个版本的核心源代码, 以及上次你自行编译的参数设置值才对; (2)如果你只是想要在原本的核心下面加入某些特殊功能, 而该功能已经针对核心源代码推出 patch 补丁文件时。那你该如何进行核心源代码的更新,以便后续的编译呢?
其实每一次核心释出时,除了释出完整的核心压缩文件之外,也会释出“该版本与前一版本的差异性 patch 文件”, 关于 patch 的制作我们已经在[第二十一章](../Text/index.html#tarball_patch)当中提及, 你可以自行前往参考。这里仅是要提供给你的信息是,每个核心的 patch 仅有针对前一版的核心来分析而已, 所以,万一你想要由 3.10.85 升级到 3.10.89 的话,那么你就得要下载 patch-3.10.86, patch-3.10.87, patch-3.10.88, patch-3.10.89 等文件,然后“依序”一个一个的去进行 patch 的动作后, 才能够升级到 3.10.89 喔!这个重要!不要忘记了。
同样的,如果是某个硬件或某些非官方认定的核心添加功能网站所推出的 patch 文件时,你也必须要了解该 patch 文件所适用的核心版本,然后才能够进行 patch ,否则容易出现重大错误喔!这个项目对于某些商业公司的工程师来说是很重要的。 举例来说,鸟哥的一个高中同学在业界服务,他主要是进行类似 Eee PC 开发的计划,然而该计划的硬件是该公司自行推出的! 因此,该公司必须要自行搭配核心版本来设计他们自己的驱动程序,而该驱动程序并非 GPL 授权,因此他们就得要自行将驱动程序整合进核心!如果改天他们要将这个驱动程序释出,那么就得要利用 patch 的方式, 将硬件驱动程序文件释出,我们就得要自行以 patch 来更新核心啦!
在进行完 patch 之后,你可以直接检查一下原本的设置值,如果没有问题, 就可以直接编译,而不需要再重新的选择核心的参数值,这也是一个省时间的方法啊! 至于 patch file 的下载,同样是在 kernel 的相同目录下,寻找文件名是 patch 开头的就是了。
### 24.1.5 核心源代码的解压缩/安装/观察
其实,不论是从 CentOS 官网取得的 SRPM 或者是从 Linux kernel 官网取得的 tarball 核心源代码,最终都会有一个 tarball 的核心源代码就是了! 因此,鸟哥从 linux kernel 官网取得 linux-3.10.89.tar.xz 这个核心文件,这个核心文件的源代码是从下面的网址取得的:
* [ftp://ftp.twaren.net/pub/Unix/Kernel/linux/kernel/v3.x/linux-3.10.89.tar.xz](ftp://ftp.twaren.net/pub/Unix/Kernel/linux/kernel/v3.x/linux-3.10.89.tar.xz)
* 核心源代码的解压缩与放置目录
鸟哥这里假设你也是下载上述的链接内的文件,然后该文件放置到 /root 下面。由于 Linux 核心源代码一般建议放置于 /usr/src/kernels/ 目录下面,因此你可以这样处理:
```
[root@study ~]# tar -Jxvf linux-3.10.89.tar.xz -C /usr/src/kernels/
```
此时会在 /usr/src/kernels 下面产生一个新的目录,那就是 linux-3.10.89 这个目录啰! 我们在下个小节会谈到的各项编译与设置,都必须要在这个目录下面进行才行喔!好了,那么这个目录下面的相关文件有啥咚咚? 下面就来谈谈:
* 核心源代码下的次目录
在上述核心目录下含有哪些重要数据呢?基本上有下面这些东西:
* arch :与硬件平台有关的项目,大部分指的是 CPU 的类别,例如 x86, x86_64, Xen 虚拟支持等;
* block :与区块设备较相关的设置数据,区块数据通常指的是大量储存媒体!还包括类似 ext3 等文件系统的支持是否允许等。
* crypto :核心所支持的加密的技术,例如 md5 或者是 des 等等;
* Documentation :与核心有关的一堆说明文档,若对核心有极大的兴趣,要瞧瞧这里!
* drivers :一些硬件的驱动程序,例如显卡、网卡、PCI 相关硬件等等;
* firmware :一些旧式硬件的微指令码 (固件) 数据;
* fs :核心所支持的 filesystems ,例如 vfat, reiserfs, nfs 等等;
* include :一些可让其他程序调用的标头 (header) 定义数据;
* init :一些核心初始化的定义功能,包括挂载与 init 程序的调用等;
* ipc :定义 Linux 操作系统内各程序的沟通;
* kernel :定义核心的程序、核心状态、线程、程序的调度 (schedule)、程序的讯号 (signle) 等
* lib :一些函数库;
* mm :与内存单元有关的各项数据,包括 swap 与虚拟内存等;
* net :与网络有关的各项协定数据,还有防火墙模块 (net/ipv4/netfilter/*) 等等;
* security :包括 selinux 等在内的安全性设置;
* sound :与音效有关的各项模块;
* virt :与虚拟化机器有关的信息,目前核心支持的是 KVM (Kernel base Virtual Machine)
这些数据先大致有个印象即可,至少未来如果你想要使用 patch 的方法加入额外的新功能时, 你要将你的源代码放置于何处?这里就能够提供一些指引了。当然,最好还是跑到 Documentation 那个目录下面去瞧瞧正确的说明, 对你的核心编译会更有帮助喔!
';
第二十四章、Linux 核心编译与管理
最后更新于:2022-04-01 22:17:36
# 第二十四章、Linux 核心编译与管理
最近更新日期:20//
我们说的 Linux 其实指的就是核心 (kernel) 而已。这个核心控制你主机的所有硬件并提供系统所有的功能, 所以说,他重不重要啊!我们开机的时候其实就是利用开机管理程序载入这个核心文件来侦测硬件, 在核心载入适当的驱动程序后,你的系统才能够顺利的运行。现今的系统由于强调线上升级机制,因此非常不建议自订核心编译! 但是,如果你想要将你的 Linux 安装到 U盘、想要将你的 Eee PC 小笔记本安装自己的 Linux , 想让你的 Linux 可以驱动你的小家电,此时,核心编译就是相当重要的一个任务了! 这一篇比较进阶,如果你对系统移植没有兴趣的话,这一篇可以先略过喔! ^_^
';
23.6 参考资料与延伸阅读
最后更新于:2022-04-01 22:17:34
## 23.6 参考资料与延伸阅读
* [[1]](#ac1)维基百科对 X Window 的介绍:[http://en.wikipedia.org/wiki/X_Window_System](http://en.wikipedia.org/wiki/X_Window_System)
* [[2]](#ac2)X Server/X client 与网络相关性的参考图示:
[http://en.wikipedia.org/wiki/File:X_client_sever_example.svg](http://en.wikipedia.org/wiki/File:X_client_sever_example.svg)
* [[3]](#ac3)系统的 man page: man xinit 、 man Xorg 、 man startx
* [[4]](#ac4)一些与中文字体有关的网页链接:
洪朝贵老师评论员的字体设置:[http://www.cyut.edu.tw/~ckhung/b/gnu/font.php](http://www.cyut.edu.tw/~ckhung/b/gnu/font.php)
* X 相关的官方网站: X.org 官方网站 ([http://www.x.org/](http://www.x.org/))、 XFree86 官方网站 ([http://www.xfree86.org/](http://www.xfree86.org/))
2003/02/12:第一次完成
2005/06/29:将旧的文章移动到 [这里](http://linux.vbird.org/linux_basic/0590xwindow/0590xwindow.php) 。如果你需要旧版的 xf86config 与相关的工具,则请前往该旧文章查阅!
2005/07/11:经历了许多的时间,将主机的配置文件重复改了改,终于完成一些简单的 X 测试!
2006/11/07:经由网友[x1215 这一篇](http://phorum.vbird.org/viewtopic.php?t=27157)的介绍,得知该网站,赶紧去处理!
2009/07/03:将旧版基于 FC4 的版本移动到[此处](http://linux.vbird.org/linux_basic/0590xwindow/0590xwindow-fc4.php)
2009/07/15:奋战好几天,将驱动程序安装加上,同时加入字体管理功能。
2009/07/28:网友 LazyBug Chan 兄热情回报,使用 XFCE 的 Ubuntu 是 Xubuntu 这个分支!感谢回报!
2009/08/07:加入 Window Manger 的全名与链接
2015/09/11:将旧的基于 CentOS 5.x 的版本移动到 [此处](http://linux.vbird.org/linux_basic/0590xwindow//0590xwindow/0590xwindow-centos5.php)
';
23.5 本章习题
最后更新于:2022-04-01 22:17:31
## 23.5 本章习题
( 要看答案请将鼠标移动到“答:”下面的空白处,按下左键圈选空白处即可察看 )
* 在 X 设置没问题的情况下,你在 Linux 主机如何取得窗口接口?如果是在 multi-user.target 模式下,可以使用 startx 进入,至于 graphical.target ,则直接进入 tty1 即可使用 display manager 登陆 X Window 系统。
* 利用 startx 可以在 multi-user.target 的环境下进入 X Window 系统。请问 startx 的主要功能?整个 X 窗口系统的重点在启动 X server 并载入 X client ,而执行 X server/X client 调用的任务为 xinit ,startx 只是一个较为友好的脚本程序,可以搜寻系统上面的 X server / X client 设置值, 以提供 xinit 来执行而已。
* 如何知道你系统当中 X 系统的版本与计划?最简单可以利用 root 的身份下达 X -version 或 Xorg -version 即可知道!
* 要了解为何 X 系统可以允许不同硬件、主机、操作系统之间的沟通,需要知道 X server / X client 的相关知识。 请问 X Server / X client / Window manager 的主要用途功能?X Server 主要负责屏幕的绘制,以及周边输入设备如鼠标、键盘等数据的收集,并回报给 X Client ; X Client 主要负责数据的运算,收到来自 X Server 的数据后,加以运算得到图形的数据,并回传给 X Server, 让 X server 自行绘制图形。至于 Window manager 是一个比较特殊的 X Client ,他可以管理更多控制元素, 最重要的地方还是在于窗口的大小、重叠、移动等等的功能。
* 如何重新启动 X
* 最简单在 X Window System 下,直接按下 [alt]+[ctrl]+[backspace<--] 即可
* 也可以 systemctl isolate multi-usertarget 再 systemctl isolate graphical.target
* 也可以关闭 X 后,再 startx 启动等等。
* 试说明 ~/.xinitrc 这个文件的用途?当我们要启动 X 时,必须要启动 X Client 软件端。这个 ~/.xinitrc 即是在客制化自己的 X Client , 你可以在这个文件内输入你自己的 X Client 。若无此文件,则默认以 /etc/X11/xinit/xinitrc 替代。
* 我在 CentOS 的系统中,默认使用 GNOME 登陆 X 。但我想要改以 KDE 登陆,该怎么办?
* 首先你必须要已经安装 KDE 环境 (参考前一章的 yum grouplist 功能),
* 然后可以借由修改 /etc/sysconfig/desktop 内的设置值即可。
* 但如果你不是 root 无法修订该文件时,亦可以在自己的主文件夹参考 /etc/X11/xinit/xinitrc 的内容自行制作 ~/.xinitrc 文件来修改!
* X Server 的 port 默认开放在?目前默认并不会启动 TCP 端口。不过如果经过设置,则 X port 默认开放在 port 6000 ,而且称此一显示为 :0
* Linux 主机是否可以有两个以上的 X是的!可以!第一个 X 通常在 tty1 ,第二个在 tty2 以后,依序类推。 第几个是以启动的顺序来定义,并非 :0 , :1 的意思~
* X Server 的配置文件是 xorg.conf,在该文件中, Section Files 干嘛用的?相当重要!是设置显示字体用的。而字体一般放置目录在 /usr/share/X11/fonts/ 及 /usr/share/fonts/ 当中。
* 我发现我的 X 系统键盘所输入的字母老是打不出我所需要的单字,可能原因该如何修订?应该是键盘符号对应表跑掉了。可以修改 xorg.conf 文件内, 关于 Keyboard 的 Option XkbLayout 项目,将他改为 us 即可!
* 当我的系统内有安装 GNOME 及 KDE 两个 X Widnow Manager ,我原本是以 KDE 为默认的 WM, 若想改为 GNOME 时,应该如何修改?修改 /etc/sysconfig/desktop 内部,成为 GNOME 即可!
';
23.4 重点回顾
最后更新于:2022-04-01 22:17:29
## 23.4 重点回顾
* Unix Like 操作系统上面的 GUI 使用的是最初由 MIT 所开发的 X window system,在 1987 释出 X11 版,并于 1994 更改为 X11R6 ,故此 GUI 接口也被称为 X 或 X11
* X window system 的 X server 最初由 XFree86 计划所开发,后来则由 Xorg 基金会所持续开发;
* X window system 主要分为 X server 与 X client ,其中 X Server 在管理硬件,而 X Client 则是应用程序。
* 在运行上,X Client 应用程序会将所想要呈现的画面告知 X Server ,最终由 X server 来将结果通过他所管理的硬件绘制出来!
* 每一支 X client 都不知道对方的存在,必须要通过特殊的 X client ,称为 Window Manager 的, 来管理各窗口的重叠、移动、最小化等工作。
* 若有需要登陆图形接口,有时会有 Display Manager 来管理这方面的动作
* startx 可以侦测 X server / X client 的启动脚本,并调用 xinit 来分别执行;
* X 可以启动多个,各个 X 显示的位置使用 -display 来处理,显示位置为 :0, :1...
* Xorg 是一个 X server ,配置文件位于 /etc/X11/xorg.conf ,里面含有 Module, Files, Monitor, Device 等设置阶段。目前较新的设置中, 会将额外的设置放置于 /etc/X11/xorg.conf.d/*.conf
';
23.3 显卡驱动程序安装范例
最后更新于:2022-04-01 22:17:27
## 23.3 显卡驱动程序安装范例
虽然你的 X 窗口系统已经顺利的启动了,也调整到你想要的分辨率了,不过在某些场合下面,你想要使用显卡提供的 3D 加速功能时,却发现 X 提供的默认的驱动程序并不支持!此时真是欲哭无泪啊~那该如何是好?没关系,安装官方网站提供的驱动程序即可! 目前 (2015) 世界上针对 x86 提供显卡的厂商最大的应该是 Nvidia / AMD (ATI) / Intel 这三家 (没有照市占率排列), 所以下面鸟哥就针对这三家的显卡驱动程序安装,作个简单的介绍吧!
由于硬件驱动程序与核心有关,因此你想要安装这个驱动程序之前,请务必先参考[第二十一章](../Text/index.html)与[第二十二章](../Text/index.html)的介绍,才能够顺利的编译出显卡驱动程序喔! 建议可以直接使用 yum 去安装“ Development Tools ”这个软件群组以及 kernel-devel 这个软件即可。
![鸟哥的图示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** 因为你得要有实际的硬件才办法安装这些驱动程序,因此下面鸟哥使用的则是实体机器上面装有个别的显卡的设备,就不是使用虚拟机了喔!
### 23.3.1 NVidia
虽然 Xorg 已经针对 NVidia 公司的显卡驱动程序提供了 "nouveau" 这个模块,不过这个模块无法提供很多额外的功能。 因此,如果你想要使用新的显卡功能时,就得要额外安装 NVidia 提供的给 Linux 的驱动程序才行。
至于 NVidai 虽然有提供驱动程序给大家使用,不过他们并没有完全释出,因此自由软件圈不能直接拿人家的东西来重新开发! 不过还是有很多好心人士有提供相关的软件库给大家使用啦!你可以自行 google 查阅相关的软件库 (比较可惜的是,EPEL 里面并没有 NVidia 官网释出的驱动程序就是了!)所以,下面我们还是使用传统的从 NVidia 官网上面下载相关的软件来安装的方式喔!
* 查询硬件与下载驱动程序
你得要先确认你的硬件为何才可以下载到正确的驱动程序啊!简单查询的方法可以使用 lspci 喔!还不需要拆主机机箱啦!
```
[root@study ~]# lspci | grep -Ei '(vga|display)'
00:02.0 Display controller: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor Integrated
Graphics Controller (rev 06)
01:00.0 VGA compatible controller: NVIDIA Corporation GF119 [GeForce GT 610] (rev a1)
# 鸟哥选的这部实体机器测试中,其实有内置 Intel 显卡以及 NVidia GeForece GT610 这两张卡!
# 屏幕则是接在 NVidia 显卡上面喔!
```
建议你可以到 NVidia 的官网 ([http://www.nvidia.com.tw](http://www.nvidia.com.tw/)) 自行去下载最新的驱动程序,你也可以到下面的链接直接查阅给 Linux 用的驱动程序:
* [http://www.nvidia.com.tw/object/unix_tw.html](http://www.nvidia.com.tw/object/unix_tw.html)
请自行选择与你的系统相关的环境。现在 CentOS 7 都仅有 64 位啊!所以不要怀疑,就是选择 Linux x86_64/AMD64/EM64T 的版本就对了! 不过还是得要注意你的 GPU 是旧的还是新的喔~像鸟哥刚刚查到上面使用的是 GT610 的显卡,那使用最新长期稳定版就可以了! 鸟哥下载的版本文件名有点像: NVIDIA-Linux-x86_64-352.41.run,我将这文件名放置在 /root 下面喔!接下来就是这样作:
* 系统升级与取消 nouveau 模块的载入
因为这部系统是新安装的,所以没有我们虚拟机里面已经安装好所有需要的环境了。因此,我们建议你最好是做好系统升级的动作, 然后安装所需要的编译环境,最后还得要将 nouveau 模块排除使用!因为强迫系统不要使用 nouveau 这个驱动,这样才能够完整的让 nvidia 的驱动程序运行! 那就来瞧瞧怎么作啰!
```
# 1\. 先来全系统升级与安装所需要的编译程序与环境;
[root@study ~]# yum update
[root@study ~]# yum groupinstall "Development Tools"
[root@study ~]# yum install kernel-devel kernel-headers
# 2\. 开始处理不许载入 nouveau 模块的动作!
[root@study ~]# vim /etc/modprobe.d/blacklist.conf # 这文件默认应该不存在
blacklist nouveau
options nouveau modeset=0
[root@study ~]# vim /etc/default/grub
GRUB_CMDLINE_LINUX="vconsole.keymap=us crashkernel=auto vconsole.font=latarcyrheb-sun16
rhgb quiet rd.driver.blacklist=nouveau nouveau.modeset=0"
# 在 GRUB_CMDLINE_LINUX 设置里面加上 rd.driver.blacklist=nouveau nouveau.modeset=0 的意思!
[root@study ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
[root@study ~]# reboot
[root@study ~]# lsmod | grep nouveau
# 最后要没有出现任何模块才是对的!
```
* 安装驱动程序
要完成上述的动作之后才能够处理下面的行为喔!(文件名依照你的环境去下载与执行):
```
[root@study ~]# systemctl isolate multi-user.target
[root@study ~]# sh NVIDIA-Linux-x86_64-352.41.run
# 接下来会出现下面的数据,请自行参阅图示内容处理啰!
```
![Nvidia 官网驱动程序相关设置画面示意](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_57357380d91a5.jpg)图23.3.1-1、Nvidia 官网驱动程序相关设置画面示意
上面说的是授权,你必须要接受 (Accept) 才能继续。
![Nvidia 官网驱动程序相关设置画面示意](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735738106f3f.jpg)图23.3.1-2、Nvidia 官网驱动程序相关设置画面示意
要不要安装 32 位相容的函数库,鸟哥个人是认为还是装一下比较好啦!
![Nvidia 官网驱动程序相关设置画面示意](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735738119558.jpg)图23.3.1-3、Nvidia 官网驱动程序相关设置画面示意
让这支安装程序主动的去修改 xorg.conf 吧!比较轻松愉快!就按下 Yes 即可。
最后按下 OK 就结束安装啰!这个时候如果你去查阅一下 /etc/X11/xorg.conf 的内容,会发现 Device 的 Driver 设置会成为 nvidia 喔!这样就搞定啰!很简单吧! 而且这个时候你的 /usr/lib64/xorg/modules/drivers 目录内,会多出一个 nvidia_drv.so 的驱动程序文件啰! 同时这个软件还提供了一支很有用的程序来帮助我们进行驱动程序升级喔!
```
[root@study ~]# nvidia-installer --update
# 可以进行驱动程序的升级检查喔!
```
好啰,那你就赶紧试看看新的显卡芯片的功能吧。而如果有什么疑问的话,查阅一下 /var/log/nvidia* 开头的登录文件看看吧! ^_^
### 23.3.2 AMD (ATI)
AMD 的显卡 (ATI) 型号也很多,不过因为 AMD 的显卡有提供成为 Open Source ,目前有个名为 ELrepo 的网站有主动提供 AMD 的显卡驱动喔! 而且是针对我们 CentOS 7 耶~好像还不赖~其实 ELrepo 也提供了 NVidia 的驱动程序啦!只是型号太多,所以鸟哥还是使用 NVidia 官网的数据来教学而已。
那如何取得 ELrepo 呢?这个网站主文件夹在下面,你可以自己瞧一瞧,至于安装 ELrepo 的 yum 配置文件方式如下:
* [http://elrepo.org](http://elrepo.org/)
```
[root@study ~]# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
[root@study ~]# rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
[root@study ~]# yum clean all
[root@study ~]# yum --enablerepo elrepo-testing search fglrx
kmod-fglrx.x86_64 : fglrx kernel module(s)
fglrx-x11-drv.x86_64 : AMD's proprietary driver for ATI graphic cards # 这就对了!
fglrx-x11-drv-32bit.x86_64 : Compatibility 32-bit files for the 64-bit Proprietary AMD driver
fglrx-x11-drv-devel.x86_64 : Development files for AMD OpenGL X11 display driver.
[root@study ~]# yum --enablerepo elrepo-testing install fglrx-x11-drv
# 很快的!这样就安装好了 AMD 的显卡驱动程序了耶!超开心的吧!
```
安装完毕后,系统就会在 /usr/lib64/xorg/modules/drivers/ 里面出现 fglrx_drv.so 这个新的驱动程序啦! 与 Nvidia 相同的, ATI 也提供一支名为 aticonfig 的指令来帮忙设置 xorg.conf ,你可以直接输入“ aticonfig -v ”来看看处理的方式即可。然后你就可以重新启动 X 来看看新的驱动程序功能啰!非常简单吧!
### 23.3.3 Intel
老实说,由于 Intel 针对 Linux 的图形接口驱动程序已经开放成为 Open source 了,所以理论上你不需要重新安装 Intel 的显卡驱动程序的。除非你想要使用比默认的更新的驱动程序,那么才需要重新安装下面的驱动程序。 Intel 对 Linux 的显卡驱动程序已经有独立的网站在运行,如下的链接就是安装的说明网页:
* [https://01.org/zh/linuxgraphics](https://01.org/zh/linuxgraphics)
其实 Intel 的显卡用的地方非常的多喔!因为只要是整合型主板芯片组,用的是 Intel 的芯片时, 通常都整合了 Intel 的显卡啰~鸟哥使用的一组 cluster 用的就是 Intel 的芯片,所以啰~ 这家伙也是用的到的啦!
一般来说, Intel 的显卡都常常会使用 i910 等驱动程序,而不是这个较新的 intel 驱动程序! 你可以察看一下你系统是否有存在这些文件:
```
[root@study ~]# locate libdrm
/usr/lib64/libdrm.so.2
/usr/lib64/libdrm.so.2.4.0
/usr/lib64/libdrm_intel.so.1 # 就是这几个怪东西!
/usr/lib64/libdrm_intel.so.1.0.0
.....(下面省略).....
[root@study ~]# locate intel | grep xorg
/usr/lib64/xorg/modules/drivers/intel_drv.so
# 上面这个就是 Intel 的显卡驱动程序了!
```
呼呼!我们的 CentOS 有提供新的 Intel 显卡驱动程序啦!所以不需要重新安装说~ 只是可能需要修改 xorg.conf 这个配置文件的内容。基本上,要修改的地方有:
```
[root@study ~]# vi /etc/X11/xorg.conf
Section "Device"
Identifier "Videocard0"
Driver "intel" <==原本可能会是使用 i91x 喔
EndSection
Section "Module"
....(中间省略)....
Load "glx" <==这两个很重要!务必要载入!
Load "dri"
....(中间省略)....
EndSection
Section "DRI" <==这三行是新增的!让大家都能使用 DRI
Mode 0666 <==基本上,就是权限的设置
EndSection
```
如果一切顺利的话,接下来就是重新启动 X 啰~使用新的 Intel 驱动程序吧!加油啰!
![鸟哥的图示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** 老实说,CentOS 7 的 Xorg 自动侦测程序作的其实还不错,在鸟哥这次测试实体机器的系统上面安装的图形界面时,几乎 Xorg 都可以正确的抓到驱动程序, 连双屏幕功能也都可以顺利的启用没问题。所以除非必要,否则您应该不需要重新设置 xorg.conf 喔! ^_^
';
23.2 X Server 配置文件解析与设置
最后更新于:2022-04-01 22:17:24
## 23.2 X Server 配置文件解析与设置
从前面的说明来看,我们知道一个 X 窗口系统能不能成功启动,其实与 X Server 有很大的关系的。因为 X Server 负责的是整个画面的描绘,所以没有成功启动 X Server 的话,即使有启动 X Client 也无法将图样显示出来啊。所以,下面我们就针对 X Server 的配置文件来做个简单的说明,好让大家可以成功的启动 X Window System 啊。
基本上, X Server 管理的是显卡、屏幕分辨率、鼠标按键对应等等,尤其是显卡芯片的认识,真是重要啊。 此外,还有显示的字体也是 X Server 管理的一环。基本上,X server 的配置文件都是默认放置在 /etc/X11 目录下,而相关的显示模块或上面提到的总总模块,则主要放置在 /usr/lib64/xorg/modules 下面。比较重要的是字体文件与芯片组,她们主要放置在:
* 提供的屏幕字体: /usr/share/X11/fonts/
* 显卡的芯片组: /usr/lib64/xorg/modules/drivers/
在 CentOS 下面,这些都要通过一个统一的配置文件来规范,那就是 X server 的配置文件啦。这个配置文件的文件名就是 /etc/X11/xorg.conf 喔!
### 23.2.1 解析 xorg.conf 设置
如同前几个小节谈到的,在 Xorg 基金会里面的 X11 版本为 X11R7.N ,那如果你想要知道到底你用的 X Server 版本是第几版,可以使用 X 指令来检查喔!(你必须以 root 的身分执行下列指令)
```
[root@study ~]# X -version
X.Org X Server 1.15.0
Release Date: 2013-12-27
X Protocol Version 11, Revision 0
Build Operating System: 2.6.32-220.17.1.el6.x86_64
Current Operating System: Linux study.centos.vbird 3.10.0-229.el7.x86_64 #1 SMP Fri Mar
6 11:36:42 UTC 2015 x86_64
Kernel command line: BOOT_IMAGE=/vmlinuz-3.10.0-229.el7.x86_64 root=/dev/mapper/centos-
root ro rd.lvm.lv=centos/root rd.lvm.lv=centos/swap crashkernel=auto rhgb quiet
Build Date: 10 April 2015 11:44:42AM
Build ID: xorg-x11-server 1.15.0-33.el7_1
Current version of pixman: 0.32.4
Before reporting problems, check http://wiki.x.org
to make sure that you have the latest version.
```
由上面的几个关键字我们可以知道,目前鸟哥的这部测试机使用的 X server 是 Xorg 计划所提供的 X11 版, 不过看起来 Xorg 已经将所谓的 X11R7 那个 R7 的版次移除,使用的是 Xorg 自己的版次了!所以是 Xorg 1.15.0 版本! 此外,若有问题则可以到 http://wiki.x.org 去查询~因为是 Xorg 这个 X server ,因此我们的配置文件文件名为 /etc/X11/xorg.conf 这一个哩。所以,理解这个文件的内容对于 X server 的功能来说,是很重要的。
比较需要留意的是,从 CentOS 6 以后 (当然包含 CentOS 7),X server 在每次启动的时候都会自行侦测系统上面的显示芯片、屏幕类型等等, 然后自行搭配最优化的驱动程序载入。因此,这个 /etc/X11/xorg.conf 已经不再被需要了。不过,如果你不喜欢 X 系统自行侦测的设置值, 那也可以自行创建 xorg.conf 就是了。
此外,如果你只想要加入或者是修改部份的设置,并不是每个元件都要自行设置的话,那么可以在 /etc/X11/xorg.conf.d/ 这个目录下创建文件名为 .conf 的文件, 将你需要的额外项目加进去即可喔!那就不会每个设置都以你的 xorg.conf 为主了!了解乎?
![鸟哥的图示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** 那我怎么知道系统用的是哪一个设置呢?可以参考 /var/log/Xorg.0.log 的内容,该文件前几行会告诉你使用的设置文件是来自于哪里的喔!
注意一下,在修改这个文件之前,务必将这个文件给它备份下来,免的改错了什么东西导致连 X server 都无法启动的问题啊。这个文件的内容是分成数个段落的,每个段落以 Section 开始,以 EndSection 结束, 里面含有该 Section (段落) 的相关设置值,例如:
```
Section "section name"
…… <== 与这个 section name 有关的设置项目
……
EndSection
```
至于常见的 section name 主要有:
1. Module: 被载入到 X Server 当中的模块 (某些功能的驱动程序);
2. InputDevice: 包括输入的 1\. 键盘的格式 2\. 鼠标的格式,以及其他相关输入设备;
3. Files: 设置字体所在的目录位置等;
4. Monitor: 监视器的格式, 主要是设置水平、垂直的更新频率,与硬件有关;
5. Device: 这个重要,就是显卡芯片组的相关设置了;
6. Screen: 这个是在屏幕上显示的相关分辨率与色彩深度的设置项目,与显示的行为有关;
7. ServerLayout: 上述的每个项目都可以重复设置,这里则是此一 X server 要取用的哪个项目值的设置啰。
前面说了,xorg.conf 这个文件已经不存在,那我们怎么学习呢?没关系,Xorg 有提供一个简单的方式可以让我们来重建这个 xorg.conf 文件! 同时,这可能也是 X 自行侦测 GPU 所产生的最优化设置喔!怎么处理呢?假设你是在 multi-user.target 的环境下,那就可以这样作来产生 xorg.conf 喔!
```
[root@study ~]# Xorg -configure
.....(前面省略).....
Markers: (--) probed, (**) from config file, (==) default setting,
(++) from command line, (!!) notice, (II) informational,
(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(==) Log file: "/var/log/Xorg.0.log", Time: Wed Sep 16 10:13:57 2015
List of video drivers: # 这里在说明目前这个系统上面有的显卡芯片组的驱动程序有哪些的意思
qxl
vmware
v4l
ati
radeon
intel
nouveau
dummy
modesetting
fbdev
vesa
(++) Using config file: "/root/xorg.conf.new" # 使用的配置文件
(==) Using config directory: "/etc/X11/xorg.conf.d" # 额外设置项目的位置
(==) Using system config directory "/usr/share/X11/xorg.conf.d"
(II) [KMS] Kernel modesetting enabled.
.....(中间省略).....
Your xorg.conf file is /root/xorg.conf.new # 最终新的文件出现了!
To test the server, run 'X -config /root/xorg.conf.new' # 测试手段!
```
这样就在你的 root 主文件夹产生一个新的 xorg.conf.new 啰!好了,直接来看看这个文件的内容吧!这个文件默认的情况是取消很多设置值的, 所以你的配置文件可能不会看到这么多的设置项目。不要紧的,后续的章节会交代如何设置这些项目的喔!
```
[root@study ~]# vim xorg.conf.new
Section "ServerLayout" # 目前 X 决定使用的设置项目
Identifier "X.org Configured"
Screen 0 "Screen0" 0 0 # 使用的屏幕为 Screen0 这一个 (后面会解释)
InputDevice "Mouse0" "CorePointer" # 使用的鼠标设置为 Mouse0
InputDevice "Keyboard0" "CoreKeyboard" # 使用的键盘设置为 Keyboard0
EndSection
# 系统可能有多组的设置值,包括多种不同的键盘、鼠标、显示芯片等等,而最终 X 使用的设置,
# 就是在这个 ServerLayout 项目中来处理的!因此,你还得要去下面找出 Screen0 是啥
Section "Files"
ModulePath "/usr/lib64/xorg/modules"
FontPath "catalogue:/etc/X11/fontpath.d"
FontPath "built-ins"
EndSection
# 我们的 X Server 很重要的一点就是必须要提供字体,这个 Files 的项目就是在设置字体,
# 当然啦,你的主机必须要有字体文件才行。一般字体文件在:/usr/share/X11/fonts/ 目录中。
# 但是 Xorg 会去读取的则是在 /etc/X11/fontpath.d 目录下的设置喔!
Section "Module"
Load "glx"
EndSection
# 上面这些模块是 X Server 启动时,希望能够额外获得的相关支持的模块。
# 关于更多模块可以搜寻一下 /usr/lib64/xorg/modules/extensions/ 这个目录
Section "InputDevice"
Identifier "Keyboard0"
Driver "kbd"
EndSection
# 就是键盘,在 ServerLayout 项目中有出现这个 Keyboard0 吧!主要是设置驱动程序!
Section "InputDevice"
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "auto"
Option "Device" "/dev/input/mice"
Option "ZAxisMapping" "4 5 6 7" # 支持磙轮功能!
EndSection
# 这个则主要在设置鼠标功能,重点在那个 Protocol 项目,
# 那个是可以指定鼠标接口的设置值,我这里使用的是自动侦测!不论是 USB/PS2。
Section "Monitor"
Identifier "Monitor0"
VendorName "Monitor Vendor"
ModelName "Monitor Model"
EndSection
# 屏幕监视器的设置仅有一个地方要注意,那就是垂直与水平的更新频率,常见设置如下:
# HorizSync 30.0 - 80.0
# VertRefresh 50.0 - 100.0
# 在上面的 HorizSync 与 VerRefresh 的设置上,要注意,不要设置太高,
# 这个玩意儿与实际的监视器功能有关,请查询你的监视器手册说明来设置吧!
# 传统 CRT 屏幕设置太高的话,据说会让 monitor 烧毁呢,要很注意啊。
Section "Device" # 显卡芯片 (GPU) 的驱动程序!很重要的设置!
Identifier "Card0"
Driver "qxl" # 实际使用的显卡驱动程序!
BusID "PCI:0:2:0"
EndSection
# 这地方重要了,这就是显卡的芯片模块载入的设置区域。由于鸟哥使用 Linux KVM
# 仿真器仿真这个测试机,因此这个地方显示的驱动程序为 qxl 模块。
# 更多的显示芯片模块可以参考 /usr/lib64/xorg/modules/drivers/
Section "Screen" # 与显示的画面有关,分辨率与色彩深度
Identifier "Screen0" # 就是 ServerLayout 里面用到的那个屏幕设置
Device "Card0" # 使用哪一个显卡的意思!
Monitor "Monitor0" # 使用哪一个屏幕的意思!
SubSection "Display" # 此阶段的附属设置项目
Viewport 0 0
Depth 1 # 就是色彩深度的意思!
EndSubSection
SubSection "Display"
Viewport 0 0
Depth 16
EndSubSection
SubSection "Display"
Viewport 0 0
Depth 24
EndSubSection
EndSection
# Monitor 与实际的显示器有关,而 Screen 则是与显示的画面分辨率、色彩深度有关。
# 我们可以设置多个分辨率,实际应用时可以让使用者自行选择想要的分辨率来呈现,设置如下:
# Modes "1024x768" "800x600" "640x480" <==分辨率
# 上述的 Modes 是在 "Display" 下面的子设置。
# 不过,为了避免困扰,鸟哥通常只指定一到两个分辨率而已。
```
上面设置完毕之后,就等于将整个 X Server 设置妥当了,很简单吧。如果你想要更新其他的例如显示芯片的模块的话,就得要去硬件开发商的网站下载原始文件来编译才行。 设置完毕之后,你就可以启动 X Server 试看看啰。然后,请将 xorg.conf.new 更名成类似 00-vbird.conf 之类的文件名, 再将该文件移动到 /etc/X11/xorg.conf.d/ 里面去,这样就 OK 了!
```
# 测试 X server 的配置文件是否正常:
[root@study ~]# startx <==直接在 multi-user.target 启动 X 看看
[root@study ~]# Xorg :1 <==在 tty3 单独启动 X server 看看
```
当然,你也可以利用 systemctl isolate graphical.target 这个指令直接切换到图形接口的登陆来试看看啰。
![鸟哥的图示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** 经由讨论区网友的说明,如果你发现明明有捉到显卡驱动程序却老是无法顺利启动 X 的话,可以尝试去官网取得驱动程序来安装, 也能够将“Device”阶段的“Driver”修改成默认的“Driver "vesa"”,使用该驱动程序来暂时启动 X 内的显卡喔!
### 23.2.2 字体管理
我们 Xorg 所使用的字体大部分都是放置于下面的目录中:
* /usr/share/X11/fonts/
* /usr/share/fonts/
不过 Xorg 默认会载入的字体则是记录于 /etc/X11/fontpath.d/ 目录中,使用链接文件的模式来进行链接的动作而已。 你应该还记得 xorg.conf 里面有个“ Flies ”的设置项目吧?该项目里面就有指定到“ FontPath "catalogue:/etc/X11/fontpath.d" ” 对吧!也就是说,我们默认的 Xorg 使用的字体就是取自于 /etc/X11/fontpath.d 啰!
鸟哥查了一下 CentOS 7 针对中文字体 (chinese) 来说,有楷书与明体,明体默认安装了,不过楷书却没有安装耶~ 那我们能不能安装了楷书之后,将楷书也列为默认的字体之一呢?来瞧一瞧我们怎么作的好了:
```
# 1\. 检查中文字体,并且安装中文字体与检验有没有放置到 fontpath.d 目录中!
[root@study ~]# ll -d /usr/share/fonts/cjk*
drwxr-xr-x. 2 root root 22 May 4 17:54 /usr/share/fonts/cjkuni-uming
[root@study ~]# yum install cjkuni-ukai-fonts
[root@study ~]# ll -d /usr/share/fonts/cjk*
drwxr-xr-x. 2 root root 21 Sep 16 11:48 /usr/share/fonts/cjkuni-ukai # 这就是楷书!
drwxr-xr-x. 2 root root 22 May 4 17:54 /usr/share/fonts/cjkuni-uming
[root@study ~]# ll /etc/X11/fontpath.d/ lrwxrwxrwx. 1 root root 29 Sep 16 11:48 cjkuni-ukai-fonts -> /usr/share/fonts/cjkuni-ukai/
lrwxrwxrwx. 1 root root 30 May 4 17:54 cjkuni-uming-fonts -> /usr/share/fonts/cjkuni-uming/
lrwxrwxrwx. 1 root root 36 May 4 17:52 default-ghostscript -> /usr/share/fonts/default/ghostscript
lrwxrwxrwx. 1 root root 30 May 4 17:52 fonts-default -> /usr/share/fonts/default/Type1
lrwxrwxrwx. 1 root root 27 May 4 17:51 liberation-fonts -> /usr/share/fonts/liberation
lrwxrwxrwx. 1 root root 27 Sep 15 17:10 xorg-x11-fonts-100dpi:unscaled:pri=30 -> /usr/share/X11/fonts/100dpi
lrwxrwxrwx. 1 root root 26 Sep 15 17:10 xorg-x11-fonts-75dpi:unscaled:pri=20 -> /usr/share/X11/fonts/75dpi
lrwxrwxrwx. 1 root root 26 May 4 17:52 xorg-x11-fonts-Type1 -> /usr/share/X11/fonts/Type1
# 竟然会自动的将该字体加入到 fontpath.d 当中!太好了! ^_^
# 2\. 创建该字体的字体高速缓存数据,并检查是否真的取用了?
[root@study ~]# fc-cache -v | grep ukai
/usr/share/fonts/cjkuni-ukai: skipping, existing cache is valid: 4 fonts, 0 dirs
[root@study ~]# fc-list | grep ukai
/usr/share/fonts/cjkuni-ukai/ukai.ttc: AR PL UKai TW:style=Book
/usr/share/fonts/cjkuni-ukai/ukai.ttc: AR PL UKai HK:style=Book
/usr/share/fonts/cjkuni-ukai/ukai.ttc: AR PL UKai CN:style=Book
/usr/share/fonts/cjkuni-ukai/ukai.ttc: AR PL UKai TW MBE:style=Book
# 3\. 重新启动 Xorg,或者是强制重新进入 graphical.target
[root@study ~]# systemctl isolate multi-user.target; systemctl isolate graphical.target
```
如果上述的动作没有问题的话,现在你可以在图形界面下面,通过“应用程序” --> “公用程序” --> “字体检视程序”当中找到一个名为 “AR PL UKai CN, Book”字样的字体,点下去就会看到如下的图示,那就代表该字体已经可以被使用了。不过某些程序可能还得要额外的加工就是了~[[4]](#ps4)
![安装楷书字体的结果](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_57357380a22c0.jpg)图23.2.1、安装楷书字体的结果
鸟哥比较好奇的是,这个字体的开发者怎么这么有趣!列出来的示意字体竟然是吃了玻璃会身体头好壮壮~这...会不会教坏小孩啊?呵呵呵呵~
* 让窗口管理员可以使用额外的字体
如果想要使用额外的字体的话,你可以自行取得某些字体来处理的。鸟哥这边从 Windows 微软正黑体、Times new Romans 两种字体加上粗、斜体等共六个文件来处理字体的安装~ 这边得注明一下是纯粹的测试,测试完毕后文件就给它拿掉了,并没有持续使用喔!并没有想要违法的意思啦~大家参考看看就好了。 那就来看看如何增加字体吧!(假设上述的字体文件是放置在 /root/font 中)
```
# 1\. 将字体文件放置到系统设置目录,亦即下面的目录中:
[root@study ~]# cd /usr/share/fonts/
[root@study ~]# mkdir windows
[root@study ~]# cp /root/font/*.ttf /usr/share/fonts/windows/
# 2\. 使用 fc-cache 将上述的文件加入字体的支持中:
[root@study ~]# fc-cache -f -v
....(前面省略)....
/usr/share/fonts/windows: caching, new cache contents: 6 fonts, 0 dirs
....(后面省略)....
# -v 仅是列出目前的字体数据, -f 则是强制重新创建字体高速缓存!
# 3\. 通过 fc-list 列出已经被使用的文件看看:
[root@study ~]# fc-list : file | grep window <==找出被高速缓存住的文件名
/usr/share/fonts/windows/timesbi.ttf:
/usr/share/fonts/windows/timesi.ttf:
/usr/share/fonts/windows/msjh.ttf:
/usr/share/fonts/windows/times.ttf:
/usr/share/fonts/windows/msjhbd.ttf:
/usr/share/fonts/windows/timesbd.ttf:
```
之后在字体检视器里面就会发现有多了“Microsoft JhengHei, Times New Roman”等等的字体可以用啰!
### 23.2.3 显示器参数微调
有些朋友偶而会这样问:“我的显示器明明还不错,但是屏幕分辨率却永远只能达到 800x600 而已, 这该如何处理?”,屏幕的分辨率应该与显卡相关性不高,而是与显示器的更新频率有关!
所谓的更新频率,指的是在一段时间内屏幕重新绘制画面的速度。举例来说, 60Hz 的更新频率, 指的是每秒钟画面更新 60 次的意思。那么关于显示器的更新频率该如何调整呢? 你得先去找到你的显示器的使用说明书 (或者是网站会有规格介绍),取得最高的更新率后,接下来选择你想要的分辨率, 然后通过这个 gtf 的指令功能来调整:
![鸟哥的图示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** 基本上,现在新的 Linux distribution 的 X server 大多使用自行侦测方式来处理所有的设置了,因此, 除非你的屏幕特别新或者是特别怪,否则应该不太需要使用到 gtf 的功能啰!
```
# 1\. 先来测试一下你目前的屏幕搭配显卡所能够处理的分辨率与更新频率 (须在 X 环境下)
[root@study ~]# xrandr
Screen 0: minimum 320 x 200, current 1440 x 900, maximum 8192 x 8192
Virtual-0 connected primary 1440x900+0+0 0mm x 0mm
1024x768 59.9 +
1920x1200 59.9
1920x1080 60.0
1600x1200 59.9
1680x1050 60.0
1400x1050 60.0
1280x1024 59.9
1440x900 59.9*
1280x960 59.9
1280x854 59.9
1280x800 59.8
1280x720 59.9
1152x768 59.8
800x600 59.9
848x480 59.7
720x480 59.7
640x480 59.4
# 上面显示现在的环境中,测试过最高分辨率大概是 1920x1200 ,但目前是 1440x900 (*)
# 若需要调整成 1280*800 的话,可以使用下面的方式来调整喔!
[root@study ~]# xrandr -s 1280x800
# 2\. 若想强迫 X server 更改屏幕的分辨率与更新频率,则需要修订 xorg.conf 的设置。先来侦测:
[root@study ~]# gtf 水平像素 垂直像素 更新频率 [-xv]
选项与参数:
水平像素:就是分辨率的 X 轴
垂直像素:就是分辨率的 Y 轴
更新频率:与显示器有关,一般可以选择 60, 75, 80, 85 等频率
-x :使用 Xorg 配置文件的模式输出,这是默认值
-v :显示侦测的过程
# 1\. 使用 1024x768 的分辨率,75 Hz 的更新频率来取得显示器内容
[root@study ~]# gtf 1024 768 75 -x
# 1024x768 @ 75.00 Hz (GTF) hsync: 60.15 kHz; pclk: 81.80 MHz
Modeline "1024x768_75.00" 81.80 1024 1080 1192 1360 768 769 772 802 -HSync +Vsync
# 重点是 Modeline 那一行!那行给他抄下来
# 2\. 将上述的数据输入 xorg.conf.d/*.conf 内的 Monitor 项目中:
[root@study ~]# vim /etc/X11/xorg.conf.d/00-vbird.conf
Section "Monitor"
Identifier "Monitor0"
VendorName "Monitor Vendor"
ModelName "Monitor Model"
Modeline "1024x768_75.00" 81.80 1024 1080 1192 1360 768 769 772 802 -HSync +Vsync
EndSection
# 就是新增上述的那行特殊字体部分到 Monitor 的项目中即可。
```
然后重新启动你的 X ,这样就能够选择新的分辨率啰!那如何重新启动 X 呢?两个方法, 一个是“ systemctl isolate multi-user.target; systemctl isolate graphical.target ”从文字模式与图形模式的执行等级去切换,另一个比较简单, 如果原本就是 graphical.target 的话,那么在 X 的画面中按下“ [alt] + [crtl] + [backspace] ”三个组合按键, 就能够重新启动 X 窗口啰!
';
23.1 什么是 X Window System
最后更新于:2022-04-01 22:17:22
## 23.1 什么是 X Window System
Unix Like 操作系统不是只能进行服务器的架设而已,在美编、排版、制图、多媒体应用上也是有其需要的。 这些需求都需要用到图形接口 (Graphical User Interface, GUI) 的操作的, 所以后来才有所谓的 X Window System 这玩意儿。那么为啥图形窗口接口要称为 X 呢?因为就英文字母来看 X 是在 W(indow) 后面,因此,人们就戏称这一版的窗口接口为 X 啰 (有下一版的新窗口之意)!
事实上, X Window System 是个非常大的架构,他还用到网络功能呢!也就是说,其实 X 窗口系统是能够跨网络与跨操作系统平台的! 而鸟哥这个基础篇是还没有谈到服务器与网络主从式架构,因此 X 在这里并不容易理解的。不过,没关系! 我们还是谈谈 X 怎么来的,然后再来谈谈这 X 窗口系统的元件有哪些,慢慢来,应该还是能够理解 X 的啦!
### 23.1.1 X Window 的发展简史
X Window 系统最早是由 MIT (Massachusetts Institute of Technology, 麻省理工学院) 在 1984 年发展出来的, 当初 X 就是在 Unix 的 System V 这个操作系统版本上面开发出来的。在开发 X 时,开发者就希望这个窗口接口不要与硬件有强烈的相关性,这是因为如果与硬件的相关性高,那就等于是一个操作系统了, 如此一来的应用性会比较局限。因此 X 在当初就是以应用程序的概念来开发的,而非以操作系统来开发。
由于这个 X 希望能够通过网络进行图形接口的存取,因此发展出许多的 X 通讯协定,这些网络架构非常的有趣, 所以吸引了很多厂商加入研发,因此 X 的功能一直持续在加强!一直到 1987 年更改 X 版本到 X11 ,这一版 X 取得了明显的进步, 后来的窗口接口改良都是架构于此一版本,因此后来 X 窗口也被称为 X11 。这个版本持续在进步当中,到了 1994 年发布了新版的 X11R6 ,后来的架构都是沿用此一释出版本,所以后来的版本定义就变成了类似 1995 年的 X11R6.3 之类的样式。 [[1]](#ps1)
1992 年 XFree86 ([http://www.xfree86.org/](http://www.xfree86.org/)) 计划顺利展开, 该计划持续在维护 X11R6 的功能性,包括对新硬件的支持以及更多新增的功能等等。当初定名为 XFree86 其实是根据“ X + Free software + x86 硬件 ”而来的呢。早期 Linux 所使用的 X Window 的主要核心都是由 XFree86 这个计划所提供的,因此,我们常常将 X 系统与 XFree86 挂上等号的说。
不过由于一些授权的问题导致 XFree86 无法继续提供类似 GPL 的自由软件,后来 Xorg 基金会就接手 X11R6 的维护! Xorg ([http://www.x.org/](http://www.x.org/)) 利用当初 MIT 发布的类似自由软件的授权, 将 X11R6 拿来进行维护,并且在 2004 年发布了 X11R6.8 版本,更在 2005 年后发表了 X11R7.x 版。 现在我们 CentOS 7.x 使用的 X 就是 Xorg 提供的 X11R7.X 喔! 而这个 X11R6/X11R7 的版本是自由软件,因此很多组织都利用这个架构去设计他们的图形接口喔!包括 Mac OS X v10.3 也曾利用过这个架构来设计他们的窗口呢!我们的 CentOS 也是利用 Xorg 提供的 X11 啦!
从上面的说明,我们可以知道的是:
* 在 Unix Like 上面的图形使用者接口 (GUI) 被称为 X 或 X11;
* X11 是一个“软件”而不是一个操作系统;
* X11 是利用网络架构来进行图形接口的执行与绘制;
* 较著名的 X 版本为 X11R6 这一版,目前大部分的 X 都是这一版演化出来的 (包括 X11R7);
* 现在大部分的 distribution 使用的 X 都是由 Xorg 基金会所提供的 X11 软件;
* X11 使用的是 MIT 授权,为类似 GPL 的开放源代码授权方式。
### 23.1.2 主要元件: X Server/X Client/Window Manager/Display Manager
如同前面谈到的,X Window system 是个利用网络架构的图形使用者接口软件,那到底这个架构可以分成多少个元件呢? 基本上是分成 X Server 与 X Client 两个元件而已喔!其中 X Server 在管理硬件,而 X Client 则是应用程序。 在运行上,X Client 应用程序会将所想要呈现的画面告知 X Server ,最终由 X server 来将结果通过他所管理的硬件绘制出来! 整体的架构我们大约可以使用如下的图示来作个介绍:[[2]](#ps2)
![X Window System 的架构](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_57357380049b3.gif)图23.1.1、X Window System 的架构
上面的图示非常有趣喔!我们在用户端想要取得来自服务器的图形数据时,我们用户端使用的当然是用户端的硬件设备啊, 所以,X Server 的重点就是在管理用户端的硬件,包括接受键盘/鼠标等设备的输入信息, 并且将图形绘制到屏幕上 (请注意上图的所有元件之间的箭头指示)。但是到底要绘制个啥东西呢? 绘图总是需要一些数据才能绘制吧?此时 X Client (就是 X 应用程序) 就很重要啦!他主要提供的就是告知 X Server 要绘制啥东西。那照这样的想法来思考,我们是想要取得远端服务器的绘图数据来我们的计算机上面显示嘛! 所以啰,远端服务器提供的是 X client 软件啊!
下面就让我们来更深入的聊一聊这两个元件吧!
* X Server:硬件管理、屏幕绘制与提供字体功能:
既然 X Window System 是要显示图形接口,因此理所当然的需要一个元件来管理我主机上面的所有硬件设备才行! 这个任务就是 X Server 所负责的。而我们在 X 发展简史当中提到的 XFree86 计划及 Xorg 基金会,主要提供的就是这个 X Server 啦!那么 X Server 管理的设备主要有哪些呢?其实与输入/输出有关喔!包括键盘、鼠标、手写板、显示器 (monitor) 、屏幕分辨率与色彩深度、显卡 (包含驱动程序) 与显示的字体等等,都是 X Server 管理的。
咦!显卡、屏幕以及键盘鼠标的设置,不是在开机的时候 Linux 系统以 systemd 的相关设置处理好了吗? 为何 X Server 还要重新设置啊?这是因为 X Window 在 Linux 里面仅能算是“一套很棒的软件”, 所以 X Window 有自己的配置文件,你必须要针对他的配置文件设置妥当才行。也就是说, Linux 的设置与 X Server 的设置不一定要相同的!因此,你在 CentOS 7 的 multi-user.target 想要玩图形接口时,就得要载入 X Window 需要的驱动程序才行~总之, X Server 的主要功能就是在管理“主机”上面的显示硬件与驱动程序。
既然 X Window System 是以通过网络取得图形接口的一个架构,那么用户端是如何取得服务器端提供的图形画面呢? 由于服务器与用户端的硬件不可能完全相同,因此我们用户端当然不可能使用到服务器端的硬件显示功能! 举例来说,你的用户端计算机并没有 3D 影像加速功能,那么你的画面可能呈现出服务器端提供的 3D 加速吗? 当然不可能吧!所以啰 X Server 的目的在管理用户端的硬件设备!也就是说:“每部用户端主机都需要安装 X Server,而服务器端则是提供 X Client 软件, 以提供用户端绘图所需要的数据数据”。
X Server / X Client 的互动并非仅有 client --> server,两者其实有互动的!从上图 23.1.1 我们也可以发现, X Server 还有一个重要的工作,那就是将来自输入设备 (如键盘、鼠标等) 的动作告知 X Client, 你晓得, X Server 既然是管理这些周边硬件,所以,周边硬件的动作当然是由 X Server 来管理的, 但是 X Server 本身并不知道周边设备这些动作会造成什么显示上的效果, 因此 X Server 会将周边设备的这些动作行为告知 X Client ,让 X Client 去伤脑筋。
* X Client:负责 X Server 要求的“事件”之处理:
前面提到的 X Server 主要是管理显示接口与在屏幕上绘图,同时将输入设备的行为告知 X Client, 此时 X Client 就会依据这个输入设备的行为来开始处理,最后 X Client 会得到“ 嗯!这个输入设备的行为会产生某个图示”,然后将这个图示的显示数据回传给 X Server , X server 再根据 X Client 传来的绘图数据将他描图在自己的屏幕上,来得到显示的结果。
也就是说, X Client 最重要的工作就是处理来自 X Server 的动作,将该动作处理成为绘图数据, 再将这些绘图数据传回给 X Server 啰!由于 X Client 的目的在产生绘图的数据,因此我们也称呼 X Client 为 X Application (X 应用程序)。而且,每个 X Client 并不知道其他 X Client 的存在, 意思是说,如果有两个以上的 X client 同时存在时,两者并不知道对方到底传了什么数据给 X Server , 因此 X Client 的绘图常常会互相重叠而产生困扰喔!
举个例子来说,当我们在 X Window 的画面中,将鼠标向右移动,那他是怎么告知 X Server 与 X Client 的呢? 首先, X server 会侦测到鼠标的移动,但是他不知道应该怎么绘图啊!此时,他将鼠标的这个动作告知 X Client, X Client 就会去运算,结果得到,嘿嘿!其实要将鼠标指标向右移动几个像素,然后将这个结果告知 X server , 接下来,您就会看到 X Server 将鼠标指标向右移动啰~
这样做有什么好处啊?最大的好处是, X Client 不需要知道 X Server 的硬件配备与操作系统!因为 X Client 单纯就是在处理绘图的数据而已,本身是不绘图的。所以,在用户端的 X Server 用的是什么硬件?用的是哪套操作系统?服务器端的 X Client 根本不需要知道~相当的先进与优秀~对吧! ^_^ 整个运行流程可以参考下图:用户端用的是什么操作系统在 Linux 主机端是不在乎的!
![X Server 用户端的操作系统与 X client 的沟通示意](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735738015145.gif)图23.1.2、X Server 用户端的操作系统与 X client 的沟通示意
* X Window Manager:特殊的 X Client ,负责管理所有的 X client 软件
刚刚前面提到,X Client 的主要工作是将来自 X Server 的数据处理成为绘图数据,再回传给 X server 而已, 所以 X client 本身是不知道他在 X Server 当中的位置、大小以及其他相关信息的。这也是上面我们谈到的, X client 彼此不知道对方在屏幕的哪个位置啊!为了克服这个问题,因此就有 Window Manager (WM, 窗口管理员) 的产生了。 窗口管理员也是 X client ,只是他主要在负责全部 X client 的控管,还包括提供某些特殊的功能,例如:
* 提供许多的控制元素,包括工作列、背景桌面的设置等等;
* 管理虚拟桌面 (virtual desktop);
* 提供窗口控制参数,这包括窗口的大小、窗口的重叠显示、窗口的移动、窗口的最小化等等。
我们常常听到的 KDE, GNOME, XFCE 还有阳春到爆的 twm 等等,都是一些窗口管理员的专案计划啦! 这些专案计划中,每种窗口管理员所用以开发的显示发动机都不太相同,所著重的方向也不一样, 因此我们才会说,在 Linux 下面,每套 Window Manager 都是独特存在的,不是换了桌面与显示效果而已, 而是连显示的发动机都不会一样喔!下面是这些常见的窗口管理员全名与链接:
* GNOME (GNU Network Object Model Environment):[http://www.gnome.org/](http://www.gnome.org/)
* KDE (K Desktop Enviroment):[http://kde.org/](http://kde.org/)
* twm (Tab Window Manager):[http://xwinman.org/vtwm.php](http://xwinman.org/vtwm.php)
* XFCE (XForms Common Environment):[http://www.xfce.org/](http://www.xfce.org/)
由于 Linux 越来越朝向 Desktop 桌面电脑使用方向走,因此窗口管理员的角色会越来越重要! 目前我们 CentOS 默认提供的有 GNOME 与 KDE ,这两个窗口管理员上面还有提供非常多的 X client 软件, 包括办公室生产力软件 (Open Office) 以及常用的网络功能 (firefox 浏览器、 Thunderbird 收发信件软件) 等。 现在使用者想要接触 Linux 其实真的越来越简单了,如果不要架设服务器,那么 Linux 桌面的使用与 Windows 系统可以说是一模一样的!不需要学习也能够入门哩! ^_^
那么你知道 X Server / X client / window manager 的关系了吗?我们举 CentOS 默认的 GNOME 为例好了, 由于我们要在本机端启动 X Window system ,因此,在我们的 CentOS 主机上面必须要有 Xorg 的 X server 核心, 这样才能够提供屏幕的绘制啊~然后为了让窗口管理更方便,于是就加装了 GNOME 这个计划的 window manager , 然后为了让自己的使用更方便,于是就在 GNOME 上面加上更多的窗口应用软件,包括输入法等等的, 最后就建构出我们的 X Window System 啰~ ^_^!所以你也会知道,X server/X client/Window Manager 是同时存在于我们一部 Linux 主机上头的啦!
* Display Manager:提供登陆需求
谈完了上述的数据后,我们得要了解一下,那么我如何取得 X Window 的控制?在本机的命令行下面你可以输入 startx 来启动 X 系统,此时由于你已经登陆系统了,因此不需要重新登陆即可取得 X 环境。但如果是 graphical.target 的环境呢?你会发现在 tty1 或其他 tty 的地方有个可以让你使用图形接口登陆 (输入帐号密码) 的咚咚,那个是啥? 是 X Server/X client 还是什么的?其实那是个 Display Manager 啦!这个 display manager 最大的任务就是提供登陆的环境, 并且载入使用者选择的 Window Manager 与语系等数据喔!
几乎所有的大型窗口管理员专案计划都会提供 display manager 的,在 CentOS 上面我们主要利用的是 GNOME 的 GNOME Display Manager (gdm) 这支程序来提供 tty1 的图形接口登陆喔!至于登陆后取得的窗口管理员, 则可以在 gdm 上面进行选择的!我们在[第四章](../Text/index.html#start_startx)介绍的登陆环境, 那个环境其实就是 gdm 提供的啦!再回去参考看看图示吧! ^_^!所以说,并非 gdm 只能提供 GNOME 的登陆而已喔!
### 23.1.3 X Window 的启动流程
现在我们知道要启动 X Window System 时,必须要先启动管理硬件与绘图的 X Server ,然后才载入 X Client 。 基本上,目前都是使用 Window Manager 来管理窗口接口风格的。那么如何取得这样的窗口系统呢? 你可以通过登陆本机的命令行后,输入 startx 来启动 X 窗口;也能够通过 display manager (如果有启动 graphical.target) 提供的登陆画面,输入你的帐号密码来登陆与取得 X 窗口的!
问题是,你的 X server 配置文件为何?如何修改分辨率与显示器?你能不能自己设置默认启动的窗口管理员? 如何设置默认的使用者环境 (与 X client 有关) 等等的,这些数据都需要通过了解 X 的启动流程才能得知! 所以,下面我们就来谈谈如何启动 X 的流程吧! ^_^
* 在命令行启动 X :通过 startx 指令
我们都知道 Linux 是个多用户多任务的操作系统,所以啦,X 窗口也是可以根据不同的使用者而有不同的设置! 这也就是说,每个用户启动 X 时, X server 的分辨率、启动 X client 的相关软件及 Window Manager 的选择可能都不一样! 但是,如果你是首次登陆 X 呢?也就是说,你自己还没有创建自己的专属 X 画面时,系统又是从哪里给你这个 X 默认画面呢?而如果你已经设置好相关的信息,这些信息又是存放于何处呢?
事实上,当你在纯命令行且并没有启动 X 窗口的情况下来输入 startx 时,这个 startx 的作用就是在帮你设置好上头提到的这些动作啰! startx 其实是一个 shell script ,他是一个比较友好的程序,会主动的帮忙使用者创建起他们的 X 所需要引用的配置文件而已。你可以自行研究一下 startx 这个 script 的内容,鸟哥在这里仅就 startx 的作用作个介绍。
startx 最重要的任务就是找出使用者或者是系统默认的 X server 与 X client 的配置文件,而使用者也能够使用 startx 外接参数来取代配置文件的内容。这个意思是说:startx 可以直接启动,也能够外接参数,例如下面格式的启动方式:
```
[root@study ~]# startx [X client 参数] -- [X server 参数]
# 范例:以色彩深度为 16 bit 启动 X
[root@study ~]# startx -- -depth 16
```
startx 后面接的参数以两个减号“--”隔开,前面的是 X Client 的设置,后面的是 X Server 的设置。 上面的范例是让 X server 以色彩深度 16 bit 色 (亦即每一像素占用 16 bit ,也就是 65536 色) 显示, 因为色彩深度是与 X Server 有关的,所以参数当然是写在 -- 后面啰,于是就成了上面的模样!
你会发现,鸟哥上面谈到的 startx 都是提到如何找出 X server / X client 的设置值而已! 没错,事实上启动 X 的是 xinit 这支程序, startx 仅是在帮忙找出设置值而已!那么 startx 找到的设置值可用顺序为何呢?基本上是这样的:
* X server 的参数方面:
1. 使用 startx 后面接的参数;
2. 若无参数,则找寻使用者主文件夹的文件,亦即 ~/.xserverrc
3. 若无上述两者,则以 /etc/X11/xinit/xserverrc
4. 若无上述三者,则单纯执行 /usr/bin/X (此即 X server 可执行文件)
* X client 的参数方面:
1. 使用 startx 后面接的参数;
2. 若无参数,则找寻使用者主文件夹的文件,亦即 ~/.xinitrc
3. 若无上述两者,则以 /etc/X11/xinit/xinitrc
4. 若无上述三者,则单纯执行 xterm (此为 X 下面的终端机软件)
根据上述的流程找到启动 X 时所需要的 X server / X client 的参数,接下来 startx 会去调用 xinit 这支程序来启动我们所需要的 X 窗口系统整体喔!接下来当然就是要谈谈 xinit 啰~
* 由 startx 调用执行的 xinit
事实上,当 startx 找到需要的设置值后,就调用 xinit 实际启动 X 的。他的语法是:
```
[root@study ~]# xinit [client option] -- [server or display option]
```
那个 client option 与 server option 如何下达呢?其实那两个咚咚就是由刚刚 startx 去找出来的啦! 在我们通过 startx 找到适当的 xinitrc 与 xserverrc 后,就交给 xinit 来执行。 在默认的情况下 (使用者尚未有 ~/.xinitrc 等文件时),你输入 startx , 就等于进行 xinit /etc/X11/xinit/xinitrc -- /etc/X11/xinit/xserverrc 这个指令一般!但由于 xserverrc 也不存在,参考上一小节的参数搜寻顺序, 因此实际上的指令是:xinit /etc/X11/xinit/xinitrc -- /usr/bin/X,这样瞭了吗?
那为什么不要直接执行 xinit 而是使用 startx 来调用 xinit 呢?这是因为我们必须要取得一些参数嘛! startx 可以帮我们快速的找到这些参数而不必手动输入的。因为单纯只是执行 xinit 的时候,系统的默认 X Client 与 X Server 的内容是这样的:[[3]](#ps3)
```
xinit xterm -geometry +1+1 -n login -display :0 -- X :0
```
在 X client 方面:那个 xterm 是 X 窗口下面的虚拟终端机,后面接的参数则是这个终端机的位置与登陆与否。 最后面会接一个“ -display :0 ”表示这个虚拟终端机是启动在“第 :0 号的 X 显示接口”的意思。至于 X Server 方面, 而我们启动的 X server 程序就是 X 啦!其实 X 就是 Xorg 的链接文件,亦即是 X Server 的主程序啰! 所以我们启动 X 还挺简单的~直接执行 X 而已,同时还指定 X 启动在第 :0 个 X 显示接口。 如果单纯以上面的内容来启动你的 X 系统时,你就会发现 tty2 以后的终端机有画面了!只是.....很丑~因为我们还没有启动 window manager 啊!
从上面的说明我们可以知道, xinit 主要在启动 X server 与载入 X client ,但这个 xinit 所需要的参数则是由 startx 去帮忙找寻的。因此,最重要的当然就是 startx 找到的那些参数啦! 所以呢,重点当然就是 /etc/X11/xinit/ 目录下的 xinitrc 与 xserverrc 这两个文件的内容是啥啰~ 虽然 xserverrc 默认是不存在的。下面我们就分别来谈一谈这两个文件的主要内容与启动的方式~
* 启动 X server 的文件: xserverrc
X 窗口最先需要启动的就是 X server 啊,那 X server 启动的脚本与参数是通过 /etc/X11/xinit/ 里面的 xserverrc 。不过我们的 CentOS 7.x 根本就没有 xserverrc 这个文件啊! 那使用者主文件夹目前也没有 ~/.xserverrc ,这个时候系统会怎么做呢?其实就是执行 /usr/bin/X 这个指令啊! 这个指令也是系统最原始的 X server 可执行文件啰。
在启动 X Server 时,Xorg 会去读取 /etc/X11/xorg.conf 这个配置文件。针对这个配置文件的内容, 我们会在下个小节介绍。如果一切顺利,那么 X 就会顺利的在 tty2 以后终端环境中启动了 X 。 单纯的 X 启动时,你只会看到画面一片漆黑,然后中心有个鼠标的光标而已~
由前一小节的说明中,你可以发现到其实 X 启动的时候还可以指定启动的接口喔!那就是 :0 这个参数,这是啥? 事实上我们的 Linux 可以“同时启动多个 X”喔!第一个 X 的画面会在 :0 亦即是 tty2 ,第二个 X 则是 :1 亦即是 tty3 。 后续还可以有其他的 X 存在的。因此,上一小节我们也有发现, xterm 在载入时,也必须要使用 -display 来说明, 这个 X 应用程序是需要在哪个 X 载入的才行呢!其中比较有趣的是, X server 未注明载入的接口时,默认是使用 :0 ~ 但是 X client 未注明时,则无法执行喔!
![鸟哥的图示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** CentOS 7 的 tty 非常有趣!如果你在[分析 systemd 的章节中](../Text/index.html#systemd_cfg_repeat)有仔细看的话, 会发现到其实 tty 是有用到才会启动的,这与之前 CentOS 6 以前的版本默认启用 6 个 tty 给你是不同的。因此,如果你只有用到 tty1 的话, 那么启动 X 就会默认丢到 tty2 ,而 X :1 就会丢到 tty3 这样~以此类推喔~
启动了 X server 后,接下来就是载入 X client 到这个 X server 上面啦!
* 启动 X Client 的文件: xinitrc
假设你的主文件夹并没有 ~/.xinitrc ,则此时 X Client 会以 /etc/X11/xinit/xinitrc 来作为启动 X Client 的默认脚本。xinitrc 这个文件会将很多其他的文件参数引进来, 包括 /etc/X11/xinit/xinitrc-common 与 /etc/X11/xinit/Xclients 还有 /etc/sysconfig/desktop 。你可以参考 xinitrc 后去搜寻各个文件来了解彼此的关系。
不过分析到最后,其实最终就是载入 KDE 或者是 GNOME 而已。你也可以发现最终在 XClient 文件当中会有两个指令的搜寻, 包括 startkde 与 gnome-session 这两个,这也是 CentOS 默认会提供的两个主要的 Window Manager 啰。 而你也可以通过修改 /etc/sysconfig/desktop 内的 DESKTOP=GNOME 或 DESKTOP=KDE 来决定默认使用哪个窗口管理员的。 如果你并没有安装这两个大家伙,那么 X 就会去使用阳春的 twm 这个窗口管理员来管理你的环境啰。
![鸟哥的图示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** 不论怎么说,鸟哥还是希望大家可以通过解析 startx 这个 script 的内容去找到每个文件, 再根据分析每个文件来找到您 distributions 上面的 X 相关文件~ 毕竟每个版本的 Linux 还是有所差异的~
另外,如果有特殊需求,你当然可以自订 X client 的参数!这就得要修改你主文件夹下的 ~/.xinitrc 这个文件啰。 不过要注意的是,如果你的 .xinitrc 配置文件里面有启动的 x client 很多的时候,千万注意将除了最后一个 window manager 或 X Client 之外,都放到背景里面去执行啊!举例来说,像下面这样:
```
xclock -geometry 100x100-5+5 &
xterm -geometry 80x50-50+150 &
exec /usr/bin/twm
```
意思就是说,我启动了 X ,并且同时启动 xclock / xterm / twm 这三个 X clients 喔! 如此一来,你的 X 就有这三个咚咚可以使用了!如果忘记加上 & 的符号,那就..... 会让系统等待啊,而无法一次就登陆 X 呢!
* X 启动的端口
好了,根据上面的说明,我们知道要在命令行下面启动 X 时,直接使用 startx 来找到 X server 与 X client 的参数或配置文件, 然后再调用 xinit 来启动 X 窗口系统。xinit 先载入 X server 到默认的 :0 这个显示接口,然后再载入 X client 到这个 X 显示接口上。而 X client 通常就是 GNOME 或 KDE ,这两个设置也能够在 /etc/sysconfig/desktop 里面作好设置。最后我们想要了解的是,既然 X 是可以跨网络的,那 X 启动的端口是几号?
其实,CentOS 由于考虑 X 窗口是在本机上面运行,因此将端口改为插槽档 (socket) 了,因此你无法观察到 X 启动的端口的。事实上, X server 应该是要启动一个 port 6000 来与 X client 进行沟通的! 由于系统上面也可能有多个 X 存在,因此我们就会有 port 6001, port 6002... 等等。这也就是说:(假设为 multi-user.target 模式, 且用户仅曾经切换到 tty1 而已)
| X 窗口系统 | 显示接口号码 | 默认终端机 | 网络监听端口 |
| --- | --- |
| 第一个 X | hostname:0 | tty2 | port 6000 |
| 第二个 X | hostname:1 | tty3 | port 6001 |
在 X Window System 的环境下,我们称 port 6000 为第 0 个显示接口,亦即为 hostname:0 , 那个主机名称通常可以不写,所以就成了 :0 即可。在默认的情况下,第一个启动的 X (不论是启动在第几个 port number) 是在 tty2 ,亦即按下 [ctrl]+[Alt]+[F2] 那个画面。 而起动的第二个 X (注意到了吧!可以有多个 X 同时启动在您的系统上呢) 则默认在 tty3 亦即 [ctrl]+[Alt]+[F3] 那个画面呢!很神奇吧! ^_^
如前所述,因为主机上的 X 可能有多个同时存在,因此,当我们在启动 X Server / Client 时, 应该都要注明该 X Server / Client 主要是提供或接受来自哪个 display 的 port number 才行。
### 23.1.4 X 启动流程测试
好了,我们可以针对 X Server 与 X client 的架构来做个简单的测试喔! 这里鸟哥假设你的 tty1 是 multi-user.target 的,而且你也曾经在 tty2 测试过相关的指令,所以你的 X :1 将会启用在 tty3 喔! 而且,下面的指令都是在 tty1 的地方执行的,至于下面的画面则是在 tty3 的地方展现。 因此,请自行切换 tty1 下达指令与 tty3 查阅结果啰!
```
1\. 先来启动第一个 X 在 :1 画面中:
[dmtsai@study ~]$ X :1 &
```
![单纯启动 X server的情况](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735738033910.gif)图23.1.3、单纯启动 X server的情况
上述的 X 是大写,那个 :1 是写在一起的,至于 & 则是放到背景去执行。此时系统会主动的跳到第二个图形接口终端机,亦即 tty8 上喔!所以如果一切顺利的话,你应该可以看到一个 X 的鼠标光标可以让你移动了(如上图所示)。 该画面就是 X Server 启动的画面啰!丑丑的,而且没有什么 client 可以用啊! 接下来,请按下 [ctrl]+[alt]+[F1] 回到刚刚下达指令的终端机: (若没有 xterm 请自行 yum 安装它!)
```
2\. 输入数个可以在 X 当中执行的虚拟终端机
[dmtsai@study ~]$ xterm -display :1 &
[dmtsai@study ~]$ xterm -display :1 &
```
![在 X 上面启动 xterm 终端机显示的结果](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_57357380440a5.jpg)图23.1.4、在 X 上面启动 xterm 终端机显示的结果
那个 xterm 是必须要在 X 下面才能够执行的终端机接口。加入的参数 -display 则是指出这个 xterm 要在那个 display 使用的。这两个指令请不要一次下完!先执行一次,然后按下 [ctrl]+[alt]+[F3] 去到 X 画面中,你会发现多了一个终端机啰~ 不过,可惜的是,你无法看到终端机的标题、也无法移动终端机,当然也无法调整终端机的大小啊!我们回到刚刚的 tty1 然后再次下达 xterm 指令,理论上应该多一个终端机,去到 tty3 查阅一下。唉~没有多出一个终端机啊? 这是因为两个终端机重叠了~我们又无法移动终端机,所以只看到一个。 接下来,请再次回到 tty1 去下达指令吧!(可能需要 yum install xorg-x11-apps 喔!)
```
3\. 在输入不同的 X client 观察观察,分别去到 tty3 观察喔!
[dmtsai@study ~]$ xclock -display :1 &
[dmtsai@study ~]$ xeyes -display :1 &
```
![分别启动 xclock 时钟与 xeyes 眼睛的结果](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735738058058.jpg)图23.1.5、分别启动 xclock 时钟与 xeyes 眼睛的结果
跟前面一样的,我们又多执行了两个 X client ,其中 xclock 会显示时钟,而 xeyes 则是会出现一双大眼睛来盯着光标! 你可以移动一下光标就可以发现眼睛的焦聚会跑啊 ^_^!不过,目前的四个 X client 通通不能够移动与放大缩小! 如此一来,你怎么在 xterm 下面下达指令啊?当然就很困扰~所以让我们来载入最阳春的窗口管理员吧!
```
4\. 输入可以管理的 window manager,我们这边先以 root 来安装 twm 喔!
[root@study ~]# yum install http://ftp.ksu.edu.tw/FTP/CentOS/6/os/x86_64/\
> Packages/xorg-x11-twm-1.0.3-5.1.el6.x86_64.rpm
# 真要命!CentOS 7 说 twm 已经没有在维护,所以没有提供这玩意儿了!鸟哥只好拿旧版的 twm 来安装!
# 请您自行到相关的网站上找寻这个 twm 啰!因为版本可能会不一样!
[root@study ~]# yum install xorg-x11-fonts-{100dpi,75dpi,Type1}
5\. 接下来就可以开始用 dmtsai 的身份来玩一下这玩意儿了!
[dmtsai@study ~]$ twm -display :1 &
```
![窗口管理员 twm 的功能显示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735738078e3e.jpg)图23.1.6、窗口管理员 twm 的功能显示
回到 tty1 后,用最简单的 twm 这个窗口管理员来管理我们的 X 吧!输入之后,去到 tty3 看看,用鼠标移动一下终端机看看?可以移动了吧?也可以缩小放大窗口啰~同时也出现了标题提示啰~也看到两个终端机啦! 现在终于知道窗口管理员的重要性了吧? ^_^!在黑屏幕地方按下鼠标右键,就会出现类似上面画面最右边的菜单, 你就可以进行额外的管理啰~玩玩看先!
```
6\. 将所有刚刚创建的 X 相关工作全部杀掉!
[dmtsai@study ~]# kill %6 %5 %4 %3 %2 %1
```
很有趣的一个小实验吧~通过这个实验,你应该会对 X server 与 Window manager 及 tty3 以后的终端接口使用方式有比较清楚的了解~加油!
### 23.1.5 我是否需要启用 X Window System
谈了这么多 X 窗口系统方面的信息后,再来聊聊,那么你的 Linux 主机是否需要默认就启动 X 窗口呢? 一般来说,如果你的 Linux 主机定位为网络服务器的话,那么由于 Linux 里面的主要服务的配置文件都是纯文本的格式文件, 相当的容易设置的,所以啊,根本就是不需要 X Window 存在呢!因为 X Window 仅是 Linux 系统内的一个软件而已啊!
但是万一你的 Linux 主机是用来作为你的桌上计算机用的,那么 X Window 对你而言,就是相当重要的一个咚咚了!因为我们日常使用的办公室软件,都需要使用到 X Window 图形的功能呢!此外,以鸟哥的例子来说,俺之前接触到的数值分析模式,需要利用图形处理软件来将数据读取出来, 所以在那部 Linux 主机上面,我一定需要 X Window 的。
由于目前的主机系统配备已经很不错,除非你使用的是单版计算机,否则桌面电脑、笔记本电脑的系统配备要拿来跑 X window 大概都不是问题! 所以,是否默认要启用你的 X window 系统,完全掌握在你的服务器用途考虑上啰!!
';
第二十三章、X Window 设置介绍
最后更新于:2022-04-01 22:17:20
# 第二十三章、X Window 设置介绍
最近更新日期:20//
在 Linux 上头的图形接口我们称之为 X Window System,简称为 X 或 X11 啰! 为何称之为系统呢?这是因为 X 窗口系统又分为 X server 与 X client ,既然是 Server/Client (主从架构) 这就表示其实 X 窗口系统是可以跨网络且跨平台的!X 窗口系统对于 Linux 来说仅是一个软件, 只是这个软件日趋重要喔!因为 Linux 是否能够在桌面电脑上面流行,与这个 X 窗口系统有关啦! 好在,目前的 X 窗口系统整合到 Linux 已经非常优秀了,而且也能够具有 3D 加速的功能, 只是,我们还是得要了解一下 X 窗口系统才好,这样如果出问题,我们才有办法处理啊!
';
22.7 参考资料与延伸阅读
最后更新于:2022-04-01 22:17:17
## 22.7 参考资料与延伸阅读
* [[1]](#ac1)GNU Privacy Guard (GPG) 官方网站的介绍:[http://www.gnupg.org/](http://www.gnupg.org/)
* RPM 包装文件管理程序:[http://www.study-area.org/tips/rpm.htm](http://www.study-area.org/tips/rpm.htm)
* 中文 RPM HOW-TO:[http://www.linux.org.tw/CLDP/RPM-HOWTO.html](http://www.linux.org.tw/CLDP/RPM-HOWTO.html)
* RPM 的使用:[http://linux.tnc.edu.tw/techdoc/rpm-howto.htm](http://linux.tnc.edu.tw/techdoc/rpm-howto.htm)
* 大家来作 RPM :[http://freebsd.ntu.edu.tw/bsd/4/3/2/29.html](http://freebsd.ntu.edu.tw/bsd/4/3/2/29.html)
* 一本 RPM 的原文书:[http://linux.tnc.edu.tw/techdoc/maximum-rpm/rpmbook/](http://linux.tnc.edu.tw/techdoc/maximum-rpm/rpmbook/)
* 台湾网络危机处理小组:[http://www.cert.org.tw/](http://www.cert.org.tw/)
2002/08/21:第一次完成
2003/02/11:重新编排与加入 FAQ
2004/04/11:已经完成了 [Source code 与 Tarball](../Text/index.html) ,开始进行 RPM 与 SRPM 的介绍!(需要耗时多日啊!因为又要进兵营去了!)
2004/04/20:终于给他熬出来啦!又是过了两个休假期间~啊!给我退伍令、其余免谈!
2005/10/02:旧版的 SRPM 数据已经移动到 [此处](http://linux.vbird.org/linux_basic/0520softwaremanager/0530srpm.php) 。
2005/10/03:旧版的针对 Red Hat 与 Mandriva 的版本移动到 [此处](http://linux.vbird.org/linux_basic/0520softwaremanager/0520rpm_and_srpm.php)。
2005/10/03:将原本去年的版本改为 FC4 为范例的模样!
2009/06/20:原本的针对 FC4 写的旧版文章移动到[此处](http://linux.vbird.org/linux_basic/0520softwaremanager/0520rpm_and_srpm-fc4.php)。
2009/09/18:加入了简单的情境仿真,也加入了一些关于 yum 的习题喔!
2015/10/16:加入了 ELRepo 这个专门提供核心给 CentOS 使用的软件库功能介绍!
';
22.6 本章习题
最后更新于:2022-04-01 22:17:15
## 22.6 本章习题
* 情境仿真题:通过 EPEL 安装 NTFS 文件系统所需要的软件
* 目标:利用 EPEL 提供的软件来搜寻是否有 NTFS 所需要的各项模块!;
* 目标:你的 Linux 必须要已经接上 Internet 才行;
* 需求:最好了解磁盘容量是否够用,以及如何启动服务等。
其实这个任务非常简单!因为我们在前面各小节的说明当中已经说明了如何设置 EPEL 的 yum 配置文件,此时你只要通过下面的方式来处理即可:
* 使用 yum --enablerepo=epel search ntfs 找出所需要的软件名称
* 再使用 yum --enablerepo=epel install ntfs-3g ntfsprogs 来安装即可!
* * *
简答题部分:
* 如果你曾经修改过 yum 配置文件内的软件库设置 (/etc/yum.repos.d/*.repo) ,导致下次使用 yum 进行安装时老是发现错误, 此时你该如何是好?先确认你的配置文件确实是正确的,如果没问题,可以将 yum 的高速缓存清除,使用“yum clean all”即可。 事实上, yum 的所有高速缓存、下载软件、下载软件的表头数据,都放置于 /var/cache/yum/ 目录下。
* 简单说明 RPM 与 SRPM 的异同?RPM 文件是由程序打包者 (通常是由 distribution 的开发商) 借由程序的源代码,在特定的平台上面所编译成功的 binary program 的数据,并将该数据制作成为 RPM 的格式,以方便相同软、硬件平台的使用者之安装使用。 在安装时显的很简单,因为程序打包者的平台与使用者所使用的平台默认为相同。
至于 SRPM 则是借由与 RPM 相同的配置文件数据,不过将源代码直接包在 SRPM 文件当中,而不经过编译。 因为 SRPM 所内含的数据为源代码,所以安装时必须要再经过编译的行为才能成为 RPM 并提供使用者安装。
* 假设我想要安装一个软件,例如 pkgname.i386.rpm ,但却老是发生无法安装的问题,请问我可以加入哪些参数来强制安装他?可以加入 --nodeps 等参数。例如 rpm -ivh --nodeps pkgname.i386.rpm
* 承上题,你认为强制安装之后,该软件是否可以正常执行?为什么?一般来说,应该是“不能执行”的,因为该软件具有相依属性的问题, 某些时刻该软件的程序可能需要调用外部的函数库,但函数库可能未安装,因此当然无法执行成功。
* 有些人使用 CentOS 7.x 安装在自己的 Atom CPU 上面,却发现无法安装,在查询了该原版光盘的内容,发现里面的文件名称为 ***.x86_64.rpm 。请问,无法安装的可能原因为何?Atom 虽然也是属于 x86 的架构,但是某些 atom 是属于 32 位的系统。但是 CentOS 7 已经仅释出 64 位的版本,所以当然无法安装了!
* 请问我使用 rpm -Fvh *.rpm 及 rpm -Uvh *.rpm 来升级时,两者有何不同?-Uvh 后面接的软件,如果原本未安装,则直接安装,原本已安装时,则直接升级;
-Fvh 后面接的软件,如果原本未安装,则不安装,原本已安装时,则直接升级;
* 假设有一个厂商推出软件时,自行处理了数码签章,你想要安装他们的软件所以需要使用数码签章,假设数码签章的文件名为 signe, 那你该如何安装?rpm --import signe
* 承上,假设该软件厂商提供了 yum 的安装网址为: http://their.server.name/path/ ,那你该如何处理 yum 的配置文件?可以自行取个文件名,在此例中我们使用“ vim /etc/yum.repos.d/their.repo ”,扩展名要正确! 内容有点像这样即可:
```
[their]
name=their server name
baseurl=http://their.server.name/path/
enable=1
gpgcheck=0
```
然后使用 yum 去安装该软件看看。
';
22.5 重点回顾
最后更新于:2022-04-01 22:17:13
## 22.5 重点回顾
* 为了避免使用者自行编译的困扰,开发商自行在特定的硬件与操作系统平台上面预先编译好软件, 并将软件以特殊格式封包成文件,提供终端用户直接安装到固定的操作系统上,并提供简单的查询/安装/移除等流程。 此称为软件管理员。常见的软件管理员有 RPM 与 DPKG 两大主流。
* RPM 的全名是 RedHat Package Manager,原本是由 Red Hat 公司所发展的,流传甚广;
* RPM 类型的软件中,所含有的软件是经过编译后的 binary program ,所以可以直接安装在使用者端的系统上, 不过,也由于如此,所以 RPM 对于安装者的环境要求相当严格;
* RPM 除了将软件安装至使用者的系统上之外,还会将该软件的版本、名称、文件与目录配置、系统需求等等均记录于数据库 (/var/lib/rpm) 当中,方便未来的查询与升级、移除;
* RPM 可针对不同的硬件等级来加以编译,制作出来的文件可于扩展名 (i386, i586, i686, x86_64, noarch) 来分辨;
* RPM 最大的问题为软件之间的相依性问题;
* SRPM 为 Source RPM ,内含的文件为 Source code 而非为 binary file ,所以安装 SRPM 时还需要经过 compile ,不过,SRPM 最大的优点就是可以让使用者自行修改设置参数 (makefile/configure 的参数) ,以符合使用者自己的 Linux 环境;
* RPM 软件的属性相依问题,已经可以借由 yum 或者是 APT 等方式加以克服。 CentOS 使用的就是 yum 机制。
* yum 服务器提供多个不同的软件库放置个别的软件,以提供用户端分别管理软件类别。
';
22.4 SRPM 的使用 : rpmbuild (Optional)
最后更新于:2022-04-01 22:17:11
## 22.4 SRPM 的使用 : rpmbuild (Optional)
谈完了 RPM 类型的软件之后,再来我们谈一谈包含了 Source code 的 SRPM 该如何使用呢?假如今天我们由网络上面下载了一个 SRPM 的文件,该如何安装他?又,如果我想要修改这个 SRPM 里面源代码的相关设置值,又该如何订正与重新编译呢? 此外,最需要注意的是,新版的 rpm 已经将 RPM 与 SRPM 的指令分开了,SRPM 使用的是 rpmbuild 这个指令,而不是 rpm 喔!
### 22.4.1 利用默认值安装 SRPM 文件 (--rebuid/--recompile)
假设我下载了一个 SRPM 的文件,又不想要修订这个文件内的源代码与相关的设置值, 那么我可以直接编译并安装吗?当然可以!利用 rpmbuild 配合选项即可。选项主要有下面两个:
| | |
| --- | --- |
| --rebuild | 这个选项会将后面的 SRPM 进行“编译”与“打包”的动作,最后会产生 RPM 的文件,但是产生的 RPM 文件并没有安装到系统上。当你使用 --rebuild 的时候,最后通常会发现一行字体: `Wrote: /root/rpmbuild/RPMS/x86_64/pkgname.x86_64.rpm` 这个就是编译完成的 RPM 文件啰!这个文件就可以用来安装啦!安装的时候请加绝对路径来安装即可! |
| --recompile | 这个动作会直接的“编译”“打包”并且“安装”啰!请注意, rebuild 仅“编译并打包”而已,而 recompile 不但进行编译跟打包,还同时进行“安装”了! |
不过,要注意的是,这两个选项都没有修改过 SRPM 内的设置值,仅是通过再次编译来产生 RPM 可安装软件文件而已。 一般来说,如果编译的动作顺利的话,那么编译过程所产生的中间暂存盘都会被自动删除,如果发生任何错误, 则该中间文件会被保留在系统上,等待使用者的除错动作!
问:请由 [http://vault.centos.org/](http://vault.centos.org/) 下载正确的 CentOS 版本中, 在 updates 软件库当中的 ntp 软件 SRPM,请下载最新的那个版本即可,然后进行编译的行为。答:目前 (2015/09) 最新的版本为:ntp-4.2.6p5-19.el7.centos.1.src.rpm 这一个,所以我是这样作的:
* 先下载软件:
wget http://vault.centos.org/7.1.1503/updates/Source/SPackages/ntp-4.2.6p5-19.el7.centos.1.src.rpm
* 再尝试直接编译看看:
rpmbuild --rebuild ntp-4.2.6p5-19.el7.centos.1.src.rpm
* 上面的动作会告诉我还有一堆相依软件没有安装~所以我得要安装起来才行:
yum install libcap-devel openssl-devel libedit-devel pps-tools-devel autogen autogen-libopts-devel
* 再次尝试编译的行为:
rpmbuild --rebuild ntp-4.2.6p5-19.el7.centos.1.src.rpm
* 最终的软件就会被放置到:
/root/rpmbuild/RPMS/x86_64/ntp-4.2.6p5-19.el7.centos.1.x86_64.rpm
上面的测试案例是将一个 SRPM 文件抓下来之后,依据你的系统重新进行编译。一般来说,因为该编译可能会依据你的系统硬件而最优化, 所以可能性能会好一些些,但是...人类根本感受不到那种性能优化的效果~所以并不建议你这么作。此外, 这种情况也很能发生在你从不同的 Linux distribution 所下载的 SRPM 拿来想要安装在你的系统上,这样作才算是有点意义。
一般来说,如果你有需要用到 SRPM 的文件,大部分的原因就是...你需要重新修改里面的某些设置,让软件加入某些特殊功能等等的。 所以啰,此时就得要将 SRPM 拆开,编辑一下编译配置文件,然后再予以重新编译啦!下个小节我们来玩玩修改设置的方式!
### 22.4.2 SRPM 使用的路径与需要的软件
SRPM 既然含有 source code ,那么其中必定有配置文件啰,所以首先我们必需要知道,这个 SRPM 在进行编译的时候会使用到哪些目录呢?这样一来才能够来修改嘛! 不过从 CentOS 6.x 开始 (当然包含我们的 CentOS 7.x 啰),因为每个用户应该都有能力自己安装自己的软件,因此 SRPM 安装、设置、编译、最终结果所使用的目录都与操作者的主文件夹有关~鸟哥假设你用 root 的身份来进行 SRPM 的操作, 那么你应该就会使用到下列的目录喔:
| | |
| --- | --- |
| /root/rpmbuild/SPECS | 这个目录当中放置的是该软件的配置文件,例如这个软件的信息参数、设置项目等等都放置在这里; |
| /root/rpmbuild/SOURCES | 这个目录当中放置的是该软件的原始文件 (*.tar.gz 的文件) 以及 config 这个配置文件; |
| /root/rpmbuild/BUILD | 在编译的过程中,有些暂存的数据都会放置在这个目录当中; |
| /root/rpmbuild/RPMS | 经过编译之后,并且顺利的编译成功之后,将打包完成的文件放置在这个目录当中。里头有包含了 x86_64, noarch.... 等等的次目录。 |
| /root/rpmbuild/SRPMS | 与 RPMS 内相似的,这里放置的就是 SRPM 封装的文件啰!有时候你想要将你的软件用 SRPM 的方式释出时, 你的 SRPM 文件就会放置在这个目录中了。 |
![鸟哥的图示](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-13_5735736501917.gif "鸟哥的图示")
**Tips** 早期要使用 SRPM 时,必须是 root 的身份才能够使用编译行为,同时源代码都会被放置到 /usr/src/redhat/ 目录内喔! 跟目前放置到 /~username/rpmbuild/ 的情况不太一样!
此外,在编译的过程当中,可能会发生不明的错误,或者是设置的错误,这个时候就会在 /tmp 下面产生一个相对应的错误文件,你可以根据该错误文件进行除错的工作呢! 等到所有的问题都解决之后,也编译成功了,那么刚刚解压缩之后的文件,就是在 /root/rpmbild/{SPECS, SOURCES, BUILD} 等等的文件都会被杀掉,而只剩下放置在 /root/rpmbuild/RPMS 下面的文件了!
由于 SRPM 需要重新编译,而编译的过程当中,我们至少需要有 make 与其相关的程序,及 gcc, c, c++ 等其他的编译用的程序语言来进行编译,更多说明请参考[第二十一章源代码所需基础软件](../Text/index.html#tarball_pack)吧。 所以,如果你在安装的过程当中没有选取软件开发工具之类的软件,这时就得要使用上一小节介绍的 yum 来安装就是了! 当然,那个 "Development Tools" 的软件群组请不要忘记安装了!
问:尝试将上个练习下载的 ntp 的 SRPM 软件直接安装到系统中 (不要编译),然后查阅一下所有用到的目录为何?答:
```
# 1\. 鸟哥这里假设你用 root 的身份来进行安装的行为喔!
[root@study ~]# rpm -ivh ntp-4.2.6p5-19.el7.centos.1.src.rpm
Updating / installing...
1:ntp-4.2.6p5-19.el7.centos.1 ################################# [100%]
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
# 会有一堆 warning 的问题,那个不要理它!可以忽略没问题的!
# 2\. 查阅一下 /root/rpmbuild 目录的内容!
[root@study ~]# ll -l /root/rpmbuild
drwxr-xr-x. 3 root root 39 Sep 8 16:16 BUILD
drwxr-xr-x. 2 root root 6 Sep 8 16:16 BUILDROOT
drwxr-xr-x. 4 root root 32 Sep 8 16:16 RPMS
drwxr-xr-x. 2 root root 4096 Sep 9 09:43 SOURCES
drwxr-xr-x. 2 root root 39 Sep 9 09:43 SPECS # 这个家伙最重要!
drwxr-xr-x. 2 root root 6 Sep 8 14:51 SRPMS
[root@study ~]# ll -l /root/rpmbuild/{SOURCES,SPECS}
/root/rpmbuild/SOURCES:
-rw-rw-r--. 1 root root 559 Jun 24 07:44 ntp-4.2.4p7-getprecision.patch
-rw-rw-r--. 1 root root 661 Jun 24 07:44 ntp-4.2.6p1-cmsgalign.patch
.....(中间省略).....
/root/rpmbuild/SPECS:
-rw-rw-r--. 1 root root 41422 Jun 24 07:44 ntp.spec # 这就是重点!
```
### 22.4.3 配置文件的主要内容 (*.spec)
如前一个小节的练习,我们知道在 /root/rpmbuild/SOURCES 里面会放置原始文件 (tarball) 以及相关的修补档 (patch file), 而我们也知道编译需要的步骤大抵就是 ./configure, make, make check, make install 等,那这些动作写入在哪里呢? 就在 SPECS 目录中啦!让我们来瞧一瞧 SPECS 里面的文件说些什么吧!
```
[root@study ~]# cd /root/rpmbuild/SPECS
[root@study SPECS]# vim ntp.spec
# 1\. 首先,这个部分在介绍整个软件的基本相关信息!不论是版本还是释出次数等。
Summary: The NTP daemon and utilities # 简易的说明这个软件的功能
Name: ntp # 软件的名称
Version: 4.2.6p5 # 软件的版本
Release: 19%{?dist}.1 # 软件的释出版次
# primary license (COPYRIGHT) : MIT # 下面有很多 # 的注解说明!
.....(中间省略).....
License: (MIT and BSD and BSD with advertising) and GPLv2
Group: System Environment/Daemons
Source0: http://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-4.2/ntp-%{version}.tar.gz
Source1: ntp.conf # 写 SourceN 的就是源代码!
Source2: ntp.keys # 源代码可以有很多个!
.....(中间省略).....
Patch1: ntp-4.2.6p1-sleep.patch # 接下来则是补丁文件,就是 PatchN 的目的!
Patch2: ntp-4.2.6p4-droproot.patch
.....(中间省略).....
# 2\. 这部分则是在设置相依属性需求的地方!
URL: http://www.ntp.org # 下面则是说明这个软件的相依性,
Requires(post): systemd-units # 还有编译过程需要的软件有哪些等等!
Requires(preun): systemd-units
Requires(postun): systemd-units
Requires: ntpdate = %{version}-%{release}
BuildRequires: libcap-devel openssl-devel libedit-devel perl-HTML-Parser
BuildRequires: pps-tools-devel autogen autogen-libopts-devel systemd-units
.....(中间省略).....
%package -n ntpdate # 其实这个软件包含有很多次软件喔!
Summary: Utility to set the date and time via NTP
Group: Applications/System
Requires(pre): shadow-utils
Requires(post): systemd-units
Requires(preun): systemd-units
Requires(postun): systemd-units
.....(中间省略).....
# 3\. 编译前的预处理,以及编译过程当中所需要进行的指令,都写在这里
# 尤其 %build 下面的数据,几乎就是 makefile 里面的信息啊!
%prep # 这部份大多在处理补丁的动作!
%setup -q -a 5
%patch1 -p1 -b .sleep # 这些 patch 当然与前面的 PatchN 有关!
%patch2 -p1 -b .droproot
.....(中间省略).....
%build # 其实就是 ./configure, make 等动作!
sed -i 's|$CFLAGS -Wstrict-overflow|$CFLAGS|' configure sntp/configure
export CFLAGS="$RPM_OPT_FLAGS -fPIE -fno-strict-aliasing -fno-strict-overflow"
export LDFLAGS="-pie -Wl,-z,relro,-z,now"
%configure \ # 不就是 ./configure 的意思吗!
--sysconfdir=%{_sysconfdir}/ntp/crypto \
--with-openssl-libdir=%{_libdir} \
--without-ntpsnmpd \
--enable-all-clocks --enable-parse-clocks \
--enable-ntp-signd=%{_localstatedir}/run/ntp_signd \
--disable-local-libopts
echo '#define KEYFILE "%{_sysconfdir}/ntp/keys"' >> ntpdate/ntpdate.h
echo '#define NTP_VAR "%{_localstatedir}/log/ntpstats/"' >> config.h
make %{?_smp_mflags} # 不就是 make 了吗!
.....(中间省略).....
%install # 就是安装过程所进行的各项动作了!
make DESTDIR=$RPM_BUILD_ROOT bindir=%{_sbindir} install
mkdir -p $RPM_BUILD_ROOT%{_mandir}/man{5,8}
sed -i 's/sntp\.1/sntp\.8/' $RPM_BUILD_ROOT%{_mandir}/man1/sntp.1
mv $RPM_BUILD_ROOT%{_mandir}/man{1/sntp.1,8/sntp.8}
rm -rf $RPM_BUILD_ROOT%{_mandir}/man1
.....(中间省略).....
# 4\. 这里列出,这个软件释出的文件有哪些的意思!
%files # 这软件所属的文件有哪些的意思!
%dir %{ntpdocdir}
%{ntpdocdir}/COPYRIGHT
%{ntpdocdir}/ChangeLog
.....(中间省略).....
# 5\. 列出这个软件的更改历史纪录档!
%changelog
* Tue Jun 23 2015 CentOS Sources <bugs@centos.org> - 4.2.6p5-19.el7.centos.1
- rebrand vendorzone
* Thu Apr 23 2015 Miroslav Lichvar <mlichvar@redhat.com> 4.2.6p5-19.el7_1.1
- don't step clock for leap second with -x option (#1191122)
.....(后面省略).....
```
要注意到的是 ntp.sepc 这个文件,这是主要的将 SRPM 编译成 RPM 的配置文件,他的基本规则可以这样看:
1. 整个文件的开头以Summary为开始,这部份的设置都是最基础的说明内容;
2. 然后每个不同的段落之间,都以 % 来做为开头,例如 %prep 与 %install 等;
我们来谈一谈几个常见的 SRPM 设置段落:
* 系统整体信息方面:
刚刚你看到的就有下面这些重要的咚咚啰:
| 参数 | 参数意义 |
| --- | --- |
| Summary | 本软件的主要说明,例如上表中说明了本软件是针对 NTP 的软件功能与工具等啦! |
| Name | 本软件的软件名称 (最终会是 RPM 文件的文件名构成之一) |
| Version | 本软件的版本 (也会是 RPM 文件名的构成之一) |
| Release | 这个是该版本打包的次数说明 (也会是 RPM 文件名的构成之一)。由于我们想要动点手脚,所以请将“ 19%{?dist}.1 ” 修改为“ 20.vbird ” 看看 |
| License | 这个软件的授权模式,看起来涵盖了所有知名的 Open source 授权啊!! |
| Group | 这个软件在安装的时候,主要是放置于哪一个软件群组当中 (yum grouplist 的特点!); |
| URL | 这个源代码的主要官方网站; |
| SourceN | 这个软件的来源,如果是网络上下载的软件,通常一定会有这个信息来告诉大家这个原始文件的来源! 此外,如果有多个软件来源,就会以 Source0, Source1... 来处理源代码喔! |
| PatchN | 就是作为补丁的 patch file 啰!也是可以有好多个! |
| BuildRoot | 设置作为编译时,该使用哪个目录来暂存中间文件 (如编译过程的目标文件/链接文件等档)。 |
| 上述为必须要存在的项目,下面为可使用的额外设置值 |
| Requires | 如果你这个软件还需要其他的软件的支持,那么这里就必需写上来,则当你制作成 RPM 之后,系统就会自动的去检查啦!这就是“相依属性”的主要来源啰! |
| BuildRequires | 编译过程中所需要的软件。Requires 指的是“安装时需要检查”的,因为与实际运行有关,这个 BuildRequires 指的是“编译时”所需要的软件,只有在 SRPM 编译成为 RPM 时才会检查的项目。 |
上面几个数据通常都必需要写啦!但是如果你的软件没有相依属性的关系时,那么就可以不需要那个 Requires 啰! 根据上面的设置,最终的文件名就会是“{Name}-{Version}-{Release}.{Arch}.rpm”的样式, 以我们上面的设置来说,文件名应该会是“ntp-4.2.6p5-20.vbird.x86_64.rpm”的样子啰!
* %description:
将你的软件做一个简短的说明!这个也是必需要的。还记得使用“ rpm -qi 软件名称 ”会出现一些基础的说明吗? 上面这些东西包括 Description 就是在显示这些重要信息的啦!所以,这里记得要详加解释喔!
* %prep:
pre 这个关键字原本就有“在...之前”的意思,因此这个项目在这里指的就是“尚未进行设置或安装之前,你要编译完成的 RPM 帮你事先做的事情”,就是 prepare 的简写啰!那么他的工作事项主要有:
1. 进行软件的补丁 (patch) 等相关工作;
2. 寻找软件所需要的目录是否已经存在?确认用的!
3. 事先创建你的软件所需要的目录,或者事先需要进行的任务;
4. 如果待安装的Linux系统内已经有安装的时候可能会被覆盖掉的文件时,那么就必需要进行备份(backup)的工作了!
在本案例中,你会发现程序会使用 patch 去进行补丁的动作啦!所以程序的源代码才会更新到最新啊!
* %build:
build 就是创建啊!所以当然啰,这个段落就是在谈怎么 make 编译成为可执行的程序啰! 你会发现在此部分的程序码方面,就是 ./configure, make 等项目哩!一般来说,如果你会使用 SRPM 来进行重新编译的行为, 通常就是要重新 ./configure 并给予新的参数设置!于是这部份就可能会修改到!
* %install:
编译完成 (build) 之后,就是要安装啦!安装就是写在这里,也就是类似 Tarball 里面的 make install 的意思啰!
* %files:
这个软件安装的文件都需要写到这里来,当然包括了“目录”喔!所以连同目录请一起写到这个段落当中!以备查验呢!^_^ !此外,你也可以指定每个文件的类型,包括文档文件 (%doc 后面接的) 与配置文件 (%config 后面接的) 等等。
* %changelog:
这个项目主要则是在记录这个软件曾经的更新纪录啰!星号 (*) 后面应该要以时间,修改者, email 与软件版本来作为说明, 减号 (-) 后面则是你要作的详细说明啰!在这部份鸟哥就新增了两行,内容如下:
```
%changelog
* Wed Sep 09 2015 VBird Tsai <vbird@mail.vbird.idv.tw>- 4.2.6p5-20.vbird
- only rbuild this SRPM to RPM
* Tue Jun 23 2015 CentOS Sources <bugs@centos.org> - 4.2.6p5-19.el7.centos.1
- rebrand vendorzone
....(下面省略)....
```
修改到这里也差不多了,您也应该要了解到这个 ntp.spec 有多么重要!我们用 rpm -q 去查询一堆信息时, 其实都是在这里写入的!这样了解否?接下来,就让我们来了解一下如何将 SRPM 给他编译出 RPM 来吧!
### 22.4.4 SRPM 的编译指令 (-ba/-bb)
要将在 /root/rpmbuild 下面的数据编译或者是单纯的打包成为 RPM 或 SRPM 时,就需要 rpmbuild 指令与相关选项的帮忙了!我们只介绍两个常用的选项给您了解一下:
```
[root@study ~]# rpmbuild -ba ntp.spec <==编译并同时产生 RPM 与 SRPM 文件
[root@study ~]# rpmbuild -bb ntp.spec <==仅编译成 RPM 文件
```
这个时候系统就会这样做:
1. 先进入到 BUILD 这个目录中,亦即是: /root/rpmbuild/BUILD 这个目录;
2. 依照 *.spec 文件内的 Name 与 Version 定义出工作的目录名称,以我们上面的例子为例,那么系统就会在 BUILD 目录中先删除 ntp-4.2.6p5 的目录,再重新创建一个 ntp-4.2.6p5 的目录,并进入该目录;
3. 在新建的目录里面,针对 SOURCES 目录下的来源文件,也就是 *.spec 里面的 Source 设置的那个文件,以 tar 进行解压缩,以我们这个例子来说,则会在 /root/rpmbuild/BUILD/ntp-4.2.6p5 当中,将 /root/rpmbuild/SOURCES/ntp-* 等等多个源代码文件进行解压缩啦!
4. 再来开始 %build 及 %install 的设置与编译!
5. 最后将完成打包的文件给他放置到该放置的地方去,如果你的系统是 x86_64 的话,那么最后编译成功的 *.x86_64.rpm文件就会被放置在 /root/rpmbuild/RPMS/x86_64 里面啰!如果是 noarch 那么自然就是 /root/rpmbuild/RPMS/noarch 目录下啰!
整个步骤大概就是这样子!最后的结果数据会放置在 RPMS 那个目录下面就对啦!我们这个案例中想要同时打包 RPM 与 SRPM , 因此请您自行处理一下“ rpmbuild -ba ntp.spec ”吧!
```
[root@study ~]# cd /root/rpmbuild/SPECS
[root@study SPECS]# rpmbuild -ba ntp.spec
.....(前面省略).....
Wrote: /root/rpmbuild/SRPMS/ntp-4.2.6p5-20.vbird.src.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/ntp-4.2.6p5-20.vbird.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/noarch/ntp-perl-4.2.6p5-20.vbird.noarch.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/ntpdate-4.2.6p5-20.vbird.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/sntp-4.2.6p5-20.vbird.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/noarch/ntp-doc-4.2.6p5-20.vbird.noarch.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/ntp-debuginfo-4.2.6p5-20.vbird.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.xZh6yz
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd ntp-4.2.6p5
+ /usr/bin/rm -rf /root/rpmbuild/BUILDROOT/ntp-4.2.6p5-20.vbird.x86_64
+ exit 0
[root@study SPECS]# find /root/rpmbuild -name 'ntp*rpm'
/root/rpmbuild/RPMS/x86_64/ntp-4.2.6p5-20.vbird.x86_64.rpm
/root/rpmbuild/RPMS/x86_64/ntpdate-4.2.6p5-20.vbird.x86_64.rpm
/root/rpmbuild/RPMS/x86_64/ntp-debuginfo-4.2.6p5-20.vbird.x86_64.rpm
/root/rpmbuild/RPMS/noarch/ntp-perl-4.2.6p5-20.vbird.noarch.rpm
/root/rpmbuild/RPMS/noarch/ntp-doc-4.2.6p5-20.vbird.noarch.rpm
/root/rpmbuild/SRPMS/ntp-4.2.6p5-20.vbird.src.rpm
# 上面分别是 RPM 与 SRPM 的文件文件名!
```
您瞧!嘿嘿~有 vbird 的软件出现了!相当有趣吧!另外,有些文件软件是与硬件等级无关的 (因为单纯的文件啊!),所以如上表所示, 你会发现 ntp-doc-4.2.6p5-20.vbird.noarch.rpm 是 noarch 喔!有趣吧!
### 22.4.5 一个打包自己软件的范例
这个就有趣了!我们自己来编辑一下自己制作的 RPM 怎么样?会很难吗?完全不会! 我们这里就举个例子来玩玩吧!还记得我们在前一章谈到 Tarball 与 make 时,曾经谈到的 [main](../Text/index.html#make) 这个程序吗?现在我们将这个程序加上 Makefile 后, 将他制作成为 main-0.1-1.x86_64.rpm 好吗?那该如何进行呢?下面就让我们来处理处理吧!
* 制作源代码文件 tarball 产生:
因为鸟哥的网站并没有直接释出 main-0.2,所以假设官网提供的是 main-0.l 版本之外,同时提供了一个 patch 文件~ 那我们就得要这样作:
* main-0.1.tar.gz 放在 /root/rpmbuild/SOURCES/
* main_0.1_to_0.2_patch 放在 /root/rpmbuild/SOURCES/
* main.spec 自行撰写放在 /root/rpmbuild/SPECS/
```
# 1\. 先来处理源代码的部份,假设你的 /root/rpmbuild/SOURCES 已经存在了喔!
[root@study ~]# cd /root/rpmbuild/SOURCES
[root@study SOURCES]# wget http://linux.vbird.org/linux_basic/0520source/main-0.1.tgz
[root@study SOURCES]# wget http://linux.vbird.org/linux_basic/0520source/main_0.1_to_0.2.patch
[root@study SOURCES]# ll main*
-rw-r--r--. 1 root root 703 Sep 4 14:47 main-0.1.tgz
-rw-r--r--. 1 root root 1538 Sep 4 14:51 main_0.1_to_0.2.patch
```
接下来就是 spec 文件的创建啰!
* 创建 *.spec 的配置文件
这个文件的创建是所有 RPM 制作里面最重要的课题!你必须要仔细的设置他,不要随便处理!仔细看看吧! 有趣的是,CentOS 7.x 会主动的将必要的设置参数列出来喔!相当有趣! ^_^
```
[root@study ~]# cd /root/rpmbuild/SPECS
[root@study SPECS]# vim main.spec
Name: main
Version: 0.1
Release: 1%{?dist}
Summary: Shows sin and cos value.
Group: Scientific Support
License: GPLv2
URL: http://linux.vbird.org/
Source0: main-0.1.tgz # 这两个文件名要正确喔!
Patch0: main_0.1_to_0.2.patch
%description
This package will let you input your name and calculate sin cos value.
%prep
%setup -q
%patch0 -p1 # 要用来作为 patch 的动作!
%build
make clean main # 编译就好!不要安装!
%install
mkdir -p %{buildroot}/usr/local/bin
install -m 755 main %{buildroot}/usr/local/bin # 这才是顺利的安装行为!
%files
/usr/local/bin/main
%changelog
* Wed Sep 09 2015 VBird Tsai <vbird@mail.vbird.idv.tw> 0.2
- build the program
```
* 编译成为 RPM 与 SRPM
老实说,那个 spec 文件创建妥当后,后续的动作就简单的要命了!开始来编译吧!
```
[root@study SPECS]# rpmbuild -ba main.spec
.....(前面省略).....
Wrote: /root/rpmbuild/SRPMS/main-0.1-1.el7.centos.src.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/main-0.1-1.el7.centos.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/main-debuginfo-0.1-1.el7.centos.x86_64.rpm
```
很快的,我们就已经创建了几个 RPM 文件啰!接下来让我们好好测试一下打包起来的成果吧!
* 安装/测试/实际查询
```
[root@study ~]# yum install /root/rpmbuild/RPMS/x86_64/main-0.1-1.el7.centos.x86_64.rpm
[root@study ~]# rpm -ql main
/usr/local/bin/main <==自己尝试执行 main 看看!
[root@study ~]# rpm -qi main
Name : main
Version : 0.1
Release : 1.el7.centos
Architecture: x86_64
Install Date: Wed 09 Sep 2015 04:29:08 PM CST
Group : Scientific Support
Size : 7200
License : GPLv2
Signature : (none)
Source RPM : main-0.1-1.el7.centos.src.rpm
Build Date : Wed 09 Sep 2015 04:27:29 PM CST
Build Host : study.centos.vbird
Relocations : (not relocatable)
URL : http://linux.vbird.org/
Summary : Shows sin and cos value.
Description :
This package will let you input your name and calculate sin cos value.
# 看到没?属于你自己的软件喔!真是很愉快的啦!
```
用很简单的方式,就可以将自己的软件或者程序给他修改与设置妥当!以后你就可以自行设置你的 RPM 啰!当然,也可以手动修改你的 SRPM 的来源文件内容啰!
';