how to create and submit kernel patch through git step by step

What follows is astep-by-step guide on how to submit a Linux kernel patch and hope that it gets accepted into the mainlinekernel. This HOW-TO is based on an actual patch that I wrote and submitted andwhich got accepted into mainline kernel yesterday. The guide mostly highlightsthe mechanics of sending patches and not necessarily technical design aspectsof Linux kernel.

Step 1: Install GitTools

The first thing we need to do is to make sure that we have necessarytools to create and submit our Linux kernel patch. I am using my Ubuntu systemfor this HOW-TO.

# apt-get update
# apt-get install git git-email gitk

Additionally it is a good ideato configure some few parameters that Git will use when it generates yourpatch:

# git config --add user.name "Bean Huo"
# git config --add user.email "jackyard88@gmail.com"

Step 2:Clone Linus’ Git Tree

The nextthing you may want to do is to clone Linus’s Git tree preferably on your Linuxmachine. Make sure you have enough space (at least 2GB) before you clone thetree. At the time of this writing the total size of the tree was around 950+MB.

root@bean-ThinkCentre-M92p:~# cd /usr/src/
root@bean-ThinkCentre-M92p:/usr/src/# gitclone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6mylinux-2.6

Now wait for 30 minutes or so, depending on your Internet connectionspeed, before the entire tree gets downloaded into your directory mylinux-2.6(directory will be created automatically since you have specified in thecommand). Any patchwork should always be done against this tree to make surethat your changes might not conflict with changes made by other developers.

root@bean-ThinkCentre-M92p:/usr/src/# cdmylinux-2.6
root@bean-ThinkCentre-M92p:/usr/src/mylinux-2.6#ls
arch COPYING  crypto drivers fsinit  Kbuild   kernel  MAINTAINERS  mm  README samples  security  tools  virt block  CREDITS Documentation  firmware  include  ipc   Kconfig lib  Makefile net  REPORTING-BUGS  scripts sound     usr
root@bean-ThinkCentre-M92p:/usr/src/mylinux-2.6#

Fromhere onwards all the work will be done in /usr/src/mylinux-2.6directory.

Step 3:Now create a local branch to make your changes

Bydefault when you clone the Git tree you are in the master branch.

# git branch
* master
#

The *above indicates your current branch.

Let’screate a new branch my patch_v1 in which we will doour code changes:

# git branch patch_v1

Thenyou need to checkout the above newly created branch:

# git checkout patch_v1

Confirmthat you are in the above branch:

# git branch
* patch_v1
master
#

Step 4:Make your changes

Now Iam going to make changes to the driver/mtd/chips/cfi_cmdset_0002.c  file. After you made your changes to the fileand saved it give the following command:

# git commit -a

Theabove command will open a text editor in the same window on your terminalscreen (my default text editor is nano) like this:

# Please enter thecommit message for your changes. Lines starting
# with '#' will beignored, and an empty message aborts the commit.
# On branch Test1
# Changes to becommitted:
#   (use"git reset HEAD <file>..." to unstage)
#
#      modified:   the driver/mtd/chips/cfi_cmdset_0002.c
#

Nowwe will enter our commit log message. Be very careful what you type in the logmessage because these messages will become part of Linux Git tree commit logand people will be searching your commit based on these messages. Here is whatI typed in and here is what my final editor window looked it:

mtd:nor:timeout:fix do_write_buffer() timeout error

 

The size of the buffer program has been increased from 256 to 512 ,

2ms maximum timeout can not adapt to all the different vendor'snorflash,

There maximum timeout information in the CFI area,so the best way isto

choose the result calculated according to timeout field of structcfi_ident

that probed from norflash's CFI aera.This is also a standard definedby CFI.

 

Without this change, if the size of buffer program is 512 orbigger than 256,

due to timeout is the shorter than that the chiprequired,do_write_buffer

sometimes fails.

