内核诊断(二)-- patch 和diff
- patch文件结构
- 生成patch文件 --diff命令
- patch 使用 -- patch命令
3.1 打path
3.1撤销patch - 使用举例
4.1 基本命令使用
4.2 内核打补丁
1. patch文件的结构
补丁头
补丁头是分别由---/+++开头的两行,用来表示要打补丁的文件。
一个补丁文件中的多个补丁
一个补丁文件中可能包含以---/+++开头的很多节,每一节用来打一个补丁。所以在一个补丁文件中可以包含好多个补丁。
块
块是补丁中要修改的地方。它通常由一部分不用修改的东西开始和结束。他们只是用来表示要修改的位置。
他们通常以@@开始,结束于另一个块的开始或者一个新 的补丁头。
块的缩进
块会缩进一列,而这一列是用来表示这一行是要增加还是要删除的。
块的第一列
+号表示这一行是要加上的。
-号表示这一行是要删除的。
没有加号也没有减号表示这里只是引用的而不需要修改。
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index f5d7f4134524..26a2198c59b3 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -220,9 +220,6 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
# Avoid indirect branches in kernel to deal with Spectre
ifdef CONFIG_RETPOLINE
-ifeq ($(RETPOLINE_CFLAGS),)
- $(error You are building kernel with non-retpoline compiler, please update your compiler.)
-endif
KBUILD_CFLAGS += $(RETPOLINE_CFLAGS)
endif
2. 生成patch文件 -- diff命令
diff命令比较两个文件的不同,然后记录下来,也就是所谓的diff补丁。
语法格式:
diff 【选项】 源文件(夹) 目的文件(夹)
diff -Naur 旧的目录 新的目录 > patch文件
diff -Naur 旧的文件 新的文件 > patch文件
给源文件(夹)打个补丁,使之变成目的文件(夹),术语也就是“升级”。
下面介绍三个最为常用选项:
-r 是一个递归选项,设置了这个选项,diff会将两个不同版本源代码目录中的所有对应文件全部都进行一次比较,包括子目录文件。
-N 选项确保补丁文件将正确地处理已经创建或删除文件的情况。
-u 选项以统一格式创建补丁文件,这种格式比缺省格式更紧凑些。
diff 对目录有一些限制,需要保持目录的一致性。
在创建patch的时候文件夹的层数应当是一样的,比如
代码:
--- old/modules/pcitableMon Sep 27 11:03:56 1999
+++ new/modules/pcitableTue Dec 19 20:05:41 2000
这样是可以的。
而代码:
--- old/try1/other/modules/pcitableMon Sep 27 11:03:56 1999
+++ new/modules/pcitableTue Dec 19 20:05:41 2000
这样做可能会有一些问题。
3.patch使用 -- patch命令
patch命令,利用diff制作的补丁来实现源文件(夹)和目的文件(夹)的转换。这样说就意味着你可以有源文件(夹)――>目的文件(夹),
也可以目的文件(夹)――>源文件(夹)。
对于一个patch文件,有两种常用使用方法:
cat new-patch | patch -p0
patch -p0 < new-patch
patch -R -p0 < new-patch
-p0 选项要从当前目录查找目的文件(夹)
-p1 选项要忽略掉第一层目录,从当前目录开始查找。
-E 选项说明如果发现了空文件,那么就删除它
-R 选项说明在补丁文件中的“新”文件和“旧”文件现在要调换过来了(实际上就是给新版本打补丁,让它变成老版本)
patch命令里面的层数(-p0?-p1?)
参数-p来指定从第几层开始比较。比如有一个patch文件的补丁头是这样的:
代码:
--- old/modules/pcitableMon Sep 27 11:03:56 1999
+++ new/modules/pcitableTue Dec 19 20:05:41 2000
如果使用参数-p0,就表示从当前目录,找一个叫作new的目录,在它下面找一个叫modules的目录,再在它下面找一个叫 pcitableMon的目录。
如果使用参数-p1,就表示忽略第一层,从当前目录找一个叫modules的目录,在它下面找一个叫modules的目录。这样会忽略掉补丁头提到的 new目录。
依此类推。
4. 使用例子
4.1 diff命令生成patch
#diff -aurN a/c a/b
diff -aurN a/c/c/a.c a/b/c/a.c
##diff命令会在补丁文件中记录这两个文件的首次创建时间
--- a/c/c/a.c 2019-02-24 10:59:30.351334765 +0800
+++ a/b/c/a.c 2019-02-24 10:52:19.139836763 +0800
@@ -10,5 +10,6 @@
#include<string.h>
#include "head.h"
int main(){
+ printf("hello world\r\n");
return 0;
}
diff -aurN a/c/c/head.h a/b/c/head.h
--- a/c/c/head.h 2019-02-24 10:59:30.355336764 +0800
+++ a/b/c/head.h 2019-02-24 10:52:32.942734763 +0800
@@ -7,5 +7,6 @@
************************************************************************/
#ifndef HEADER_H
#define HEADER_H
+extern void test();
#endif
4.2 patch使用
打patch
lin@lin:~/mytest$ patch -p0 < 123.patch
patching file a/c/c/a.c
patching file a/c/c/head.h
查看文件
lin@lin:~/mytest$ cat a/c/c/a.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "head.h"
int main(){
printf("hello world\r\n");
return 0;
}
lin@lin:~/mytest$ cat a/c/c/head.h
#ifndef HEADER_H
#define HEADER_H
extern void test();
#endif
撤销patch
lin@lin:~/mytest$ patch -R -p0 < 123.patch
patching file a/c/c/a.c
patching file a/c/c/head.h
查看文件
lin@lin:~/mytest$ cat a/c/c/head.h
#ifndef HEADER_H
#define HEADER_H
#endif
lin@lin:~/mytest$ cat a/c/c/a.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "head.h"
int main(){
return 0;
}
4.3 内核打patch
内核不同版本介绍:
(一)Linux内核版本类型及patch简介:
1)基础版本
2.6.x为基础版本,patch位置:
http://www.kernel.org/pub/linux/kernel/v2.6/
2)修正版本
2.6.x.y为2.6.x基础版本之上派生出来的修正版本,称为-stable内核版本,patch位置:
http://www.kernel.org/pub/linux/kernel/v2.6/
3)发布版本
2.6.x.rcN(Release Candidate)内核,是在2.6.(x-1)之上派生出来的之后版本的侯选版本;此种内核
不稳定,发布的时候表示可以用来测试了;
例如对2.6.21加了新功能后派生出2.6.22-rc1,patch位置:
http://www.kernel.org/pub/linux/kernel/v2.6/testing/
4)git版本
git内核是每日内核树的快照,此类型比rc内核更不稳定,从基础版本或rc版本派生出来;
例如2.6.26-git1,2.6.26-rc9-git2,patch位置:
http://www.kernel.org/pub/linux/kernel/v2.6/snapshots/
5)mm版本
mm内核是专门针对内核的mm模块维护的版本,类似于git版本从基础版本或rc版本派生出来;
例如2.6.21-mm2, 2.6.21-rc2-mm1,patch位置:
http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/
不同类型内核的patch名称在前面加上“patch-”(mm内核除外,直接用的版本号),例如:patch-2.6.21, patch-2.6.21.7, patch-2.6.26-git1, patch-2.6.26-rc9-git2, 2.6.21-mm2, 2.6.21-rc2-mm1
(二) 内核补丁类型
增量补丁
同一类型的版本的补丁是用本版本对相邻的前一个版本制作的。
例如,patch-2.6.21是对2.6.20做的补丁,patch-2.6.22是对2.6.21做的补丁,这就是增量补丁。
2.6.x基础版本内核,采用的是增量补丁。非增量补丁
也增量补丁相反,是基本某一固定版本制作的补丁,而非相邻的前一个版本。
例如,patch-2.6.21.3是2.6.21.3版本相对于2.6.21基础版本做的补丁,patch-2.6.21.4是2.6.21.4版本相对于2.6.21基础版本做的补丁,
也就是说2.6.21.4与2.6.21.3之前没有补丁可用。
rc内核,git内核和mm内核都是非增量补丁,都是相对于当前基础版本或rc版本制作出来的补丁。
另外,对于rc内核,git内核,相应的patch目录下面有inc目录中,包含有增量补丁。
(三)内核版本升级
- 同版本升级内核版本
现有基础内核版本2.6.21,想转成2.6.21.7内核stable版本,应该怎么办?
(a) 去内核源码目录下载patch-2.6.21.7;
(b) Linux shell下面,cd到2.6.21内核源文件根目录(linux-2.6.21),
将patch-2.6.21.7也放在本目录(命令执行的当前止录),执行patch命令:
patch -p1 < patch-2.6.21.7
(p1的意思是忽略patch文件(即diff文件)内容中的第一个路径)
c) 打完补丁后,即变成了2.6.21.7的内核了,如果想回退至2.6.21基础版本,执行如下命令即可:
patch -R -p1 < patch-2.6.21.7
(-R的参数意思表示回退这个patch)
2.不同版本内核升级
现有基础内核版本2.6.21,想转成2.6.23.1内核stable版本,应该怎么办?
a) 同1中下载patch-2.6.22, patch-2.6.23, patch-2.6.23.1文件,并设置执行路径和环境;
b) 多次打补丁
patch -p1 < patch-2.6.22 变成了2.6.22
patch -p1 < patch-2.6.23 变成了2.6.23
patch -p1 < patch-2.6.23.1 变成了2.6.23.1
c) 回退操作
patch -R -p1 < patch-2.6.23.1 变成了2.6.23
patch -R -p1 < patch-2.6.23 变成了2.6.22
patch -R -p1 < patch-2.6.22 变成了2.6.21
3.不同内核版本升级
现有基础内核版本2.6.21-git2,想转成2.6.22-rc1-mm2内核stable版本,应该怎么办?
a) 同1中下载patch-2.6.21-git2, patch-2.6.22-rc1, 2.6.22-rc1-mm2文件,
并设置执行路径和环境;
b)打补丁
patch -R -p1 < patch-2.6.21-git2 变成了2.6.21
patch -p1 < patch-2.6.22-rc1 变成了2.6.22-rc1
patch -p1 < 2.6.22-rc1-mm2 变成了2.6.22-rc1-mm2
c) 回退操作
patch -R -p1 < 2.6.22-rc1-mm2 变成了2.6.22-rc1
patch -R -p1 < patch-2.6.22-rc1 变成了2.6.21
patch -p1 < patch-2.6.21-git2 变成了2.6.21-git2
内核诊断(二)-- patch 和diff的更多相关文章
- patch与diff的恩怨
一.概述 diff和patch是一对相辅相成的工具,在数学上来说,diff类似于对两个集合的差运算,patch类似于对两个集合的和运算.diff比较两个文件或文件集合的差异,并记录下来,生成一个dif ...
- linux内核(二)内核移植(DM365-DM368开发攻略——linux-2.6.32的移植)
一.介绍linux-2.6.32: Linux-2.6.32的网上介绍:增添了虚拟化内存 de-duplicacion.重写了 writeback 代码.改进了 Btrfs 文件系统.添加了 ATI ...
- linux内核第一二章总结
1 Linux内核简介 1 Unix的历史 1.Unix演化版实现了任务管理.换页机制.TCP/IP等新的特性. 2.Unix的特点: Unix很简洁,仅仅提供几百个系统调用并且有一个非常明确的设计目 ...
- GIT打补丁 - patch和diff应用
一. 准备工作: [root@guangzhou gittest]# git br * master [root@guangzhou gittest]# git chk -b patch-test1 ...
- 深入理解PHP内核(十二)函数-函数的定义、传参及返回值
原文链接:http://www.orlion.ga/344/ 一.函数的定义 用户函数的定义从function 关键字开始,如下 function foo($var) { echo $var; ...
- windbg内核诊断方式--转载
一.WinDbg是什么?它能做什么? WinDbg是在windows平台下,强大的用户态和内核态调试工具.它能够通过dmp文件轻松的定位到问题根源,可用于分析蓝屏.程序崩溃(IE崩溃)原因,是我们日常 ...
- linux内核系列(二)内核数据结构之链表
双向链表 传统链表与linu内核链表的区别图: 图一 图二 从上图中看出在传统链表中各种不同链表间没有通用性,因为各个数据域不同,而在linux内核中巧妙将链表结构内嵌到数据域结构中使得不同结构之间能 ...
- Linux内核 实践二
实践二 内核模块编译 20135307 张嘉琪 一.实验原理 Linux模块是一些可以作为独立程序来编译的函数和数据类型的集合.之所以提供模块机制,是因为Linux本身是一个单内核.单内核由于所有内容 ...
- (笔记)Linux内核学习(二)之进程
一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器. 内核调度的对象是线程而不是进程.对 ...
随机推荐
- Android 集成支付宝第三方登录
前言: 在集成支付宝支付的时候遇到一点小麻烦,先在此记录供大家参考 1.授权 支付宝第三方登录需要在后台进行授权,在查看授权的时候我们一定要看清楚时候真的已经获得了权限(我在没有获取权限的情况下集成的 ...
- Linux服务器上日志报com.mysql.jdbc.PacketTooBigException: Packet for query is too large (1783 > 1024). You can change this value on the server by setting the max_allowed_packet' variable.
在做查询数据库操作时,报了以上错误,还有out of memery heap hacp ,原因是MySQL的max_allowed_packet设置过小引起的,我一开始设置的是1M,后来改为了20M ...
- K8S中RC与Deployment的区别
原文:http://fx114.net/qa-81-152379.aspx replication controller与deployment的区别 replication controller Re ...
- 学习C++的50条忠告
1. 把C++当成一门新的语言学习: 2. 看<Thinking In C++>,不要看<C++变成死相>: 3. 看<The C++ Programming Langu ...
- Oracle物化视图的一般使用
普通视图和物化视图根本就不是一个东西,说区别都是硬拼到一起的,首先明白基本概念,普通视图是不存储任何数据的,他只有定义,在查询中是转换为对应的定义SQL去查询,而物化视图是将数据转换为一个表,实际存储 ...
- CSS定位DIV(一)一列样式
前记:CSS样式核心就是DIV布局,一些基础知识省略不记,接下来的日志只关注最核心的布局问题. 一.一列布局 1.固定宽高 直接声明宽高,或用百分比表示. width:400px; 或 width:7 ...
- C#基础入门 八
C#基础入门 八 泛型 C#中的泛型能够将类型作为参数来传递,即在创建类型时用一个特定的符号,如"T"来作为一个占位符,代替实际的类型,等待实例化时用一个实际的类型来代替. pub ...
- ERROR 3009 (HY000): Column count of mysql.user is wrong. Expected 45, found 43. Created with MySQL 5
ERROR 3009 (HY000): Column count of mysql.user is wrong. Expected 45, found 43. Created with MySQL 5 ...
- Webservice发布
此文甚好,转载自:http://blog.163.com/java_player@126/blog/static/127930738200981555021925/ 某些地方笔者已经加以改进. 使用工 ...
- linux查看占用内存多的进程
update一个简单的方法 ps aux | sort -k4nr | head -10 ps -e -o "%C : %p : %z : %a"|sort -k5 -nr|h ...