歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> 更多Linux

Linux的補丁知識

補丁的工作方式

“補丁(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.7 到 2.6.8

從 2.6.8 到 2.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-rc4 是 2.6.9 的前身,不能顛倒。注意:命名的慣例和內核 prepatches 的位置會經常發生變化。可能不得不去閱讀 Linux-內核郵件列表來得知最新補丁的保存位置及它們的名稱。

官方內核補丁的實現都支持您只需進行如下操作:

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

patch 命令的 -p1 選項表示的是“除去直到第一個正斜槓的部分路徑名,然後嘗試對除去了路徑名的文件應用補丁”。

如果所有這些看起來太過復雜和令人厭煩,那麼可能應該去嘗試使用 Cogito。本部分的最後有對 Cogito 的簡短介紹。

創建一個補丁

要記住的第一件事情是,始終要在某個地方保存內核源代碼的一個未經改動的、原始的版本。不要在它裡面進行編譯,不要編輯其中的任何文件,不要對它做任何事情 —— 只是拷貝它,來得到源代碼樹的工作拷貝。原始內核源代碼應該是在一個名為 linux.vanilla 或 linux.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 文件的哪個人,都不會有人責怪您。當無法確定如何做時,這總是可采取的最安全方法。

另外,要將您的補丁發送到 [email protected] 的 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




Copyright © Linux教程網 All Rights Reserved