Tested with MicronJS28F512M29EWx and Micron MT28EW512ABA flash devices.
# Please enter thecommit message for your changes. Lines starting
# with '#' will beignored, and an empty message aborts the commit.
# On branch Test1
# Changes to becommitted:
#   (use"git reset HEAD <file>..." to unstage)
#
#      modified:   the driver/mtd/chips/cfi_cmdset_0002.c
#

Now thetext in blue color will become your main subject line of the patch that youwill email and will also become the identifier in the Git commit log.

Note: It is very importantthat you first type the name of the subsystem to which your patch belongs to.In my case since I am modifying the the cfi_cmdset_0002.c  file in the mtd  architecture directory, I begin by subjectline with mtd:.

Afterthat you need to leave one empty line. and then type a brief description aboutyour change (in red color) which will become the changelog of the Git commitlog.

Do notworry about the text in orange color that begins with #. Those will beignored by Git commit.

Note: Ifyou don’t leave one empty line between your subject and description , yourdescription will become part of the subject line and it will be all mess.

Step 5:Generate your patch

Sonow you have commit your patch in your local Git repository, it is time togenerate the patch that we will email to the respective maintainers and mailinglists. To generate patch simply give the following command:

# git format-patch -s-n master..patch_v1

Thisshould create a file 0001-mtd-nor-timeout-fix-do_write_buffer-timeout-error.patchin your current directory whose content will be:

From 454cd2917bb25e0b1c3822b955a61101fec4de36 Mon Sep 1700:00:00 2001

From: bean huo <jackyard88@gmail.com>

Date: Sat, 17 May 2014 08:16:24 +0800

Subject: [PATCH 1/1] mtd:nor:timeout:fix do_write_buffer()timeout error

 

The size of the buffer program has been increased from 256 to512 ,

2ms maximum timeout can not adapt to all the different vendor'snorflash,

There maximum timeout information in the CFI area,so the bestway is to

choose the result calculated according to timeout field ofstruct cfi_ident

that probed from norflash's CFI aera.This is also a standard definedby CFI.

 

Without this change, if the size of buffer program is 512 orbigger than 256,

due to timeout is the shorter than that the chiprequired,do_write_buffer

sometimes fails.

 

Tested with Micron JS28F512M29EWx and Micron MT28EW512ABA flashdevices.

 

Signed-off-by: bean huo <jackyard88@gmail.com>

---

 drivers/mtd/chips/cfi_cmdset_0002.c |   50 +++++++++++++++++++++++++++++++++--

 1 file changed, 48insertions(+), 2 deletions(-)

 

diff --git a/drivers/mtd/chips/cfi_cmdset_0002.cb/drivers/mtd/chips/cfi_cmdset_0002.c

index e21fde9..813b5a4 100644

--- a/drivers/mtd/chips/cfi_cmdset_0002.c

+++ b/drivers/mtd/chips/cfi_cmdset_0002.c

@@ -628,6 +628,42 @@ struct mtd_info *cfi_cmdset_0002(structmap_info *map, int primary)

            cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;

            cfi->chips[i].buffer_write_time =1<<cfi->cfiq->BufWriteTimeoutTyp;

            cfi->chips[i].erase_time =1<<cfi->cfiq->BlockEraseTimeoutTyp;

+          

+           /*

+           * We firstcalculate the timeout max according to timeout field of

+           * structcfi_ident that probed from chip's CFI aera,If haven't probed

+           * thisinformation,we will specify a default value,and the time unit is us.

+           */        

+           if(cfi->cfiq->WordWriteTimeoutTyp &&

+                 cfi->cfiq->WordWriteTimeoutMax){

+                 cfi->chips[i].word_write_time_max=

+                       1<<(cfi->cfiq->WordWriteTimeoutTyp+

+                             cfi->cfiq->WordWriteTimeoutMax);

+                 }else{

+                 /*specify maximum timeout for byte/word program 2000us */

+                       cfi->chips[i].word_write_time_max= 2000;

+                       }

+

