Loading...

当前位置:资讯中心主页 >Linux >文章内容

  • Linux的补丁知识
  • 来源:作者: 发布时间:2007-11-09 13:14:02
    • 域名注册

    • 域名惊喜价格 cn域名1元注册
    • com域名39.9

      虚拟主机

    • 主机按月支付,低至19元/月
    • 超大流量,可开子站点

      VPS主机

    • 特惠VPS168元/月,4-8M独享带宽保证
    • 独立操作系统,无限开站点
     

    补丁的工作方式

    “补丁(patch)”是描述某个文件两个不同版本之间差别的文件。程式 diff 会逐行比较原始文件和新文件,并以特定格式向标准输出打印这些差别。程式 patch 能读取 diff 的输出,并将那些改动应用于原始文件的另一个拷贝。(注意,“补丁”一词既涉及 diff 命令的输出,也涉及应用那个补丁的命令。)例如:

    
    $ cat old/file.txt
    This
    is
    a
    simple
    file.
    $ cat new/file.txt
    This
    is
    a
    slightly more complex
    file.
    $ diff -uNr old new
    diff -uNr old/file.txt new/file.txt
    --- old/file.txt        Tue May 28 23:00:21 2002
    +++ new/file.txt        Tue May 28 23:01:01 2002
    @@ -1,5 +1,5 @@
     This
     is
     a
    -simple
    +slightly more complex
     file.
    


    可见,两个文件只有一行的差别。在命令行中列出的来自第一个文件的那一行显示时在最前有一个“-”,接下来是来自第二个文件的那一行,在命令行中显示时最前而有一个“+”。直观上,是从旧文件中“减去(subtracting)”那一行,并“添加”来自新文件的那一行。记住,旧文件总是先出现,然后是较新的文件。

    目前,让我们来应用刚刚创建的补丁。补丁会将较旧版本的文件更新为较新版本的文件,所以我们应该对文件的较旧的版本应用补丁。

    
    $ diff -uNr old new > patchfile
    $ cd old
    $ patch -p1 < ../patchfile
    patching file file.txt
    $ cat file.txt
    This
    is
    a
    slightly more complex
    file.
    


    使用 patch 命令应用了 diff 命令的输出后,“旧”文件目前和“新”文件相同。

    应用补丁

    接下来我们将学习怎么应用补丁。需要应用某个补丁的一个常见的原因是为了获得一个特定的内核版本,他不能从 ftp.kernel.org 作为一个大的 tarball 下载得到 ?? 或是为了获得一个增量的补丁,这样当大部分内核文件仍然相同时就不必去下载整个新内核。

    内核补丁的命名和创建标准不是特别简单。假定出于某种原因你需要得到内核 2.6.9-rc4,而当前已拥有版本 2.6.7 的完整的内核原始码。为了从 2.6.7 升级到 2.6.9-rc4 需要下载下列补丁:

    2.6.72.6.8

    2.6.82.6.9-rc4

    每一个 prepatch(两个主版本之间的补丁,称作 patch-2.6.x-rcN,通常能在 ftp 站点上名为 testing 的目录中找到)都是针对前一个主版本的变化而创建的。常见的错误是下载了内核版本 2.6.9,然后却尝试应用 2.6.9-rc4 prepatch。如果想要得到内核版本 2.6.9-rc4,应该下载内核 2.6.8,然后应用 2.6.9-rc4 prepatch。这是因为 2.6.9-rc42.6.9 的前身,不能颠倒。注意:命名的惯例和内核 prepatches 的位置会经常发生变化。可能不得不去阅读 linux-内核邮件列表来得知最新补丁的保存位置及他们的名称。

    官方内核补丁的实现都支持你只需进行如下操作:

    
    cd <your linux source tree>
    patch -p1 < ../patchfile
    


    patch 命令的 -p1 选项表示的是“除去直到第一个正斜杠的部分路径名,然后尝试对除去了路径名的文件应用补丁”。

    如果所有这些看起来太过复杂和令人厌烦,那么可能应该去尝试使用 Cogito。本部分的最后有对 Cogito 的简短介绍。

    创建一个补丁

    要记住的第一件事情是,始终要在某个地方保存内核原始码的一个未经改动的、原始的版本。不要在他里面进行编译,不要编辑其中的所有文件,不要对他做所有事情 ?? 只是拷贝他,来得到原始码树的工作拷贝。原始内核原始码应该是在一个名为 linux.vanillalinux.orig 的目录中,并且工作目录应该和原始代码位于同一目录之中。例如,如果原始原始码位于 /usr/src/linux.vanilla 目录下,那么工作所用的原始码也应该位于 /usr/src/ 目录中。

    在对工作拷贝进行了修改后,将使用 diff 创建一个补丁。假定你的工作原始码树名为 linux.new,那么应该运行这个命令:

    
    $ diff -upNr linux.vanilla linux.new > patchfile
    


    原始内核原始码和新的内核原始码之间的所有差别目前就已在 patchfile 之中。 注意:不要使用不一致的目录创建补丁,例如(不要 这样做):

    
    $ diff -upNr linux.vanilla working/usb/thing1/linux > patchfile
    


    这将不会创建一个标准格式的补丁,而且没有人会去费力尝试你的补丁,因为他难以应用。

    既然已创建了一个补丁,那么阅读他吧!几乎能肯定,补丁中包含的有些文件你不希望将他们作为补丁的一部分,比如旧的编辑器备份文件、对象文件,或在研发过程中创建的随机垃圾文件。要除去这些文件,能让 diff 忽略特定的文件,能删除这些文件,或能手工编辑 diff。在手工编辑补丁之前一定要理解补丁的格式,否则非常可能创建出一个不能应用的补丁。make mrproper 是个实用的命令,能用来除去在内核构建期间创建的额外文件。

    不过要记住,这会删除 .config 文件并强制你对内核进行完全的编译。

    另外,要确保补丁位于正确的目录中。新的行是不是前面有“+”的那些行?并且,要确保那些是你所希望执行的修改。非常容易使用完全错误的原始码树完成 diff。

    当认为自己已获得了补丁的最终版本之后,将他应用到原始的原始码树(不要破坏原始原始码树的惟一拷贝)。如果他不能应用而又没有报错,那么重新去完成那个补丁。

    同样,如果这这看起来太过复杂,可能应该去尝试使用 Cogito。

    在提交补丁之前需要考虑的事情

    创建了一个补丁之后,你会希望和其他人共享他。最佳的情形是,你自己测试那个补丁,也让其他人去测试他,并让其他人去阅读那个补丁本身。总之,你会希望自己的补丁没有 bug、合理编写、易于应用。

    始终要自己编译和测试自己的补丁。你会看到有人向 linux-内核提交“完全没有测试的(totally untested)”补丁,但不会对其倾心 ?? 完成没有经过测试的补丁可能是个没用的补丁。内核维护人员曾不止一次发布根本不能编译的内核。人无完人 ?? 在所有情况下都要测试你的补丁。

    确保代码和相关代码相符合,并遵循内核代码风格惯例。虽然查看其他源文件通常是了解当前惯例的最佳途径,不过还应去查看文件 Documentation/CodingStyle 中的规范说明。

    如果你的补丁难以应用,那么他几乎肯定不会被认可。除了要使用适当层次的目录创建补丁以外,创建他时所针对的内核需要和其他人将补丁应用到的内核相同(或几乎相同)。所以,如果想让 XYZ 来应用你的补丁,那么要确定 XYZ 正在使用的内核的版本,然后尝试尽可能使用和之相近的内核。通常是内核维护人员所发布的最新 vanilla 内核。

    例如,如果有一个针对 2.6.9-rc2 补丁,而 2.6.9-rc4 是发布的最新版本,那么应该针对 2.6.9-rc4 重新创建补丁。最简单的方法是,将补丁从 2.6.9-rc2 应用到 2.6.9-rc4,并修订两个版本之间的所有变化,然后针对 2.6.9-rc4 重新进行 diff。

    将补丁提交给谁

    这个问题的答案是“看情况而定”。订阅 Linux 内核邮件列表及和你的研究领域更相关的列表;你将了解到谁是适合的人选。

    尝试确定最明确参和维护你正在修改的那部分内核的人。如果你对 bar 子系统中的 foo 驱动程式进行了修改,而 foo 驱动程式有一个维护人员,那么你可能应该将补丁提交给 foo 的维护人员,只有当 foo 的维护人员不理你时再提交给 bar 子系统的维护人员。

    顶层内核原始码目录中的 MAINTAINERS 经常会过期,不过,无论怎么,通常还是会有所帮助。不管你将补丁发送给 MAINTAINERS 文件的哪个人,都不会有人责怪你。当无法确定怎么做时,这总是可采取的最安全方法。

    另外,要将你的补丁发送到 linux-kernel@vger.kernel.org 的 Linux 内核邮件列表(除非有理由不这样做)。除了维护人员以外的其他研发者可能需要知道你的修改。他们还可能会提供帮助,给出注解和建议。

    发布补丁

    大部分补丁都足够小,能包含在邮件中。虽然有些维护人员拒绝接收附件中的补丁,有些维护人员拒绝接收 MIME-编码 的补丁,不过所有维护人员都会接收包含在纯文本邮件主体中的补丁。确保邮件客户机不会破坏你的补丁 ?? 如果不能确定,那么将补丁用邮件发送给自己并应用他,这样来确保其他人也能应用他。大部分 Linux 邮件列表希望补丁拥有以字符串 [PATCH] 为前缀的有意义的英语主题,便于查找和阅读补丁。

    如果你的补丁太大,不能通过电子邮件发送(大约 40 KB 或更大),那么将他放在其他人能下载的 Web 页面上或 ftp 站点上,然后把 URL 放在电子邮件中。

    原始码树中的 Documentation/SubmittingPatches 文件中能找到关于怎么提交补丁的更多指南。

    策略考虑因素

    如果所有事实都表明你的补丁有适当的格式、是正确的而且修订了一个 bug,那么提交他将简单得多。更重要的是,你的补丁需要有吸引力、适时、有趣,而且要考虑维护人员的自尊心。在大部分情况下,简单的 bug 修复会被即时认可。不过,有时你会遇见更大的问题。重要的是要记住不能去从事 Linux 维护人员系统周边的工作;你的工作必须深入其中。

    学习关于 linux-内核的一些思路,人们试图以这些思路来说服他人将自己的补丁融入内核。如果你的补丁没有被认可,那么去聆听其他人是怎么评价他,并尝试解决他的问题。最常被拒绝的补丁是特性(feature)补丁 ?? 添加的新特性被其他维护人员认为没有吸引力。不要浪费时间去尝试让补丁被认可,只需要独立维护他。如果足够多的人发现那个补丁有用,那么在下载并使用你的补丁的人中,你会被认为是一位有帮助的内核修改者而获得名望。

    有时,维护人员只是因为他或她的自尊心而不认可某个补丁。在这种情况下,惟一的选择是维护一个独立于主内核的更好版本代码。通常,在一段时间之后,被证实是更好的外部维护的代码将取代内核内部代码 ?? 这是成为维护人员的一个途径。

    可取代 diff 和 patch 的另一种选择:Cogito

    当前非常多内核研发者使用 Cogito 来取代 diff 和 patch。他简化了大量内核研发任务,比如更新到最新的版本、创建补丁和应用补丁。

    要添加一个文件,运行:

    
    $ cg-add file
    


    要创建一个补丁,运行:

    
    $ cg-diff > patchfile
    


    要应用一个补丁,运行:

    
    $ cg-patch < patchfile
    



  • 以上内容由 华夏名网 搜集整理,如转载请注明原文出处,并保留这一部分内容。

      “华夏名网” http://www.sudu.cn 和 http://www.bigwww.com 是成都飞数科技有限公司的网络服务品牌,专业经营虚拟主机,域名注册,VPS,服务器租用业务。公司创建于2002年,经过6年的高速发展,“华夏名网”已经成为我国一家知名的互联网服务提供商,被国外权威机构webhosting.info评价为25大IDC服务商之一。

    华夏名网网址导航: 虚拟主机 双线主机 主机 域名注册 cn域名 域名 服务器租用 酷睿服务器 vps vps主机

  • (阅读次数:209)
  • 上一篇: 编写简单的Linux2.6内核模块(1)    下一篇: Linux档案属性与目录配置(1)
  • [收藏] [推荐] [评论] [打印本页] [返回上一页][关闭窗口]
  • 昵称: (为空则显示guest)
  • 评论分数: ★ ★ ★★★ ★★★★ ★★★★★
  • 评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。