|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
, v7 M) }1 d1 ^+ W; r/ ~2 ^/ h' f" g如何制作LINUX的patch文件及如何打patch- B& ?7 @/ x0 u: m
1 c& K, D* u! h' y- l% e
对某个版本的Linux内核做了修改以后,如果希望发布出去给别人用,那么就需要制作针对此版本的patch文件。
_" z! Y, @5 Z6 T( U" \patch文件也叫补丁,就是一个文本文档,这个文档包含了在两个不同版本的源代码树之间的变化。. t* R0 \2 O& s) b
补丁是通过diff应用程序来创建的。
0 v7 Q7 S( S# B# m8 P4 R为了正确地打上一个补丁,你需要知道这个补丁是从哪个基础版本产生出来的以及这个补丁将要把
3 F/ O7 ^( I; u3 u$ M: g5 C目前的源代码树变化到什么新的版本。这些信息或者会出现在补丁文件的原数据中,或者可能从文件名中推断出来。
( U& b( @, t% j$ |# ~% G! b
' z. l$ M. ~) N" M" m1,如何制作补丁patch文件
1 s/ W; I4 X* M9 M8 |
( q& B) i- t4 [; N3 m 比如基于kernel内核 做了修改,修改了LCD代码,修改前的内容放在文件夹kernel下,修改后的内容放在文件夹kernel_new下,那么制作patch文件的命令为 ^' M* ^6 i# N: j3 g
zhenwx-desktop:~/sourcecode/$diff -Naur kernel/ kernel_new/ > zwx-lcd.patch
0 U+ {" c( r, X3 l' }
7 ?, M- Y q7 w& K 当前目录为 /home/zhenwx/sourcecode/,该目录有原来修改前的内核kernel目录和修改后的目录kernel_new1 V) A- T1 j K5 L. X0 Z# b
执行命令为 diff -Naur kernel/ kernel_new/ > zwx-lcd.patch
: w: }# x& X' ]7 s+ h6 v diff命令就会对比kernel和kernel_new目录的文件,产生patch文件zwx-lcd.patch8 W! k# K' B1 w& T; V# U5 z
这时就 可以把zwx-lcd.patch发布到网上。) n" g* a M, k) |
这个patch文件是描述文件的路径信息和将第几行内容删除,在第几行添加内容,删除用减号,添加用加号
3 l0 {/ a- P/ p * |6 `; h% e7 g# D; D
2,怎样打补丁patch和卸载补丁patch
, p- V. o J- D* }2 Y$ _0 E 可以使用patch程序来打一个补丁。patch程序读取一个diff(或者patch)文件,然后把文件中" a& g+ h6 j0 r, A$ n* b
描述的变化内容应用到代码树上。 X. d4 G/ a, M" V" z% W# h
Linux内核中的补丁是相对于保存内核源代码目录的父目录而生成的。$ ]' @; d1 d# C9 C
这就意味着:patch文件中的文件路径包含了它所基于的内核源文件目录的名字(或者像是"a/"和"b/", t9 S( b) R) {4 n# `
之类的其它名字)。
2 P" q1 @. g0 k1 A 由于这很可能和你本地机器上的内核源代码目录的名字不匹配。你应该切换到你的内核源代码目录,并且在打补丁的时候去掉patch J+ Q9 k9 Y# i5 ~5 t2 m! }
中文件名字路径的第一个分量(patch命令的-p1参数可以完成这个任务)。& X3 n2 ^7 P. H8 w
为了卸载掉一个以前已经打上的补丁,使用-R参数来打补丁。. A( U0 p2 Z5 |! R# B( m' ^% Q1 l
于是,如果你使用如下的命令来打补丁:
/ n" o- n: B* S( a8 q/ } patch -p1" A+ e5 n. j* x# ]/ g. w: l
5 p9 o$ X1 m4 m A# `1 X( ~! c4 h 那么你可以像下面这样来卸载掉这个补丁:
7 z9 i! D0 L* _# ^( N; b patch -R -p1 & O* Z4 Z2 U5 R7 Q% `
l% R# A+ [- q. V 例如其他人下载到上面提供的patch文件后,只需在标准的kernel内核目录里执行
8 }9 [& p5 j& C3 E9 f" r0 g t; P zhenwx-desktop:~/sourcecode/kernel/$! W) E" d! U/ r2 W/ f' Z+ K
* Y: _# U$ _' O. }
patch -p1<../zwx-lcd.patch) R$ f, r. j% n/ ]" s% q
3 }2 `* s: V2 h$ G/ l: p
! {0 ~5 g! a) w 这里假设zwx-lcd.patch和kernel文件夹是在同一目录下,且上述命令 在kernel文件夹内执行
4 v. X* L$ g2 I5 h) w$ k 如果在/sourcecode目录下面执行命令9 Z+ ]2 O+ F' y! X
zhenwx-desktop:~/sourcecode/$
T0 \( o4 m$ Y. n7 z
! u% p; a% Y+ |, o" c# c3 ?( s% @ patch -p0<../zwx-lcd.patch% K# t; \7 L* @# ?5 y/ t
9 H: P' [. ?4 k
, m( }( ^0 K2 p" b$ f: g linux下patch命令使用详解) N5 T( p3 z# M
7 Z# h! g" L- U8 [$ _
linux打补丁命令
0 w4 U( n3 U" A# H& ~" M / K$ r5 c, K4 r+ f! d
功能说明:修补文件。
0 f; y: M% j. @
( B" ^$ ?2 V G9 m3 t5 P 语 法:patch [-bceEflnNRstTuvZ][-B <备份字首字符串>][-d <工作目录>][-D <标示符号>][-F <监别列数>][-g <控制数值>][-i <修补文件>][-o <输出文件>][-p <剥离层级>][-r <拒绝文件>][-V <备份方式>][-Y <备份字首字符串>][-z <备份字尾字符串>][--backup-if -mismatch][--binary][--help][--nobackup-if-mismatch][--verbose][原始文件 <修补文件>] 或 path [-p <剥离层级>] < [修补文件]% w1 J' C+ y! z4 V6 G) y9 @
_* |, B* I: T, y1 _# ?4 n6 @ w/ F
补充说明:patch指令让用户利用设置修补文件的方式,修改,更新原始文件。倘若一次仅修改一个文件,可直接在指令列中下达指令依序执行。如果配合修补文件的方式则能一次修补大批文件,这也是Linux系统核心的升级方法之一。
! S: j- p$ V7 t {& u" ~
- n3 k; l1 ?" u 参 数:( @' ?3 \. A8 ?# J
-b或--backup 备份每一个原始文件。 1 Z7 ]9 R l1 \# v) z
-B<备份字首字符串>或--prefix=<备份字首字符串> 设置文件备份时,附加在文件名称前面的字首字符串,该字符串可以是路径名称。8 C* N' ` l! b9 E: i9 q
-c或--context 把修补数据解译成关联性的差异。5 U) [" [: V- p4 q
-d<工作目录>或--directory=<工作目录> 设置工作目录。 5 l& Y, N3 _2 D5 z0 T Y
-D<标示符号>或--ifdef=<标示符号> 用指定的符号把改变的地方标示出来。 ; \. ^$ m. H+ [7 Y* ^+ b
-e或--ed 把修补数据解译成ed指令可用的叙述文件。+ m! Y! N5 Q- K+ E; g
-E或--remove-empty-files 若修补过后输出的文件其内容是一片空白,则移除该文件。3 Y: c, e4 |2 h+ R- o" F; p4 `3 X; j
-f或--force 此参数的效果和指定-t参数类似,但会假设修补数据的版本为新 版本。
+ m" \' p9 f' j7 k: F -F<监别列数>或--fuzz<监别列数> 设置监别列数的最大值。 % M( [9 V$ t" D& Z6 N; d7 G: T
-g<控制数值>或--get=<控制数值> 设置以RSC或SCCS控制修补作业。 & g) ?: `* l" _9 \" `4 d" Q5 x
-i<修补文件>或--input=<修补文件> 读取指定的修补问家你。
0 U% H' q L! Q1 M, O -l或--ignore-whitespace 忽略修补数据与输入数据的跳格,空格字符。 ]0 {- q) d3 P) o2 Z
-n或--normal 把修补数据解译成一般性的差异。
9 Q/ Z( e. r- {3 s1 v4 Z -N或--forward 忽略修补的数据较原始文件的版本更旧,或该版本的修补数据已使 用过。 * H* A; L9 W9 {, H; O) H9 W9 G
-o<输出文件>或--output=<输出文件> 设置输出文件的名称,修补过的文件会以该名称存放。 * _3 g& |! Z$ x+ E& s1 r0 K: b) [
-p<剥离层级>或--strip=<剥离层级> 设置欲剥离几层路径名称。# P5 ~$ C4 S7 l! q1 B
-f<拒绝文件>或--reject-file=<拒绝文件> 设置保存拒绝修补相关信息的文件名称,预设的文件名称为.rej。2 J4 r ? m2 }0 T7 n( C4 L
-R或--reverse 假设修补数据是由新旧文件交换位置而产生。
. M& Q, F( C2 x. `- W -s或--quiet或--silent 不显示指令执行过程,除非发生错误。
( w M7 [. [; [0 f% u -t或--batch 自动略过错误,不询问任何问题。 8 E5 O* q( d' A# \* {6 ?
-T或--set-time 此参数的效果和指定-Z参数类似,但以本地时间为主。 + H, K I' v# G+ U
-u或--unified 把修补数据解译成一致化的差异。 / a5 Z% I: V* i; h
-v或--version 显示版本信息。 ! o X4 Q: b+ u9 Z- L
-V<备份方式>或--version-control=<备份方式> 用-b参数备份目标文件后,备份文件的字尾会被加上一个备份字符串,这个字符串不仅可用-z参数变更,当使用-V参数指定不同备份方式时,也会产生不同字尾的备份字符串。 R4 r3 a6 u3 G
-Y<备份字首字符串>或--basename-prefix=--<备份字首字符串> 设置文件备份时,附加在文件基本名称开头的字首字符串。
7 v- |4 D( S, K4 } -z<备份字尾字符串>或--suffix=<备份字尾字符串> 此参数的效果和指定-B参数类似,差别在于修补作业使用的路径与文件名若为src/linux/fs/super.c,加上backup/字符串后,文件super.c会备份于/src/linux/fs/backup目录里。
s" W P2 T/ i1 k6 z -Z或--set-utc 把修补过的文件更改,存取时间设为UTC。
' C6 m+ D% N5 S7 R3 L. B --backup-if-mismatch 在修补数据不完全吻合,且没有刻意指定要备份文件时,才备份文件。
, _- @7 l9 G1 t( H; y --binary 以二进制模式读写数据,而不通过标准输出设备。 - t* Y% A7 O+ A. m4 | `
--help 在线帮助。 & c1 k; X" b7 _- c" F
--nobackup-if-mismatch 在修补数据不完全吻合,且没有刻意指定要备份文件时,不要备份文件。
: e9 V% D3 a% p --verbose 详细显示指令的执行过程。
' Q1 q% F; B& n3 p, u F
4 a. w2 c3 e3 b0 \/ {/ c& f patch,是打补丁的命令,有很多用法,见帮助#man patch
4 I) H" l% V% h2 K( \3 W -p参数决定了是否使用读出的源文件名的前缀目录信息,不提供-p参数,则忽略所有目录信息,( a" H1 D4 H0 V7 p1 d; Y% i
patch -p0 (“p”指的是路径,后面的数字表示去掉路径的第几部分。0,表示不去掉,为全路径)
9 ]& c3 |# J& A. [3 Y patch -p1 (“p”后面的数字1,表示去掉前第一个路径,第一个"/"以前的目录,依此类推。
) w- U# H1 w0 V* G( F2 L+ B 如/usr/src/linux-2.6.11/Makefile这样的文件名,在提供-p3参数时将使用linux-2.6.11/Makefile作为所要patch的文件。- ~7 o5 H8 {# O ^ }# A I
) I4 Q2 P1 ^+ B4 D! y
对于刚才举的Linux内核源码LCD升级包的例子,假定源码目录位于/home/zhenwx/sourcecode/kernel中,
5 T- @% A3 u5 a- N: s1 Z* Z: n! F 则在当前目录为/home/zhenwx/sourcecode/时使用"patch -p0<../zwx-lcd.patch"可以工作,
! V+ M' n8 n; U3 Q2 o4 h7 T 在当前目录为/home/zhenwx/sourcecode/kernel时,使用"patch -p1<../zwx-lcd.patch"也可以正常工作。
7 S4 k! Y* I' l! L# N& h- h
( L0 Z% N% J6 N2 }( _, k如果patch文件里面描述的第一级目录和你自己的第一级目录名字不一样,要将第一级的目录去掉,这个方法就派上用场了。8 R- r/ J. v' [9 a0 V' Y1 J
, g/ T& g# |9 F比如如果你拿到的patch描述的目录和你的不一样,patch第一行描述的目录信息
5 @1 U& q$ A. J$ B) p
; y/ H! R& ^7 g9 fdiff --git a/arch/ARM/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c& p9 g9 t4 K" C
& y- \. _$ r% W* {5 o1 O
但是你的目录既不是a,也不是b,那么你就要将目录的第一层去掉,到你的kernel的路径下面打patch/ N) }9 I5 |7 N: y5 t
, s8 A* |2 V% o
用-p1参数 |
|