+           if(cfi->cfiq->BufWriteTimeoutTyp &&

+                 cfi->cfiq->BufWriteTimeoutMax){

+                 cfi->chips[i].buffer_write_time_max=

+                       1<<(cfi->cfiq->BufWriteTimeoutTyp+

+                             cfi->cfiq->BufWriteTimeoutMax);

+                 }else{

+                 /*specify maximum timeout for buffer program 2000us */

+                       cfi->chips[i].buffer_write_time_max= 2000;

+                       }

+                

+           if(cfi->cfiq->BlockEraseTimeoutTyp &&

+                 cfi->cfiq->BlockEraseTimeoutMax){

+                 cfi->chips[i].erase_time_max=

+                       1<<(cfi->cfiq->BlockEraseTimeoutTyp+

+                             cfi->cfiq->BlockEraseTimeoutMax);

+                 }else{

+                 /*specify maximum timeout per individual block erase 3000000us */

+                       cfi->chips[i].erase_time_max= 3000000;

+                       }

+    

            cfi->chips[i].ref_point_counter = 0;

            init_waitqueue_head(&(cfi->chips[i].wq));

      }

@@ -1462,8 +1498,18 @@ static int __xipramdo_write_buffer(struct map_info *map, struct flchip *chip,

 {

      struct cfi_private *cfi = map->fldrv_priv;

      unsigned long timeo = jiffies + HZ;

-     /* see comments indo_write_oneword() regarding uWriteTimeo. */

-     unsigned longuWriteTimeout = ( HZ / 1000 ) + 1;

+

+     /* The size of thebuffer program has been increased from 256 to 512 ,

+     * 2ms maximumtimeout can not adapt to all the different vendor's norflash,

+     * There maximumtimeout information in the CFI area,so the best way is to

+     * choose the resultcalculated according to timeout field of struct cfi_ident

+     * that probed fromnorflash's CFI aera,see comments in cfi_cmdset_0002().

+     * The time unit ofuWriteTimeout is ms.

+     */

+

+     unsigned longuWriteTimeout = (chip->buffer_write_time_max % 1000) ?

+                             (chip->buffer_write_time_max/ 1000 + 1):

+                             (chip->buffer_write_time_max/ 1000);

      int ret = -EIO;

      unsigned long cmd_adr;

      int z, words;

--

1.7.9.5

Notehow the name of the file was picked from your first line of the Git commit log.Also the option -n adds the patch number [PATCH 1/1] to yoursubject and the -s option adds the Signed-off-by: line. The emailthat is picked in the signed off line is picked from your Git’s configurationthat you set in Step 1.

Step 6:Check your patch for errors

Next weneed to make sure that the patch we are trying to submit does not contain anyobvious errors like white spaces, exceeding 80 column limit, etc. There is aperl script called checkpath.pl that is provided with the kernel sourcesfor this purpose:

#scripts/checkpatch.pl 0001-mtd-nor-timeout-fix-do_write_buffer-timeout-error.patch

and youshould see something like this:

Output:

total: 0 errors, 0warnings, 14 lines checked
0001-mtd-nor-timeout-fix-do_write_buffer-timeout-error.patchhas no obvious style problems and is ready for submission.

Thereare other scripts also provided inside the kernel source to fix/clean yourpatch like:

scripts/cleanfile
scripts/cleanpatch

Step 7:Test your patch

Againit is very important that you apply your patch to the Linus’ Git tree, compileit and test it before sending your patch upstream.

# git checkout master
# patch -p1 < 0001-mtd-nor-timeout-fix-do_write_buffer-timeout-error.patch
 

Step 8:Get the list of people to submit patch to

Assumingyour patch compiled, worked the way you want it to and your test emails lookedgood the next step is to get the list of concern people to whom you shouldemail your patch. There are two methods to do that:

Method1: Use the script provided in the kernel source

#scripts/get_maintainer.pl 0001-mtd-nor-timeout-fix-do_write_buffer-timeout-error.patch

Output:

 

David Woodhouse <dwmw2@infradead.org>(maintainer:MEMORY TECHNOLOGY...)

Brian Norris <computersforpeace@gmail.com>(maintainer:MEMORY TECHNOLOGY...,commit_signer:2/6=33%)

Paul Gortmaker<paul.gortmaker@windriver.com> (commit_signer:1/6=17%,authored:1/6=17%)

Jingoo Han <jg1.han@samsung.com>(commit_signer:1/6=17%,authored:1/6=17%,removed_lines:6/58=10%)

Artem Bityutskiy<artem.bityutskiy@linux.intel.com> (commit_signer:1/6=17%)

Huang Shijie <b32955@freescale.com>(commit_signer:1/6=17%,authored:1/6=17%)

linux-mtd@lists.infradead.org (openlist:MEMORY TECHNOLOGY...)

linux-kernel@vger.kernel.org (open list)
#

Method 2: Refer to theMAINTAINERS file

The other method is torefer to the MAINTAINERS filethat is provide inside the kernel source tree. You need to at least email yourpatch to all of the people who have “M” before their name.

Note: Alsoyou need to email your patch to at least one mailing list. If you are not ablefind any mailing list, based on the above two methods, that is concerned withthe subsystem against which you are trying to submit your patch, then youshould at least email to Linux Kernel Mailing List(linux-kernel@vger.kernel.org).

Step 9: Test Email yourpatch

Although you could useany email client and SMTP host that you want and have access to, I found thatusing Gmail was the best since a lot of kernel developers use that. Now it isvery important that you first test your patch by sending it your own email addresses(possible different email account with different mail providers). I use thefollowing:

git send-email --smtp-encryption=tls--smtp-server=smtp.gmail.com --smtp-user=jackyard88@gmail.com--smtp-server-port=587 --to "beanhuo <beanhuo@micron.com>" --to"jackyard <jackyard@yahoo.com>" --cc "KK <jackyard@hotmail.com>"0001-mtd-nor-timeout-fix-do_write_buffer-timeout-error.patch

After you hit enter, itwill ask for your Gmail account password which you need to enter in order toactually send the email.

Now check email accountslisted above to verify if you got the email and everything looks good forsubmission.

Step 10: Finally Emailyour patch

If everything looks right then youfinally email your patch based on the list of people you found in Step 8.This is what I actually ended up using:

# git send-email --smtp-encryption=tls--smtp-server=smtp.gmail.com --smtp-user=jackyard88@gmail.com--smtp-server-port=587 --from "Kushal Koolwal <jackyard88@gmail.com>"--to "David Woodhouse dwmw2@infradead.org” --to " Brian Norris computersforpeace@gmail.com”--cc " Paul Gortmaker<paul.gortmaker@windriver.com> " --cc "linux-mtd@lists.infradead.org"  --cc “linux-kernel@vger.kernel.org “0001-mtd-nor-timeout-fix-do_write_buffer-timeout-error.patch

That’sit! Your patch has been submitted to linux community. Good luck with your firstpatch!

If youdon’t want to use git email tool function to send you patch ,you also cansubmit you patch by outlook or other email tools.For example ,if you useoutlook to send this patch,its format just as below;

Directlysend to maintainer mail address:  "David Woodhouse dwmw2@infradead.org”  " Brian Norris computersforpeace@gmail.com”

CCmail address:   " Paul Gortmaker <paul.gortmaker@windriver.com>   "linux-mtd@lists.infradead.org”

      “linux-kernel@vger.kernel.org”

Youremail Subject:

 [PATCH 1/1] mtd:nor:timeout:fixdo_write_buffer() timeout error

Contextis:

The size of the buffer program has beenincreased from 256 to 512 ,

2ms maximum timeout can not adapt to all thedifferent vendor's norflash,

There maximum timeout information in the CFIarea,so the best way is to

choose the result calculated according totimeout field of struct cfi_ident

that probed from norflash's CFI aera.This isalso a standard defined by CFI.

 

Without this change, if the size of bufferprogram is 512 or bigger than 256,

due to timeout is the shorter than that thechip required,do_write_buffer

sometimes fails.

 

Tested with Micron JS28F512M29EWx and MicronMT28EW512ABA flash devices.

 

Signed-off-by: bean huo <beanhuo@micron.com>

---

 drivers/mtd/chips/cfi_cmdset_0002.c |   50 +++++++++++++++++++++++++++++++++--

 1 filechanged, 48 insertions(+), 2 deletions(-)

 

diff --gita/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c

index e21fde9..813b5a4 100644

--- a/drivers/mtd/chips/cfi_cmdset_0002.c

+++ b/drivers/mtd/chips/cfi_cmdset_0002.c

@@ -628,6 +628,42 @@ struct mtd_info*cfi_cmdset_0002(struct map_info *map, int primary)

                              cfi->chips[i].word_write_time= 1<<cfi->cfiq->WordWriteTimeoutTyp;

                              cfi->chips[i].buffer_write_time= 1<<cfi->cfiq->BufWriteTimeoutTyp;

                              cfi->chips[i].erase_time= 1<<cfi->cfiq->BlockEraseTimeoutTyp;

+                          

+                           /*

+                           * We first calculate the timeout max according to timeout field of

+                           * struct cfi_ident that probed from chip's CFI aera,If haven't probed

+                           * this information,we will specify a default value,and the time unit is us.

+                           */                        

+                           if(cfi->cfiq->WordWriteTimeoutTyp &&

+                                          cfi->cfiq->WordWriteTimeoutMax){

+                                          cfi->chips[i].word_write_time_max=

+                                                         1<<(cfi->cfiq->WordWriteTimeoutTyp+

+                                                                        cfi->cfiq->WordWriteTimeoutMax);

+                                          }else{

+                                          /*specify maximum timeout for byte/word program 2000us */

+                                                         cfi->chips[i].word_write_time_max= 2000;

+                                                         }

+

+                           if(cfi->cfiq->BufWriteTimeoutTyp &&

+                                          cfi->cfiq->BufWriteTimeoutMax){

+                                          cfi->chips[i].buffer_write_time_max=

+                                                         1<<(cfi->cfiq->BufWriteTimeoutTyp+

+                                                                        cfi->cfiq->BufWriteTimeoutMax);

+                                          }else{

+                                          /*specify maximum timeout for buffer program 2000us */

+                                                         cfi->chips[i].buffer_write_time_max= 2000;

+                                                         }

+                                         

+                           if(cfi->cfiq->BlockEraseTimeoutTyp &&

+                                          cfi->cfiq->BlockEraseTimeoutMax){

+                                          cfi->chips[i].erase_time_max=

+                                                         1<<(cfi->cfiq->BlockEraseTimeoutTyp+

+                                                                        cfi->cfiq->BlockEraseTimeoutMax);

+                                          }else{

+                                          /*specify maximum timeout per individual block erase 3000000us */

+                                                         cfi->chips[i].erase_time_max= 3000000;

+                                                         }

+            

                              cfi->chips[i].ref_point_counter= 0;

                              init_waitqueue_head(&(cfi->chips[i].wq));

               }

@@ -1462,8 +1498,18 @@ static int __xipramdo_write_buffer(struct map_info *map, struct flchip *chip,

 {

               struct cfi_private *cfi =map->fldrv_priv;

               unsigned long timeo = jiffies +HZ;

-             /*see comments in do_write_oneword() regarding uWriteTimeo. */

-             unsignedlong uWriteTimeout = ( HZ / 1000 ) + 1;

+

+             /*The size of the buffer program has been increased from 256 to 512 ,

+             * 2ms maximum timeout can not adapt to all the different vendor's norflash,

+             * There maximum timeout information in the CFI area,so the best way is to

+             * choose the result calculated according to timeout field of struct cfi_ident

+             * that probed from norflash's CFI aera,see comments in cfi_cmdset_0002().

+             * The time unit of uWriteTimeout is ms.

+             */

+

+             unsignedlong uWriteTimeout = (chip->buffer_write_time_max % 1000) ?

+                                                                        (chip->buffer_write_time_max/ 1000 + 1):

+                                                                        (chip->buffer_write_time_max/ 1000);

               int ret = -EIO;

               unsigned long cmd_adr;

               int z, words;

--

1.7.9.5

Note :please use plain text mode in your email.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值