[OpenBSD]

[索引] [第四章 - 安装指南] [第六章 - 网络]

5 - 从源码构建系统


目录


5.1 - OpenBSD不同版本的类型

有三款不同"类型"的OpenBSD版本: 如图所示, 这些不同版本的发展线路像这样:
       ,------o-----------o----X                    4.5 Stable
       |      .           .
       |      .    ,------o---------o----X          4.6 Stable
       |      .    |      .         .
       |      .    |      .    ,----o----------o--> 4.7 Stable
       |      .    |      .    |    .          .
       |      .    |      .    |    .    ,-----o--> 4.8 Stable
       |      .    |      .    |    .    |     .
       |      .    |      .    |    .    |     .
 -->4.5Rel----->4.6Rel----->4.7Rel----->4.8Rel----> Current 

          Time --->

-Current -当前版 拥有充满活力的OpenBSD社区最新的开发成果, 并在最终形成下一个发行版——OpenBSD开发社区每6个月发布一个新的发行版, 到时当前版就变成了新的发行版, 源代码树不再更改, 每个发行版永远不会变化;它们被制作成CD发行或放在FTP服务器上。

-Stable -稳定版基于发行板, 而且是OpenBSD开发路线上该版本的一个分支, 当一个非常重要的安全补丁发布时, 它会被融入稳定版这个分支;基于这个原因, 稳定版也被认为是"补丁"分支。在上面的插图里, 竖线表示发行版经过更新安全补丁形成稳定版。您也会注意到上面的例子中4.5稳定版用一些"."连到了4.7发行版, 4.6稳定版也经过一串"."的路线连接到4.8的发行版上——这条线代表的意思是OpenBSD开发团队仅对当前的发行版及前两个版本提供支持和维护(支持旧版本要花费资源和时间的, 虽然我们在技术上可以继续提供对旧版本的支持, 但是我们更愿意把资源和时间集中利用在给用户提供需要的新功能上。从发行版到稳定版的编译过程设计的非常简单(比如4.8的发行版更新到4.8的稳定版)。

稳定版 是发行版加上在勘误表上公布的安全补丁。稳定版的操作与同版本号的发行版是一样的。 如果用户手册必须变动, 它可能也不会被加入到稳定版中, 换句话说新的设备驱动程序和新特征不会加入到稳定版中。

有必要在这里说明:稳定版中"稳定"这个词并非暗示当前版是不可靠的, 相反, 当前版是对系统不断修改和进化的;反而稳定版的操作及API将不会变化, 这样您就不会因为有新特色就去再熟悉系统和更改您的任何配置, 或者因为使用新程序给系统带来任何不可预料的问题。

事实上, 我们希望OpenBSD不断改进, 目标就是让当前版更可靠, 更安全, 当然还有比稳定版有更多的新特色。坦率地讲最好的OpenBSD版本是当前版。

警告:因为当前版在不断发展中。它的代码每分钟都可能在更改, 并且有充足的理由可以认为更改中的系统代码要在一段时间内经过几次调整才可以变成正式的源代码。虽然开发者非常努力的工作以确保整个系统顺利编译并没有大的纰漏, 但完全有可能您得到的一份当前系统代码不能编译成功, 不过也可能5分钟以后它已经被修正了。还有可能您会遇到设备检修日或者开发者正在更新主要系统时, 那意味着您无法下载源码。如果您对这些可能发生的事情没有心理准备, 建议您还是不要使用当前版的OpenBSD。

多数用户更应该运行稳定版或发行版。尽管如此, 很多人在生产环境中运行当前版, 这样的做法对确定当前版是否存在漏洞和测试其新特征是至关重要的。可是如果您不知道怎样描述, 诊断, 和解决一个问题, 那就不要告诉您自己(或其他人)您正在通过"使用当前版"来帮助OpenBSD项目,那没用。像这样的报告——"它不工作了"并不是一个有意义的错误报告" 。"最近的pciide driver程序的修改与我的Slugchip-based IDE 网卡不兼容。并和系统的……"这样的错误报告可能会更有意义。

有时很多"普通"用户也甘愿"冒险"使用当前版的OpenBSD, 最可能的原因是这些用户的一些硬件在发行版上没有提供支持(所以, 稳定版上也不会提供), 还有一种可能是用户希望尝试当前版的新特征。这种情况下用户或者使用当前版或者不使用他们的硬件。这样看起来当前版也没有那么令人敬而远之是吧, 不管怎样, 大家总不能只把希望寄托在等着开发者来帮您。

快照版

在两个正式发行版推出之间, 您也可以通过FTP镜像站点得到快照版, 顾名思义, 无论是什么代码, 代码作者会在第一时间把源代码放到特定平台上的快照代码树中, 请记住, 在某些平台上快照版有可能会经过数天的时间才会完成并分发。我们不承诺快照版的软件功能完整甚至不承诺您可以安装它。通常是一个需要测试的变更导致产生了新的快照, 一些平台快照每天都在构建, 另外一些平台则没有这样频繁。如果您想运行当前办版, 一个最近的快照版通常包含了所有您需要的东西, 并且如果您要通过源代码构建当前版, 在此之前您必须先升级到快照版。

有时人们会问有没有可能通过什么途径得到一份完全准确的快照版源代码以便用户自己构建一个快照版。答案是不行, 第一, 这样做没有明显的益处, 第二, 构建快照版要看是否有需求, 是否时间允许, 是否当时可以抽出人手。有些比较快的平台, 可能一天释放出几个版本的快照, 而一些比较慢的平台可能会花上一周或更长的时间构建一个快照版。如果在源代码树中为每个快照版作标记那是很不现实的。第三, 快照经常包含一些具有实验性质的代码, 这些代码并未进入代码树。

Upgrade与Update

您会经常看到"Upgrading(升级)"或"Updating(更新)"OpenBSD的说法, 虽然这两个词的意思很接近, 但是用在OpenBSD中还是有一些区别的。

Upgrading(升级) 是一个安装OpenBSD新版本的过程, 升级后的版本拥有新功能。例如, 从4.7升级到4.8, 或从6月12号的快照升级到6月20号的快照。升级的特点是, 您必须考虑是升级到当前版还是运行升级的OpenBSD(根据升级指南按新版本的要求调整系统)。

Updating(更新) 在不改变原有系统的基本功能和二进制兼容性的状况下打补丁的过程。它的特点是通过安装补丁程序(下载单独的补丁源代码并编译, 安装)或者按照稳定版制作流程将系统更新为同版本号的OpenBSD稳定版分支的过程。当您更新系统时, 系统从发行版更新为稳定版, 例如:4.8发行版变成版本号相同的4.8的稳定版。这个更新过程是"无痛苦"的, 例如, 您不必更改 /etc 目录下的文件和其它系统配置。

例如, 您原来从CD安装一个了OpenBSD 4.8发行版的, 然后用少量的时间将系统更新成OpenBSD 4.8的稳定版, 然后再用OpenBSD 4.7发行版的CD将它升级为OpenBSD 4.7的发行版, 再用少量的时间将它更新, 然后升级为4.8的发行版。

保持同步

把OpenBSD理解成一个体系完整的操作系统是非常重要的, 它不是由一个内核加上很多的应用程序(译者注:应该是指像linux的各种发行版本吧? 猜测), 您必须确保您的内核, "用户岛"(支持的应用和文件)及ports 树都是同步的, 否则就会有麻烦。从另一个角度说(因为人们总是在这里犯错), 您不能在一个月前的老系统上运行最新的ports树的或者重新编译一个当前版的内核并希望它可以与发行版的用户岛一起工作。没错它意味着如果您想运行今天刚被加进ports上新程序您必须升级您的系统。非常抱歉, 但这里不得不重复, OpenBSD的资源很有限。

还有一个也需要明白的是OpenBSD仅支持一个方向上的升级:从老版本升级到新版本, 和从稳定版升级到当前版。例如:您正在使用4.8的当前版, 但是觉得它不太安全, 想让系统变成4.8的稳定版——这样做是不行的。这个您自己决定, 如果您用非官方的方式"升级"后系统出现问题, 开发团队也无能为力。 这也就是说, 您在决定升级到当前版之前一定要深思熟虑。

5.2 - 为什么我需要从源代码构建系统?

实际上, 您几乎无需这样做。

一些为什么不从源代码编译系统的原因:

一些您可能希望或必须从源代码编译系统的原因:

OpenBSD团队一直在推出各种平台上基于当前版的非常正规的快照版, 快照版包含了当前版的所有功能, 如果您想运行当前版, 也许快照版是个不错的选择。

最普遍的从源代码构建系统的原因是想把系统更新成稳定版, 这是唯一被支持的将发行版更新成稳定版的方式。

5.3 - 从源码构建系统

5.3.1 - 构建过程纵览

从源码构建OpenBSD系统包括下面几个步骤:

一些用户可能希望执行两个另外的步骤, 取决于他们想构建什么样的系统或是否安装了"X":

5.3.2 - 安装或升级到最新的二进制文件

从源代码构建系统的第一个步骤就是确保您安装了最新的二进制文件。从下面的表格里找出您的位置, 目标及应该安装或升级到哪种二进制文件:
You are at Goal Binary upgrade to then ...
Old -release New release Newest release Done!
-release -stable Newest release Fetch & build -stable
Old -stable -stable Newest release Fetch & build -stable
-release -current Latest Snapshot (optional) Fetch & build -current
Old -current -current Latest Snapshot (optional) Fetch & build -current

我们推荐您在安装时选择"升级"选项来进行二进制文件的安装。如果不行, 您也可以参考这里的方法解压二进制文件。无论如何, 您必须完整地升级, 即使升级会对用户或/etc目录造成影响。

5.3.3 - 获取相关的源代码

OpenBSD的源代码是用CVS系统进行控制管理的, 而cvs(1)是用来从您想得到的源上拖一份拷贝到您本地计算机。这个过程可以通过一个AnonCVS服务器完成, (AnonCVS 服务器是一台OpenBSD使用的保存了OpenBSD项目所有资源的公共CVS仓库);也可以用CVSup从您维护的本地CVS仓库完成, 或者用CVSync软件包, 它在packages里面提供。 CVSup也可以被用做"提取"模式, 不过我们不在这里讨论。如果您要在多台计算机上维护源代码树, 您可能发现用CVSup或者CVSync在本地建立并维护CVS仓库是一个不错的选择。

当您选定AnonCVS服务器后, 您必须"提取"源代码树, 然后您可以运行"update"维护您的源代码树, 也就是把升级文件拖到本地代码树中。

CVS(1)命令有很多参数, 一些参数是提取和更新本地代码树必需的, 其它的参数可能破坏您本地的代码树, 参照并理解这里的说明是很重要的。

跟进成 -当前版

本例中我们假设使用一台被称为anoncvs@anoncvs.example.org:/cvs的公用AnonCVS服务器,我们 同样假设您使用sh(1)作为您的shell, 如果您使用了一个不同的shell, 您需要调整这里的部分命令。

提取一个当前版的CVS src树, 您可以用下面的命令:

# cd /usr
# export CVSROOT=anoncvs@anoncvs.example.org:/cvs
# cvs -d$CVSROOT checkout -P src

一旦您有了源代码树, 您稍后可以更新它:

# cd /usr/src
# export CVSROOT=anoncvs@anoncvs.example.org:/cvs
# cvs -d$CVSROOT up -Pd
跟进成 -稳定版

如果您想提取稳定版分支, 那您需要在check out里使用修饰符"-r":

# cd /usr
# export CVSROOT=anoncvs@anoncvs.example.org:/cvs
# cvs -d$CVSROOT checkout -rOPENBSD_4_8 -P src

它将从OpenBSD_4_8分支把src树拖下来, OpenBSD_4_8分支也被称作"补丁分支"或"稳定版"。您更新源代码也一样:

# cd /usr/src
# export CVSROOT=anoncvs@anoncvs.example.org:/cvs
# cvs -d$CVSROOT up -rOPENBSD_4_8 -Pd

事实上CVS足够体贴地在提取文件系统时粘了一个"标签", 您不用输入上面命令的"-rOPENBSD_4_8"这部分, CVS将一直记着"-rOPENBSD_4_8"这些内容, 除非您明确的清除它们或使用"-A" 选项更新标签。可是, 也许在CVS命令行里多提供一些参数比少提供一些参数好。

这里仅仅对"src" 树进行了同步, 您还需对"xenocara"树及"ports"树做同样的步骤。所有的OpenBSD组件必须保持同步, 您所用到的所有的树应该同时提取和更新。您可以用一条命令语句同时提取这些树(以稳定版为例):

# export CVSROOT=anoncvs@anoncvs.example.org:/cvs
# cd /usr
# cvs -d$CVSROOT checkout -rOPENBSD_4_8 -P src ports xenocara

然而, 更新过程必须在各自的目录中逐项完成。

在这点上无论您是想更新成稳定版或者升级为当前版您必须有一个有效的源代码树。这个过程要求您非常仔细, 可能您本想把代码树更新为稳定版却因参数不对升级成当前版了。

预先装入src.tar.gz, sys.tar.gz树

虽然您可以通过AnonCVS服务器下载整个代码树, 然而, 如果您先从OpenBSD发行版CD或FTP服务器上将代码树预装载到您的本地计算机上, 将大大节省您的带宽和时间, 特别是您想将发行版更新为稳定版时, 稳定版的源代码树只在发行版的基础上对少量文件进行了更改。

把源代码树从CD光盘上解压到/usr/src目录里(假设CD已经被挂载到/mnt):

# cd /usr/src; tar xzf /mnt/src.tar.gz
# cd /usr; tar xzf /mnt/xenocara.tar.gz
# cd /usr; tar xzf /mnt/ports.tar.gz

原代码树也可以通过FTP服务器下载, 它在ftp上被分割成了两个文件, 这样做对那些只想用其中某一个文件进行更新或升级的用户来说的可以明显地减少下载时间。这两个文件分别是sys.tar.gz(它包含了用来产生内核的文件)和src.tar.gz(包含了除ports树及X11的源代码外的其它"用户岛"应用程序)。通常情况下, 无论怎样您都需要安装这两个文件。 我们假设您已经把src.tar.gz 和 sys.tar.gz这两个文件拷贝到了/usr目录下:

# cd /usr/src
# tar xzf ../sys.tar.gz
# tar xzf ../src.tar.gz
# cd /usr
# tar xzf xenocara.tar.gz
# tar xzf ports.tar.gz

并非所有的人需要全部解压缩这些系统创建组件, 但是因为所有系统组件必须进行同步, 您通常情况下需要在本地磁盘中预先装入这些系统组件。

通常的CVS建议如前文所述, 一些选项确保了OpenBSD可以得到正确的src树。上面的"-P"选项就是其中之一:它删除那些空目录。源代码树经过多年的演变, 很多目录被建立或者删除了, 但有时某个空的老目录可能会和一个当前使用的新文件同名。没有使用"-P"参数您刚刚提取的源代码可能无法编译成功。

还有在"update"命令更新时使用的"-d"选项——它重新创建在初次checkout时加入的目录。要想成功更新您必须使用"-Pd"选项。 有经验的CVS用户可能对我们例子中指定并使用的CVSROOT产生疑问, 因为它应该包含CVS服务器的具体的地址, 这是正确的, 用户有足够的时间用自己需要的服务器修改默认的"CVSROOT=anoncvs@anoncvs.example.org:/cvs", 很多人建议在例子中总是指定一个明确的CVS仓库。值得注意的是, 当CVS(1)可以直接使用CVSROOT环境变量时因为前提条件是它的其余其余参数是不变的。 还有一个好方法是在您的主目录下建立一个 .cvsrc文件, 制定某些默认的选项。这里有一个 .cvsrc文件的例子: example.cvsrc文件:

$ more ~/.cvsrc
cvs -q -danoncvs@anoncvs.example.org:/cvs
diff -up
update -Pd
checkout -P  

此文件让cvs使用指定的AnonCVS服务器——anoncvs@anoncvs.example.org:/cvs,隐藏所有一般不需要的屏幕信息("-q"是"quiet",安静的),"cvs up"命令默认使用 "-Pd"选项,"cvs diff" 因为"-u"选项默认提供"unified diffs",还有"cvs checkout"将使用"-P"选项。虽然这很方便, 但是如果您忘记了要先建立这个文件, 或者说您在没有这个文件的计算机上运行简化的命令, 那将出问题。

因为源代码树是主要是由大量小尺寸文件构成的, 开启所在分区的soft updates通常可以提高计算机的性能。

5.3.4 - 构建内核

我们这里假设您需要构建一个标准内核(GENERIC或GENERIC.MP)。一般情况下这正是您需要的, 不要在自己尚未精通怎样构建标准内核时去考虑构建自己的定制内核。

很明显内核对计算机硬件部分有很强的依赖性。内核源代码位于 /usr/src/sys 目录。 一部分OpenBSD内核源代码可以应用在所有平台上, 其余的则只能使用在特定的处理器或构架上。如果您看了 /usr/src/sys/arch/ 目录, 您可能会有一些迷惑——例如, 那里分别有 mac68k, m68k 和 mvme68k 目录。这是因为, 虽然mvme68k和mac68k系统全使用同样的处理器, 但这三种构架却有很大的差异, 它们需要不同的内核 (计算机构架的设计比处理器的设计要复杂得多!)。无论如何它们的部分内核是通用的, 这些部分保存在m68k 的目录下。如果您想为这三种计算机建立一个基于m68k构架简单内核, 使用m68k目录下的内核源代码不会产生任何问题。如果您想构建专用的内核您就需要使用"专用"构架目录, 例如mvme68k目录。

内核构建基于内核配置文件, 它位于/usr/src/sys/arch/<your platform>/conf目录内。内核构建包含使用config(8)程序生成内核文件并把它写入一个内核编译目录这两个过程, 生成的内核文件为/usr/src/sys/arch/<your platform>/compile/<KernelName>。 在这个例子中我们假设您使用i386平台:

# cd /usr/src/sys/arch/i386/conf
# config GENERIC
# cd ../compile/GENERIC
# make clean && make depend && make
    [...lots of output...]
# make install

用您的平台名称替换第一行的"i386" 。用 machine(1) 命令可以告诉您您机器的平台名称, 如果想编译一个通用内核第一行用命令"cd /usr/src/sys/arch/`machine`/conf" 。

这时, 重新启动您的机器以便激活新内核。注意下一个步骤要求在新内核启动后进行, 如果您遵照上面的建议升级到最新的快照版, 那么是否需要重新启动就无关紧要了。因为应用编程接口发生了变化, 而旧内核将无法运行新的程序, 但是新内核通常支持旧的程序。

变更的上述过程:源代码只读

有些时候, 您可能希望确保您的 /usr/src/sys 目录(源代码所在目录)不被改动。这可以通过下面的命令完成:

$ cd /somewhere
$ cp /usr/src/sys/arch/i386/conf/GENERIC .
$ config -s /usr/src/sys -b . GENERIC
$ make clean && make depend && make
   ... lots of output ...  

注意:编译内核并不需要是root身份, 但是安装新内核必须用root身份。

5.3.5 - 构建用户岛

OpenBSD使用了一个特殊的步骤。在其它操作系统上您很熟悉的操作步骤似乎多数在OpenBSD上全无法使用, 如果您问为什么别人还会嘲笑您。

5.4 - 构建一个发行版

什么是发行版及为什么我要制作一个自己的发行版?

一个发行版包含了完整的系统创建组件, 它可以被用来在其它的计算机上创建OpenBSD系统。如果您只在一台计算机中运行OpenBSD, 那您不必制作一张发行版, 如上所述构建过程中您需要完成所有必要的工作。这里举一个例子, 您可以在最快的计算机上构建一个稳定版, 然后用它制作一个自己的发行版, 用自制的发行版来安装您办公室的其它计算机。

制作发行版的过程用到了上面构建用户岛时在 /usr/obj 目录下产生的二进制文件, 所以您必须先完成"用户岛"的构建并且保证/usr/obj目录文件完好无损才可以制作发行版, 一个可能会产生的问题:如果您为了提升性能用一个memory disk做为 /usr/obj 目录, 那您不能在构建用户岛和制作发行版之间启动!制作发行版的过程需要两个工作目录, 我们称它们为DESTDIR 和 RELEASEDIR。所有原先OpenBSD发行版所带组件将会按原有的目录结构拷贝进DESTDIR目录中, 然后它们会被tar打包进DESTDIR and RELEASEDIR.目录, 当制作过程完成时完整的OpenBSD发行版会保存在RELEASEDIR目录中。制作过程中会使用 /mnt这个位置, 所以在制作发行版过程中其它的操作不能占用/mnt。为了举例方便, 我们假设DESTDIR 的位置是/usr/dest, 而RELEASEDIR在/usr/rel目录。

这个发行版包含了一系列原版OpenBSD没有的程序, crunch 和 crunchgen可以把许多单独的二进制文件组合成一个可执行文件, 系统创建(Set up)时可以调出这个可执行文件中所需二进制文件, 这也是怎样把一系列独立的程序压缩进软盘或其它创建介质里 的内存盘内核的方法。必须在制作您的发行版以前先完成这些程序的构建。这些程序仅需要构建和安装 一次, 但因为人们经常忘记这一步骤, 而且这些程序构建过程很快, 所以有些人选择把构建这些程序的命令包含在一个制 作发行版在脚本里, 也就是在每次构建发行版时全重新构建一遍。

您必须拥有root的权限才可以制作一个自己的发行版。

构建一个发行版

定义DESTDIR 和 RELEASEDIR 环境变量:

# export DESTDIR=/usr/dest
# export RELEASEDIR=/usr/rel

我们现在清空DESTDIR 并创建所需目录:

# test -d ${DESTDIR} && mv ${DESTDIR} ${DESTDIR}.old && rm -rf ${DESTDIR}.old &

# mkdir -p ${DESTDIR} ${RELEASEDIR}

RELEASEDIR目录是否清空并不您影响制作发行版, 但是如果发行版内的文件或文件名称发生了变化, 将不会覆盖原来的旧文件, 如此一来您的制作的发行版可能含有没用的文件, 所以您应该在构建发行版以前也将这个目录清空。

我们现在来制作发行版:

# cd /usr/src/etc
# make release

发行版制作完毕后, 您最好再检查一下, 确保tar压缩文件和DESTDIR目录里的文件匹配, 执行这个命令后屏幕输出的内容应该很少。

# cd /usr/src/distrib/sets
# sh checkflist

您现在已经制作并检查了RELEASEDIR目录下发行版的组件文件, 这些文件现在可以被用来在其它的计算机上创建或升级OpenBSD系统了。

制作发行版的权威指南在release(8).

说明:如果您希望通过HTTP方式发布您的发行版, 让其它计算机通过执行脚本的方式创建或升级系统, 您需要在发行版内增加一个"index.txt" 文件, 它要包含您自制发行版的所有系统创建组件的名单。

# /bin/ls -1 >index.txt

5.5 - 构建 X (Xenocara)

X.org v7开始X改变为"模块化构造"系统, 把x.org源代码树分成了300个左右的独立程序包。

考虑到OpenBSD用户的方便性, 一个被称作Xenocara的"变化构建"系统被发展出来。这个系统把X "变回了" 一个大的源代码树, 它的构建过程只需要一个步骤。另一个长处, X的构建过程更像今后新版本的OpenBSD构建过程, 而非老版本。官方的X构建说明在/usr/xenocara/README这个文件和release(8)里。

获得源代码

一般来讲xenocara树的位置在/usr/xenocara , 源代码被以xenocara模式存在CVS中。所以提取步骤是:
$ cd /usr
$ cvs -qdanoncvs@anoncvs.example.org:/cvs checkout -P xenocara

构建 Xenocara

构建OpenBSD支持的标准xenocara树不需要任何额外的工具。
# cd /usr/xenocara
# rm -rf /usr/xobj/*
# make bootstrap
# make obj
# make build
如果您希望自行修改源代码构建自己风格的X, 您可能需要一些packages, 详情请参阅/usr/xenocara/README文件。

制作一个发行版

制作X的发行版和制作OpenBSD的发行版过程类似, 先定义两个目录DESTDIR and RELEASEDIR, 目的和上面制作OpenBSD发行版是一样的。您可以把X的RELEASEDIR和OpenBSD的RELEASEDIR放在同一个目录里, 但是DESTDIR会在这个步骤中被删除和重新建立。如果您操作得很仔细, 不会有什么问题, 不过您用另一个目录做DESTDIR也许会"安全"一些。

这个例子中, 我们使用/usr/dest 作为DESTDIR , /usr/rel 作为RELEASEDIR , 注意, 您进行这步时确保您上面的步骤已经完成了。

# export DESTDIR=/usr/dest
# export RELEASEDIR=/usr/rel
# test -d ${DESTDIR} && mv ${DESTDIR} ${DESTDIR}- && rm -rf ${DESTDIR}- &
# mkdir -p ${DESTDIR} ${RELEASEDIR}
# make release

等这个过程结束了, 您就有了一套自己的X发行版, 它在$RELEASEDIR这个目录里。

5.6 - 我为什么需要一个定制内核?

事实上, 您也许不需要。

所谓的定制内核是指更改OpenBSD标准内核配置文件GENERIC而构建的系统内核。一个定制内核可以基于-release, -stable或-current的源代码, 只要修改任何一个GENERIC内核配置文件。OpenBSD开发团队仅对您编译标准内核提供支持, 但不提供对编译用户定制内核的技术支持。

标准的OpenBSD内核配置(GENERIC)被设计成适合大多数用户。很多用户尝试通过修改标准内核配置来提升系统性能, 因而搞坏了他们的系统。还有一些人相信只有通过定制系统内核才能使系统运行最佳, 对OpenBSD来说这是错的。只有经验和知识最丰富的用户在处理一些最苛求的应用时才应该考虑一个定制的内核或系统。

一些为什么您需要一个定制内核的原因:

一些为什么您不需要一个定制内核的原因:

一个用户常犯的错误是在内核配置文件中删除设备驱动, 这样做也许会提高您机器的启动速度, 但是一旦硬件出现问题这种做法加大了系统恢复的难度。虽然删除设备驱动可以构建一个小一点的系统内核, 但实际上并没有给系统带来任何显而易见的速度提升。删除调试和错误提取的确可以提升一小部分系统性能, 然而一旦系统出现问题您不能找出原因。

再强调一次, 开发者通常不理睬定制内核的系统漏洞报告, 除非这个系统漏洞也会出现在标准内核的OpenBSD系统上。可别说我没提醒您哦。

5.7 - 构建一个定制的内核

我们这里假设您已经读了上一小节, 而且确实想自寻烦恼;另外还假设您的某个愿望无论是通过(Boot time configuration (UKC>)或者 config(8)ing a GENERIC kernel配置标准内核全不能满足。——如果上面两个假设全不成立, 说实话, 您还是应该踏踏实实地使用标准内核编译系统。

默认情况下在是通过位于/usr/src/sys/arch/<arch>/conf/目录下的配置文件控制系统内核生成。所有的平台的目录里全有一个文件, GENERIC, 它是该平台下OpenBSD的标准内核配置文件。目录里也可能有一些特殊目的的内核配置文件, 例如专为小内存计算机设计的内核配置文件, 或者专门为无盘工作站设计的。通过config(8)您可以处理内核配置文件, config(8)在../compile下创建并填充一个汇编目录, 典型的安装过程在/usr/src/sys/arch//compile/下进行, config(8)也生成一个Makefile和其余成功构建内核的所需文件。

您可以在内核配置文件中添加选项从而定制您自己的内核。通过这个文件您可以保留或删除内核支持的设备。这里有很多选项帮助您定制内核。我们在这里仅讨论一些最常用的选项, 您可以查询用户手册中关于options(4)的详细说明, 它罗列出了全部的内核配置选项, 因为用户手册会随时间变化, 请您确保您的用户手册上的OpenBSD版本和您将配置的内核相匹配。您也可以参考自己计算机所属平台内核配置文件的范例。 除非您有很充分的理由, 否则不要添加, 删除或修改原有的内核配置选项! 也不要编辑GENERIC内核配置文件!! GENERIC是OpenBSD团队唯一提供技术支持的内核配置文件, 在/usr/src/sys/arch/<arch>/conf/GENERIC和/usr/src/sys/conf/GENERIC这两个文件全是OpenBSD开发团队分发的(不要编辑它们)。当您使用定制内核的系统出现问题, 您往往会被告知避免此问题的方法是使用标准内核。并非所有的选项全可以与其余的选项彼此兼容, 许多选项是保证系统正常工作所必须的。您不能保证您的定制内核可以成功编译, 也不能保证您定制的内核编译成功就可以正常使用了。

您可以在下列文件中参阅自己所属平台的内核配置文件:

仔细看这些文件您会发现靠近开始的位置有这样的一行, 像:

     include "../../../conf/GENERIC"

这说明这个内核配置文件包含了其它各平台通用的选项。在您编译内核前务必仔细审查 文件sys/conf/GENERIC.

在内核配置文件里内核配置选项的格式如下:

option      name
option      name=value 

例如, 增加一个debug(调试)选项, 您可以像这样加上一行:

option      DEBUG

OpenBSD内核将配置选项编译成预处理指令, 因此如果您添加了DEBUG选项, 编译程序将把-DDEBUG选项的源码编译进系统内核, 选取此项等同于使用#define DEBUG 命令列选项。

有些时候, 您也许想在"src/sys/conf/GENERIC"文件里关闭一些已经定义的选项, 最好的方式是建立一个拷贝, 在拷贝上进行删除选项的修改工作。例如您非常想关闭系统的调试工具debugger(不推荐这样做), 您可以增加一行, 像这样:

rmoption    DDB

默认的内核配置文件src/sys/conf/GENERIC开启了DDB选项, 您可以通过rmoption选项关闭它。

再次强调, 请参阅options(4)以便获取更多的关于个选项的详细信息。另外需要说明的是许多选项有其相关的用户手册——永远记住在您对内核配置文件添加和删除任何选项前详细阅读这些资料中的细节。

构建一个定制内核

这个例子中, 我们修改内核配置文件让内核支持boca(4)ISA多串口卡。因为这种卡的驱动与其它驱动冲突所以标准内核是不支持的。另一个通常需要定制内核的原因是计算机使用了RAIDframe(磁盘阵列), 因为其驱动过大没有被加入到标准内核中。这里有两种制作定制内核的方法::一种是把GENERIC做一个拷贝, 并编辑拷贝的文件;另外一种是建立一个"包装"文件, 它里面"包含了"标准的内核配置文件和一些您自己需要的选项。这个例子中我们的包装文件像这样:

include "arch/i386/conf/GENERIC"
boca0  at       isa? port 0x100 irq 10     # BOCA 8-port serial cards
pccom* at       boca? slave ?  

上面的语句意思是包含了标准的内核配置文件, 下面的两句摘自标准内核配置文件里关于boca(4)卡的选项, 并按照需要调整了IRQ, 标准配置文件里这个选项是关闭的(加#号注释掉的)。这样做的好处是用包装文件避 免对标准内核进行修改, 并且可以增加对一些设备支持(后两行), 但是包裹文件不能删除原有驱动(虽然通 常情况下, 删除原有驱动是个坏主意。)

另一个产生定制内核文件的方法是将标准内核文件拷贝一份, 在这个不同名的拷贝文件上根据自己的需要 进行修改, 这样做的缺点是标准内核得不到及时的更新, 更新全在拷贝文件里, 您不得不重新制作您的配置文件。 无论两种之中哪种方法, 当您用config定制内核内核配置文件后, 参考上面5.34 构建内核的方法构建您的定制内核。全部关于制作定制内核的说明在config(8)用户手册上。

5.8 - 启动时配置

某些时候重新启动系统, 您会发现内核找到了您配置的硬件设备, 但是存在IRQ错误, 而您却需要这些设备正常工作。这种情况下您不需要立刻重新构建内核, 只要使用OpenBSD的启动时内核配置这一功能。它可以在这次启动时修正内核的错误, 但是当您每次重新启动还需要做同样的配置才可以修正错误, 所以这种办法只是暂时的修正内核错误, 而您还是应该用config(8)重新修改您的内核。您的定制内核肯定需要option BOOT_CONFIG这个启动时配置选项, 这个选项已经包含在标准内核配置文件里了。这个文件的绝大部分说明在boot_config(8).的用户手册里。

您在启动时使用-c选项就可以进入用户内核配置或UKC。

boot> boot hd0a:/bsd -c

无论您想启动哪种内核, 在启动时使用-c选项可以让您进入UKC提示符状态, 这里您可以对内核执行命令, 让它改变或删除指定设备的加载或者加载新设备。

这里提供了一些常用的UKC下的命令:

一旦您完成了对内核的配置工作, 您应该使用quit或exit命令让计算机继续启动。 启动后这些更改将永久保存在您的内核映像里(译者注:内核映像储存着内核的代码和数据), 就像5.9 –用config改变您的内核这一小节里描述的那样。

5.9 - 用config改变您的内核

使用config(8-e-u 选项对您有很有帮助, 它可以极大的节省编译定制内核的时间。-e 选项可以让您在启动时进入UKC或在启动后运行的系统上进行内核配置。这些更改会在下次启动后生效。 -u 选项可以在本次启动中测试内核更改的效果, 这里就是指您先用boot -c 进入UKC修改内核配置(并应用 –u), 然后启动您的系统, 在启动过程中查看应用的内核修改是否满足您的要求。

从下面的例子中您可以看到ep* 设备失效了。为了安全起见您应该使用 -o 选项, 这样config可以把更改的内核写入一个指定的文件。例如: config -e -o bsd.new /bsd 将把更改后的内核写入bsd.new文件, 这个例子中使用 -o 选项, 因此内核的更改没有成功, 也就是说没有写回内核的二进制文件。更多错误, 警告信息请参看config(8)的用户手册。

$ sudo config -e /bsd
OpenBSD 4.4 (GENERIC) #1021: Tue Aug 12 17:16:55 MDT 2008
    deraadt@i386.openbsd.org:/usr/src/sys/arch/i386/compile/GENERIC
warning: no output file specified
Enter 'help' for information
ukc> ?
        help                            Command help list
        add         dev                 Add a device
        base        8|10|16             Base on large numbers
        change      devno|dev           Change device
        disable     attr val|devno|dev  Disable device
        enable      attr val|devno|dev  Enable device
        find        devno|dev           Find device
        list                            List configuration
        lines       count               # of lines per page
        show        [attr [val]]        Show attribute
        exit                            Exit, without saving changes
        quit                            Quit, saving current changes
        timezone    [mins [dst]]        Show/change timezone
        nmbclust    [number]            Show/change NMBCLUSTERS
        cachepct    [number]            Show/change BUFCACHEPERCENT
        nkmempg     [number]            Show/change NKMEMPAGES
        shmseg      [number]            Show/change SHMSEG
        shmmaxpgs   [number]            Show/change SHMMAXPGS
ukc> list
  0 audio* at sb0|sb*|gus0|pas0|sp0|ess*|wss0|wss*|ym*|eap*|eso*|sv*|neo*|cmpci*
|clcs*|clct*|auich*|autri*|auvia*|fms*|uaudio*|maestro*|esa*|yds*|emu* flags 0x0
  1 midi* at sb0|sb*|opl*|opl*|opl*|opl*|ym*|mpu*|autri* flags 0x0
  2 nsphy* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|vr*
|ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep*|e
p*|ep* phy -1 flags 0x0
  3 nsphyter* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|
vr*|ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep
*|ep*|ep* phy -1 flags 0x0
  4 qsphy* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|vr*
|ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep*|e
p*|ep* phy -1 flags 0x0
  5 inphy* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|vr*
|ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep*|e
p*|ep* phy -1 flags 0x0
  6 iophy* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|vr*
|ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep*|e
p*|ep* phy -1 flags 0x0
  7 eephy* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|vr*
|ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep*|e
p*|ep* phy -1 flags 0x0
  8 exphy* at aue*|xe*|ef*|gx*|stge*|bge*|nge*|sk*|ste*|sis*|sf*|wb*|tx*|tl*|vr*
|ne0|ne1|ne2|ne*|ne*|ne*|dc*|dc*|rl*|fxp*|fxp*|xl*|xl*|ep0|ep0|ep0|ep*|ep*|ep*|e
p*|ep* phy -1 flags 0x0
[...snip...]
ukc> disable ep
 93 ep0 disabled
 94 ep* disabled
 95 ep* disabled
261 ep0 disabled
262 ep0 disabled
263 ep* disabled
264 ep* disabled
323 ep* disabled
ukc> quit
not forced  

上面的例子中, 所有的ep*设备被内核禁用, 并且内核也不会检测ep*设备。某些情况下您在启动时通过boot -c进入UKC, 您需要永久地将这些改动的内核写到一个输出文件, 为了达到这个目的, 您应该使用 -u 选项。下面这个例子, 计算机启动后进入UKC, 并且禁用wi(4)设备。因为仅仅使用boot –c并不能永久地改变内核, 所以这些改动的内核必须写入一个文件, 这里我们将通过boot –c后修改的内核写入一个内核的二进制文件bsd.new。

$ sudo config -e -u -o bsd.new /bsd
OpenBSD 4.4 (GENERIC) #1021: Tue Aug 12 17:16:55 MDT 2008
    deraadt@i386.openbsd.org:/usr/src/sys/arch/i386/compile/GENERIC
Processing history...
105 wi* disabled
106 wi* disabled
Enter 'help' for information
ukc> quit

5.10 - 启动时获得更为详尽的输出信息

在启动时得到更加详尽的系统输出信息对出问题后的调试工作是很有意义的。假设您使用软盘无法进入系统而需要得到更多的系统信息, 很简单, 在启动时进入"boot>"提示符后, 使用boot –c进入UKC>, 然后:

UKC> verbose
autoconf verbose enabled
UKC> quit
现在您在启动时会有极为详细的系统输出信息。

5.11 - 常见的错误, 编译和构建时的一些问题和技巧

大多数情况下, 构建过程错误是因为操作时没有在规定的目录内进行操作。偶尔从最新的快照版构建当前版也会出错, 但在构建发行版或稳定版时用户操作失误才是导致错误的最重要原因。

常见的错误如下:

这里还有一些您可能碰到的情况:

5.11.1 - 构建过程停止并显示 "Signal 11" 错误

在计算机上从源码构建OpenBSD或应用程序与其它任务相比艰巨的多, 计算机硬件的开销要高很多, 此时可能CPU, 内存, 硬盘全处在长时间满负荷工作的状态。因此, 如果您的硬件状态异常, 多数情 况可能出现在构建过程中。Signal 11是典型的硬件错误导致的, 通常是内存引起的, 但也有可能是 CPU, 主板或者系统散热导致的。您的系统需要在非常稳定的状态, 否则无法进行程序的编译工作。有 时您可能发现修理或更换部件后会导致错误, 这些错误可以在今后采用其它方法得到确认。如果您有一 个硬件您很想在OpenBSD使用, 但是它导致系统错误, 您可以尝试一下快照版或发行版。更多的关于 Sig11的信息参看Sig11 FAQ

5.11.2 - "make build"时因 "cannot open output file snake: is a directory"导致失败

这个信息包含了两个错误:

当您获取构建您的源代码树时, 应该按照参照相关的说明进行。

5.11.3 - 我禁止了IPv6后计算机不工作了!

是吧, 请不要修改基本系统中您不清楚其真正含义的选项, 一个小地方的修改可能会给整个系统带来巨大的灾难, 请在重新读一遍这里

5.11.4 - 糟糕!我忘记先建立 /usr/obj 目录了!

您应该在"make build"前先进行"make obj", 现在构建过程会停止, 并且大量的目标文件会散落在/usr/src目录内, 这太糟糕了。 如果您想避免重新获取您的src tree, 您可以尝试下面的命令清除所有的obj文件:

# cd /usr/src
# find . -type l -name obj | xargs rm
# make cleandir
# rm -rf /usr/obj/*
# make obj

5.11.5 - 把/usr/obj放在单独的分区

如果您经常构建系统, 您可能会发现把/usr/obj 放到一个自己独立的文件系统内会比较快, 这种方法的优点是简单, 而且它比"rm -rf /usr/obj/*"速度更快:

# umount /usr/obj
# newfs YourObjPartition
# mount /usr/obj

(译者注:newfs命令用来构造一个新的UFS文件系统)

然后运行 "rm -rf /usr/obj/*".

5.11.6 - 我怎样才能不构建源代码树上的某个部件?

有些时候您可能希望不构建源代码树上的某些部件, 通常是因为您已经安装了第三方软件包中某些软件作为这个 部件的替代品, 或者您不管什么原因想得到一个更"小"的发行版。这可以通过在 /etc/mk.conf 里加入SKIPDIR 选项来实现。

说明:这样可能导致系统的崩溃。而且OpenBSD开发团队不对这种做法提供技术支持。

5.11.7 - 我从哪里可以学到构建过程的更多知识?

这里有一些资源:

5.11.8 - 我没有在FTP上找到快照版, 它们在哪里?

快照版如果长时间放在那里可能被删除(也许是不再适用了), 或者是临近新发行版的发布期。

5.11.9 - 我怎样安装新版本的编译器(gcc)?

您只需要安装最新的快照版

OpenBSD现在在代码树中提供两种编译器, gcc v3.3.5应用于大多数平台, 但在有些平台上也只提供gcc v2.95.3, 那些平台还没有更换也许永远不会更换了, 原因是gcc3缺乏支持及它的性能不佳。

这两个编译器分属源代码树中的不同部分:

因为升级一个编译器有点像有鸡还是先有蛋的困惑, 更换成代码树中的编译器需要有一点额外的专注。您不得不构建这个编译器两次——第一次从新的源代码上编译出新的编译器软件, 但是它是被用旧编译器编译出来的, 第二部把它完全创建成新的编译器, 您应该按照以下几步来操作: 如果您的平台使用的是gcc 2.95.3:

# rm -r /usr/obj/gnu/egcs/gcc/*
# cd /usr/src/gnu/egcs/gcc
- 或者 -

如果您的平台使用的是uses gcc 3.3.5:

# rm -r /usr/obj/gnu/usr.bin/gcc/*
# cd /usr/src/gnu/usr.bin/gcc
通用的步骤(适用于v3.3.5 或 v2.95.3)
# make -f Makefile.bsd-wrapper clean
# make -f Makefile.bsd-wrapper obj
# make -f Makefile.bsd-wrapper depend
# make -f Makefile.bsd-wrapper
# make -f Makefile.bsd-wrapper install
# make -f Makefile.bsd-wrapper clean
# make -f Makefile.bsd-wrapper depend
# make -f Makefile.bsd-wrapper
# make -f Makefile.bsd-wrapper install

然后运行make build

5.11.10 - 什么是更新/etc, /var和/dev的最好方法?

作为一条原则, OpenBSD源代码树并不会自动更改 /etc 目录下的文件。这意味着永远由系统管理员决定是否需要 更改这些文件。即使是升级也不例外。更新这些目录里的文件第一个步骤是测定系统源代码的变化, 第二个步骤是手 动再申请获得这些新的源代码。

例如, 要看源代码树中文件最近的变化, 用:

# cd /usr/src/etc
# ls -lt |more

看任何OpenBSD发行版之间 /etc目录下文件的变化, 您可以用 CVS命令, 例如您想知道4.5和4.6之间的变 化, 这样做:

# cd /usr/src/etc
# cvs diff -u -rOPENBSD_4_5 -rOPENBSD_4_6
看4.6和当前版("HEAD", 到头了)之间的文件变化, 用:
# cd /usr/src/etc
# cvs diff -u -rOPENBSD_4_6 -rHEAD
/dev/MAKEDEV脚本并不会做为make build过程的一个部分而自动被更新, 然而它是做为升级二进制文件的一部分安装的。作为一般规则, 把它拷贝到待升级的计算机上并运行它是一个好主意:
# cd /dev
# cp /usr/src/etc/etc.`machine`/MAKEDEV ./
# ./MAKEDEV all

一旦提取了源代码的变化, 再申请并将它们拖到您的本地代码树, 保存您以前的配置文件。 两个发行版之间的 /etc目录的值得关注的变化是:

总而言之, 这些变化请参阅 upgrade46.html(升级到4.6发行版)或者 current.html(升级到当前版)。

5.11.11 - 有没有简单的方法改变所有的文件层次?

随着时间的流逝, 代码树中一些文件和目录被加进去, 而另一些则被从文件层次hierarchy中删除。同样文件从属信息作为文件系统的一部分也在变化。一个简单的方法可以用mtree(8)确保您的文件层次已经更新。

首先获取最新的源代码, 然后进行下面步骤:

# cd /usr/src/etc/mtree
# install -c -o root -g wheel -m 600 special /etc/mtree
# install -c -o root -g wheel -m 444 4.4BSD.dist /etc/mtree
# mtree -qdef /etc/mtree/4.4BSD.dist -p / -u

您的文件层次现在已经更新了。

5.11.12 - 我能交叉编译吗?为什么不行?

交叉编译工具存在于系统中, 被开发者用来将编译的程序提交到其它平台。然而, 这些工具并不是万能的灵丹妙药。

当开发人员将程序提交到一个新的平台, 第一个最大的挑战就是native-build, 从源码构建系统无论对OS或机器都是非常繁重的任务, 而且可以非常好的测试系统的稳定性和兼容性。基于此点, OpenBSD的所有构建工作全在该平台本身进行, 也就是所说的本地构建, 未经本地构建, 就很难确保在不同的平台上可以稳定地运行, 而非仅为了能启动系统。

[索引] [第四章 - 安装指南] [第六章 - 网络]


[back]www@openbsd.org $OpenBSD: faq5.html, v 1.168 2008/11/30 11:01:26 tobias Exp $