2010年1月24日 星期日

如何建立 patch

假設要製作 Linux kernel 原始碼中 arch/arm/boot/Makefile 的 patch。首先準備好修改前後的檔案,例如 Makefile 及 Makefile.orig。然後使用 diff 指令產生兩個檔案的差異,指令如下:

LC_ALL=C TZ=UTC0 diff -up Makefile.orig Makefile > arch_arm_boot_makefile.patch

這時會得到以下的內容:

--- Makefile.orig 2010-01-14 01:26:36.000000000 +0000
+++ Makefile 2010-01-24 11:16:04.848551840 +0000
@@ -17,6 +17,16 @@ ifneq ($(MACHINE),)
include $(srctree)/$(MACHINE)/Makefile.boot
endif

+SEC_OUTDIR := $(shell if [ -f /etc/inetd.conf ]; then \
+ cat /etc/inetd.conf | grep in.tftpd | awk '{print $$8}'; \
+ elif [ -f /etc/xinetd.d/tftp ]; then \
+ cat /etc/xinetd.d/tftp | grep server_args | \
+ sed 's/^.*-s //g'; \
+ elif [ -f /etc/default/tftpd-hpa ]; then \
+ cat /etc/default/tftpd-hpa | grep OPTIONS | \
+ sed 's/^.*-s //g' | sed 's/\".*$//g'; \
+ fi)
+
# Note: the following conditions must always be true:
# ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
# PARAMS_PHYS must be within 4MB of ZRELADDR
@@ -56,8 +66,9 @@ $(obj)/compressed/vmlinux: $(obj)/Image
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
- cp -f arch/arm/boot/zImage /tftpboot/
- @echo ' Kernel: $@ is ready'
+ $(shell if [ -d $(SEC_OUTDIR) ]; then \
+ cp -f arch/arm/boot/zImage $(SEC_OUTDIR); fi)
+ @echo ' Kernel: $@ is also ready at $(SEC_OUTDIR)'

endif

但由於避免使用 *.orig 這類的名稱,且可以在最前面加上產生 patch 的指令,因此修改成如下:

diff -up old/arch/arm/boot/Makefile new/arch/arm/boot/Makefile
--- old/arch/arm/boot/Makefile 2010-01-14 01:26:36.000000000 +0000
+++ new/arch/arm/boot/Makefile 2010-01-24 11:16:04.848551840 +0000
@@ -17,6 +17,16 @@ ifneq ($(MACHINE),)
include $(srctree)/$(MACHINE)/Makefile.boot
endif

+SEC_OUTDIR := $(shell if [ -f /etc/inetd.conf ]; then \
+ cat /etc/inetd.conf | grep in.tftpd | awk '{print $$8}'; \
+ elif [ -f /etc/xinetd.d/tftp ]; then \
+ cat /etc/xinetd.d/tftp | grep server_args | \
+ sed 's/^.*-s //g'; \
+ elif [ -f /etc/default/tftpd-hpa ]; then \
+ cat /etc/default/tftpd-hpa | grep OPTIONS | \
+ sed 's/^.*-s //g' | sed 's/\".*$//g'; \
+ fi)
+
# Note: the following conditions must always be true:
# ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
# PARAMS_PHYS must be within 4MB of ZRELADDR
@@ -56,8 +66,9 @@ $(obj)/compressed/vmlinux: $(obj)/Image
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
- cp -f arch/arm/boot/zImage /tftpboot/
- @echo ' Kernel: $@ is ready'
+ $(shell if [ -d $(SEC_OUTDIR) ]; then \
+ cp -f arch/arm/boot/zImage $(SEC_OUTDIR); fi)
+ @echo ' Kernel: $@ is also ready at $(SEC_OUTDIR)'

endif

那麼怎麼使用這個 patch 呢?指令很簡單,如下:

patch -d $PWD/s3c6410-linux-2.6.27 -p1 < arch_arm_boot_makefile.patch

就可以用這個 patch 去修改 $PWD/s3c6410-linux-2.6.27/arch/arm/boot/Makefile 了。

延伸閱讀:

張貼留言