Linux下Patch的應用和製作方法介紹 因為在u-boot移植過程中,有幾處通用檔案要修改,如果每次都要手動修改就太麻煩了。製作補丁可以解決這個問題。 學習資料的收集比較簡單,方法一類似於這種初級問題網上資料非常豐富,google或者baidu搜尋一下,然後選擇有價值的資料,方法二是閱讀man線上文檔。完成收集工作,當然最終要在自己的Linux上作實驗,比較總結,消化吸收為自己的東西。要除去這麼一種錯誤思想:一定要學全。要知道,一次學全是不可能的,只能先學習最為常用的,在以後不斷實踐的過程中逐步的豐富,最終達到比較高的水平。把握的原則是:日有所學,學以致用,用以促學。 首先介紹一下diff和patch。在這裡不會把man線上文檔上所有的選項都介紹一下,那樣也沒有必要。在99%的時間裡,我們只會用到幾個選項。所以必須學會這幾個選項。 1、diff NAME diff - find differences between two files SYNOPSIS diff [options] from-file to-file 簡單的說,diff的功能就是用來比較兩個檔案的不同,然後記錄下來,也就是所謂的diff補丁。文法格式:diff 【選項】 源檔案(夾) 目的檔案(夾),就是要給源檔案(夾)打個補丁,使之變成目的檔案(夾),術語也就是“升級”。下面介紹三個最為常用選項: -r 是一個遞迴選項,設定了這個選項,diff會將兩個不同版本原始碼目錄中的所有對應檔案全部都進行一次比較,包括子目錄檔案。 -N 選項確保補丁檔案將正確地處理已經建立或刪除檔案的情況。 -u 選項以統一格式建立補丁檔案,這種格式比預設格式更緊湊些。 2、patch NAME patch - apply a diff file to an original SYNOPSIS patch [options] [originalfile [patchfile]] but usually just patch -pnum 簡單的說,patch就是利用diff製作的補丁來實現源檔案(夾)和目的檔案(夾)的轉換。這樣說就意味著你可以有源檔案(夾)――>目的檔案(夾),也可以目的檔案(夾)――>源檔案(夾)。下面介紹幾個最常用選項: -p0 選項要從目前的目錄尋找目的檔案(夾) -p1 選項要忽略掉第一層目錄,從目前的目錄開始尋找。 在這裡以執行個體說明: --- old/modules/pcitable Mon Sep 27 11:03:56 1999 +++ new/modules/pcitable Tue Dec 19 20:05:41 2000 如果使用參數-p0,那就表示從目前的目錄找一個叫做old的檔案夾,在它下面尋找modules下的pcitable檔案來執行patch操作。 如果使用參數-p1,那就表示忽略第一層目錄(即不管old),從目前的目錄尋找modules的檔案夾,在它下面找pcitable。這樣的前提是目前的目錄必須為modules所在的目錄。而diff補丁檔案則可以在任意位置,只要指明了diff補丁檔案的路徑就可以了。當然,可以用相對路徑,也可以用絕對路徑。不過我一般習慣用相對路徑。 -E 選項說明如果發現了空檔案,那麼就刪除它 -R 選項說明在補丁檔案中的“新”檔案和“舊”檔案現在要調換過來了(實際上就是給新版本打補丁,讓它變成老版本) 下面結合具體執行個體來分析和解決,分為兩種類型:為單個檔案打補丁和為檔案夾內的多個檔案打補丁。 環境:在RedHat 9.0下面以armlinux使用者登陸。 分類樹如下: |-- bootloader |-- debug |-- images |-- kernel |-- program |-- rootfiles |-- software |-- source |-- sysapps |-- tmp `-- tools 下面在program檔案夾下面建立patch檔案夾作為實驗用,然後進入patch檔案夾。 一、為單個檔案進行補丁操作 1、建立測試檔案test0、test1 [armlinux@lqm patch]$ cat >>test0< > 111111 > 111111 > 111111 > EOF [armlinux@lqm patch]$ more test0 111111 111111 111111 [armlinux@lqm patch]$ cat >>test1< > 222222 > 111111 > 222222 > 111111 > EOF [armlinux@lqm patch]$ more test1 222222 111111 222222 111111 2、使用diff建立補丁test1.patch [armlinux@lqm patch]$ diff -uN test0 test1 > test1.patch 【註:因為單個檔案,所以不需要-r選項。選項順序沒有關係,即可以是-uN,也可以是-Nu。】 [armlinux@lqm patch]$ ls test0 test1 test1.patch [armlinux@lqm patch]$ more test1.patch patch檔案的結構 補丁頭 補丁頭是分別由---/+++開頭的兩行,用來表示要打補丁的檔案。---開頭表示舊檔案,+++開頭表示新檔案。 一個補丁檔案中的多個補丁 一個補丁檔案中可能包含以---/+++開頭的很多節,每一節用來打一個補丁。所以在一個補丁檔案中可以包含好多個補丁。 塊 塊是補丁中要修改的地方。它通常由一部分不用修改的東西開始和結束。他們只是用來表示要修改的位置。他們通常以@@開始,結束於另一個塊的開始或者一個新的補丁頭。 塊的縮排 塊會縮排一列,而這一列是用來表示這一行是要增加還是要刪除的。 塊的第一列 +號表示這一行是要加上的。 -號表示這一行是要刪除的。 沒有加號也沒有減號表示這裡只是引用的而不需要修改。 ************************************************************ ***diff命令會在補丁檔案中記錄這兩個檔案的首次建立時間,如下*** --- test0 2006-08-18 09:12:01.000000000 +0800 +++ test1 2006-08-18 09:13:09.000000000 +0800 @@ -1,3 +1,4 @@ +222222 111111 -111111 +222222 111111 [armlinux@lqm patch]$ patch -p0 < test1.patch patching file test0 [armlinux@lqm patch]$ ls test0 test1 test1.patch [armlinux@lqm patch]$ cat test0 222222 111111 222222 111111 3、可以去除補丁,恢複舊版本 [armlinux@lqm patch]$ patch -RE -p0 < test1.patch patching file test0 [armlinux@lqm patch]$ ls test0 test1 test1.patch [armlinux@lqm patch]$ cat test0 111111 111111 111111