User Tools

Site Tools


lkmp:lkmp_first_kernel_patch

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
lkmp:lkmp_first_kernel_patch [2019/04/05 16:36]
ShuahKhanLF
lkmp:lkmp_first_kernel_patch [2019/08/08 22:22] (current)
ShuahKhanLF
Line 1: Line 1:
 ====== Linux Kernel Mentorship Program - Write First Kernel Patch ====== ====== Linux Kernel Mentorship Program - Write First Kernel Patch ======
  
-This material in this guide is based on the [[https://​kernelnewbies.org/​FirstKernelPatch|FirstKernelPatch]] tutorial.+This material in this guide is based on the KernelNewbies ​[[https://​kernelnewbies.org/​FirstKernelPatch|FirstKernelPatch]] tutorial
 + 
 +Let's start by configuring global git options and then you can go onto cloning the kernel repository.
  
 ==== Setup git ==== ==== Setup git ====
-First, you need to tell git what your name and email address is, so that it can be used in the authorship information in the git commit.  ​Create a file named .gitconfig in your home directory and add lines like these to it:+ 
 +Create a user-specific Git configuration ​file named **.gitconfig** in your home directory ​with your name, email, ​and other configuration. This information is used for commits and patch generation. ​
  
 <​code>​ <​code>​
 +
 [user] [user]
    name = Your Name    name = Your Name
Line 22: Line 26:
  smtpuser ​      = user  smtpuser ​      = user
  smtppass ​      = password  smtppass ​      = password
 +
 </​code>​ </​code>​
  
-**Make sure that the email you specify here is the same email you used to set up sending mail**. The Linux kernel developers will not accept a patch where the "​From"​ email differs from the "​Signed-off-by"​ line, which is what will happen if these two emails do not match.+**The email in the .gitconfig should be the same email you will use to send patches**. The "​name"​ is the "​Author"​ name and the email is the email address for the commit. The Linux kernel developers will not accept a patch where the "​From"​ email differs from the "​Signed-off-by"​ line, which is what will happen if these two emails do not match.
  
-Make sure you store your full, legal name in the 'name' ​line. By adding your Signed-off-by line to a patch, you are certifying that you have read and understood the [[https://​www.kernel.org/​doc/​html/​latest/​process/​submitting-patches.html|Developer'​s Certificate of Origin]] and abide by the [[https://​www.kernel.org/​doc/​html/​latest/​process/​kernel-enforcement-statement.html|Linux Kernel Enforcement Statement]]. Please read though the documents before you send patches to the kernel.+Make sure you store your full, legal name in the name line. By adding your Signed-off-by line to a patch, you are certifying that you have read and understood the [[https://​www.kernel.org/​doc/​html/​latest/​process/​submitting-patches.html|Developer'​s Certificate of Origin]] and abide by the [[https://​www.kernel.org/​doc/​html/​latest/​process/​kernel-enforcement-statement.html|Linux Kernel Enforcement Statement]]. Please read though the documents before you send patches to the kernel.
  
 ==== Explore the kernel tree ==== ==== Explore the kernel tree ====
Line 38: Line 43:
 mkdir mypatches mkdir mypatches
 cd mypatches cd mypatches
-git clone git://​git.kernel.org/​pub/​scm/​linux/​kernel/​git/​torvalds/linux.git linux +git clone git://​git.kernel.org/​pub/​scm/​linux/​kernel/​git/​gregkh/staging.git staging 
-cd linux+cd staging
 </​code>​ </​code>​
  
-This is the Linux kernel tree.  You can explore it by using the `lsand `cdcommands. If you run `ls`, you'll see several different folders:+This is the Linux kernel tree.  You can explore it by using the "**ls**" ​and "**cd**" ​commands. If you run "**ls**", you'll see several different folders:
  
 <​code>​ <​code>​
 $ ls $ ls
-arch     Documentation ​ Kbuild ​      ​Makefile ​       scripts ​  ​vmlinux-gdb.py +arch     CREDITS ​       fs       ​Kbuild ​  ​LICENSES ​    ​net ​     security ​ virt 
-block    ​drivers ​       ​Kconfig ​     ​mm ​             security +block    ​crypto ​        ​include  ​Kconfig ​ ​MAINTAINERS ​ README ​  sound 
-certs    ​fs             kernel ​      Module.symvers ​ sound +certs    ​Documentation ​ init     kernel ​  Makefile ​    ​samples ​ tools 
-COPYING  ​include ​       ​lib ​         ​net ​            ​tools +COPYING  ​drivers ​       ipc      ​lib      ​mm ​          ​scripts ​ usr
-CREDITS ​ init           ​LICENSES ​    ​README ​         usr +
-crypto ​  ​ipc ​           MAINTAINERS ​ samples ​        virt+
 </​code>​ </​code>​
  
-There'​s more to this directory than meets the eye!  If you run ls -A, you'll see there'​s a hidden directory called ​{{{.git}}}.  This contains all the meta information that git uses to track branches, remote repositories,​ and changes to files in the local directory.+There'​s more to this directory than meets the eye!  If you run "**ls -A**", you'll see there'​s a hidden directory called ​"**.git**".  This contains all the meta information that git uses to track branches, remote repositories,​ and changes to files in the local directory.
  
 <​code>​ <​code>​
-arch           ​drivers ​                kernel ​         scripts +arch           Documentation ​          ​init ​     MAINTAINERS ​ sound 
-block          ​fs ​                     ​lib             ​security +block          ​drivers ​                ipc       ​Makefile ​    tools 
-certs          ​.get_maintainer.ignore  ​LICENSES ​       sound +certs          ​fs ​                     ​Kbuild ​   mm           usr 
-.clang-format  ​.git                    ​.mailmap ​       tools +.clang-format  ​.get_maintainer.ignore  ​Kconfig ​  ​net ​         virt 
-.cocciconfig ​  .gitattributes ​         ​MAINTAINERS ​    usr +.cocciconfig ​  .git                    ​kernel ​   README 
-.config ​       ​.gitignore ​             ​Makefile ​       .version +COPYING ​       ​.gitattributes ​         ​lib       ​samples 
-.config.old ​   ​include ​                mm              virt +CREDITS ​       ​.gitignore ​             ​LICENSES ​ scripts 
-COPYING ​       init                    Module.symvers ​ vmlinux-gdb.py +crypto ​        include ​                .mailmap ​ security
-CREDITS ​       ipc                     net +
-crypto ​        ​Kbuild ​                 README +
-Documentation ​ Kconfig ​                ​samples+
 </​code>​ </​code>​
  
-You can view the commit history by running ​`git log`. The following example uses 1git log -1` to check the first commit ​to illustrate the difference between full commit log vs. the short log.+You can view the commit history by running git log. The following example uses "​**git ​log -2**" ​to look at the top two commits ​to illustrate the difference between full commit log vs. the short log.
  
 <​code>​ <​code>​
-$ git log -1 +$ git log -2 
-commit ​5e7a8ca319268a70a6c7c3c1fde5bea38e1e5539 ​(HEAD -> first-patch, origin/​master,​ origin/HEAD, master+commit ​79a3aaa7b82e3106be97842dedfd8429248896e6 ​(HEAD -> master, tag: v5.1-rc3, origin/​master,​ origin/​HEAD) 
-Merge: ​db5481e705e2 7316b49c2a11+Author: Linus Torvalds <​torvalds@linux-foundation.org>​ 
 +Date:   Sun Mar 31 14:39:29 2019 -0700 
 + 
 +    Linux 5.1-rc3 
 + 
 +commit 63fc9c23488d6cf34e4c233e24ba59b7e5548412 
 +Merge: ​915ee0da5ecb 690edec54cba
 Author: Linus Torvalds <​torvalds@linux-foundation.org>​ Author: Linus Torvalds <​torvalds@linux-foundation.org>​
-Date:   Mon Apr 1 08:28:36 2019 -0700+Date:   Sun Mar 31 08:55:59 2019 -0700
  
-    Merge branch ​'work.aio' of git://​git.kernel.org/​pub/​scm/​linux/​kernel/​git/viro/vfs+    Merge tag 'for-linus' of git://​git.kernel.org/​pub/​scm/​virt/kvm/kvm
     ​     ​
-    Pull aio race fixes and cleanups ​from Al Viro.+    Pull KVM fixes from Paolo Bonzini: 
 +     "​A collection of x86 and ARM bugfixes, and some improvements to 
 +      documentation.
     ​     ​
-    The aio code had more issues with error handling and races with the aio +      On top of this, a cleanup of kvm_para.h headers, which were exported 
-    ​completing ​at just the right (wrong) time along with freeing ​the file +      by some architectures even though they not support KVM at all. This is 
-    descriptor when another thread closes the file.+      responsible for all the Kbuild changes in the diffstat"​
     ​     ​
-    ​Just a couple ​of these commits ​are the actual fixes: the others are +    ​* tag '​for-linus' ​of git://​git.kernel.org/​pub/​scm/​virt/​kvm/​kvm:​ (28 commits
-    ​cleanups ​to either make the fixes simpler, or to make the code legible +      Documentation:​ kvm: clarify KVM_SET_USER_MEMORY_REGION 
-    and understandable enough that we hope there'​s ​no more fundamental races +      KVM: docDocument ​the life cycle of a VM and its resources 
-    ​hiding.+      KVM: selftests: complete IO before migrating guest state 
 +      KVM: selftests: disable stack protector for all KVM tests 
 +      KVM: selftests: explicitly disable PIE for tests 
 +      KVM: selftests: assert on exit reason in CR4/cpuid sync test 
 +      KVM: x86: update %rip after emulating IO 
 +      x86/​kvm/​hyper-v:​ avoid spurious pending stimer on vCPU init 
 +      kvm/x86: Move MSR_IA32_ARCH_CAPABILITIES ​to array emulated_msrs 
 +      KVM: x86: Emulate MSR_IA32_ARCH_CAPABILITIES on AMD hosts 
 +      kvm: don't redefine flags as something else 
 +      kvm: mmu: Used range based flushing in slot_handle_level_range 
 +      KVM: export <​linux/​kvm_para.h> ​and <​asm/​kvm_para.h>​ iif KVM is supported 
 +      KVM: x86: remove check on nr_mmu_pages in kvm_arch_commit_memory_region() 
 +      kvm: nVMX: Add a vmentry check for HOST_SYSENTER_ESP and HOST_SYSENTER_EIP fields 
 +      KVM: SVM: Workaround errata#1096 (insn_len maybe zero on SMAP violation) 
 +      KVM: Reject device ioctls from processes other than the VM'​s ​creator 
 +      KVM: doc: Fix incorrect word ordering regarding supported use of APIs 
 +      KVM: x86: fix handling of role.cr4_pae and rename it to '​gpte_size'​ 
 +      KVM: nVMX: Do not inherit quadrant and invalid for the root shadow EPT 
 +      ...
  
----- 
----- 
 </​code>​ </​code>​
  
Line 99: Line 123:
  
 <​code>​ <​code>​
-$ git log ---pretty=oneline --abbrev-commit +$ git log ---pretty=oneline --abbrev-commit 
-5e7a8ca31926 ​(HEAD -> first-patch, origin/​master,​ origin/HEAD, master) Merge branch ​'work.aio' of git://​git.kernel.org/​pub/​scm/​linux/​kernel/​git/viro/vfs+79a3aaa7b82e ​(HEAD -> master, tag: v5.1-rc3, origin/​master,​ origin/​HEAD) ​Linux 5.1-rc3 
 +63fc9c23488d ​Merge tag 'for-linus' of git://​git.kernel.org/​pub/​scm/​virt/kvm/kvm
 </​code>​ </​code>​
  
Line 108: Line 133:
 Git includes support for branches. ​ Each branch can contain a completely different set of patches. Kernel developers typically use one branch per patch set. For example, you might have one branch that includes bug fixes, and another branch that contains commits for a new feature you're working on. Git includes support for branches. ​ Each branch can contain a completely different set of patches. Kernel developers typically use one branch per patch set. For example, you might have one branch that includes bug fixes, and another branch that contains commits for a new feature you're working on.
  
-You can run `git branchto see which branch you're on, and what other branches are available and `git branch -a` shows remote branches and origin master branch for this repository.+You can run "**git branch**" ​to see which branch you're on:
  
 <​code>​ <​code>​
Line 114: Line 139:
 * master * master
 </​code>​ </​code>​
 +
 +In this case, there is only one branch, called master. The star indicates that the "​master"​ branch is the one you are currently on. In git speak, we say that you currently have the master branch "​checked out".
 +
 +You can also use the git branch command to show branches on the staging remote repository. Run the "**git branch -a**" command:
 +
 <​code>​ <​code>​
 $ git branch -a $ git branch -a
 * master * master
   remotes/​origin/​HEAD -> origin/​master   remotes/​origin/​HEAD -> origin/​master
 +  remotes/​origin/​bus_cleanup
   remotes/​origin/​master   remotes/​origin/​master
 +  remotes/​origin/​staging-linus
 +  remotes/​origin/​staging-next
 +  remotes/​origin/​staging-testing
 </​code>​ </​code>​
  
-In this case, there is only one branch, ​called ​masterThe star indicates ​that the "master" branch ​is the one you are currently ​on. In git speakwe say that you currently ​have the master branch ​"checked out".+The first remote repository that is used to create the git checkout ​is called ​"​origin"​ For now, just remember ​that "origin" ​means Greg Kroah-Hartman'​s staging git repository. ​ Here, you can see the staging remote has five branches: master, staging-linus,​ staging-next,​ staging-testing,​ and test. The staging-linus ​branch ​contains bug fix patches for the current kernel release candidate, and the staging-next branch contains patches for the next kernel release. ​ Your patches will all go into staging-testing (since they will be code clean up, not bug fixes), so you want to base all your branches ​on the staging-testing branchGreg first applies patches to staging-testing. They are moved to staging-next shortly thereafter. 
 + 
 + 
 +Let's checkout staging-testing 
 + 
 +<​code>​ 
 +git checkout staging-testing 
 +Branch '​staging-testing'​ set up to track remote branch '​staging-testing'​ from '​origin'​. 
 +Switched to a new branch '​staging-testing'​ 
 +</​code>​ 
 + 
 +Now if you run git branchyou'll see that there are two branches, and you are currently ​on the "staging-testing" ​branch: 
 + 
 +<​code>​ 
 +git branch 
 +  master 
 +* staging-testing 
 +</​code>​
  
 Create a new branch called '​first-patch',​ and checkout that branch by running: Create a new branch called '​first-patch',​ and checkout that branch by running:
Line 130: Line 181:
 </​code>​ </​code>​
  
-Now if you run git branch, you'll see that there are two branches, and you are currently on the "​first-patch"​ branch:+Now if you run git branch, you'll see that there are three branches, and you are currently on the "​first-patch"​ branch:
  
 <​code>​ <​code>​
Line 136: Line 187:
 * first-patch * first-patch
   master   master
 +  staging-testing
 </​code>​ </​code>​
  
-You can also use the git branch ​command to show branches ​on the staging ​remote repository. ​ Run the command:+The first commit in the first-branch ​based on staging-testing is:
  
-{{{ +<​code>​ 
-intern@ubuntu:​~/​git/​kernels/​staging$ git branch ​-a +git log -1 --pretty=oneline ​--abbrev-commit 
-first-patch +932f98922f6f (HEAD -> first-patch, origin/staging-testingorigin/staging-next, staging-testing) Merge tag '​iio-for-5.2a-2'​ of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next 
-  ​staging-testing +</code>
-  remotes/origin/HEAD -> origin/master +
-  remotes/origin/master +
-  remotes/origin/staging-linus +
-  remotes/origin/staging-next +
-  remotes/origin/staging-testing +
-  ​remotes/origin/​test}}}+
  
-The first remote repository that is used to create the git checkout is called "​origin"​. ​ For now, just remember that "​origin"​ means Greg Kroah-Hartman'​s staging git repository. ​ Here, you can see the staging remote has five branches: master, staging-linus,​ staging-next,​ staging-testing,​ and test.  The staging-linus branch contains bug fix patches for the current ​kernel ​release candidate, and the staging-next branch contains patches for the next kernel release. ​ Your patches will all go into staging-testing (since they will be code clean up, not bug fixes), so you want to base all your branches on the staging-testing branch. ​ Greg first applies patches to staging-testing. ​ They are moved to staging-next shortly thereafter.+==== Update your kernel ​====
  
-= Update your kernel = 
 When you create your first application clean-up patches, you want to create them on top of the latest commit from the staging-testing tree.  If your patch is out-of-date and doesn'​t apply to the latest tree, it may be rejected. ​ You'll need to use git to fetch the latest changes: When you create your first application clean-up patches, you want to create them on top of the latest commit from the staging-testing tree.  If your patch is out-of-date and doesn'​t apply to the latest tree, it may be rejected. ​ You'll need to use git to fetch the latest changes:
  
-{{{ +<​code>​ 
-git fetch origin}}}+git fetch origin 
 +</​code>​
  
 The third word in that command is the name of the remote repository you are fetching from.  In this case, it's origin, which is the remote repository we initially cloned from (the staging repository). The third word in that command is the name of the remote repository you are fetching from.  In this case, it's origin, which is the remote repository we initially cloned from (the staging repository).
Line 163: Line 209:
 That command will fetch the changes from the remote, but it won't actually change in files in the working copy (i.e. the files in this directory). ​ If you run: That command will fetch the changes from the remote, but it won't actually change in files in the working copy (i.e. the files in this directory). ​ If you run:
  
-{{{ +<​code>​ 
-git log}}}+git log 
 +git log -1 --pretty=oneline --abbrev-commit 
 +932f98922f6f (HEAD -> first-patch,​ origin/​staging-testing,​ origin/​staging-next,​ staging-testing) Merge tag '​iio-for-5.2a-2'​ of git://​git.kernel.org/​pub/​scm/​linux/​kernel/​git/​jic23/​iio into staging-next 
 +</​code>​
  
-You will see that your current working directory still points to the original commit. ​ So where are the staging tree current changes?+You will see that your current working directory still points to the original commit. So where are the staging tree current changes?
  
-The answer is that git stores the changes in a special hidden directory called ​{{{.git}}} You can view the history of the staging repository by giving git log the "​staging-testing"​ branch of the "​origin"​ remote repository:+The answer is that git stores the changes in a special hidden directory called .git. You can view the history of the staging repository by giving git log the "​staging-testing"​ branch of the "​origin"​ remote repository:
  
-{{{ +<​code>​ 
-git log origin/​staging-testing}}}+git log origin/​staging-testing 
 +</​code>​
  
-Next, we need to update our branch to include the changes in the staging tree.  The safest way to do this is to "​rebase"​ your branch. ​ This means that if you have any commits on your branch, they will be placed on top of the staging tree commits. ​ Sometimes you may have to edit your commits if there are conflicts, but you should ask your mentor for help with this.  For now, run:+Next, we need to update our branch to include the changes in the staging tree. The safest way to do this is to "​rebase"​ your branch. ​ This means that if you have any commits on your branch, they will be placed on top of the staging tree commits. ​ Sometimes you may have to edit your commits if there are conflicts, but you should ask your mentor for help with this.  For now, run:
  
-{{{ +<​code>​ 
-git rebase origin/​staging-testing}}}+git rebase origin/​staging-testing 
 +</​code>​
  
-If you run {{{`git log`}}} to show your staging branch history and then {{{`git log origin/​staging-testing`}}} to show the staging-testing branch history, you should see that they have exactly the same commits.+If you run "**git log**" ​to show your staging branch history and then "**git log origin/​staging-testing**" ​to show the staging-testing branch history, you should see that they have exactly the same commits.
  
-== Configure the kernel ==+==== Configure the kernel ​====
 The next step is to create a configuration file, compile the new kernel, and install it. The next step is to create a configuration file, compile the new kernel, and install it.
  
-The first thing to know is that the Linux kernel is completely configurable. ​ Each driver can be separately configured to be installed or not.  There are three choices for driver installation:​+The first thing to know is that the Linux kernel is completely configurable. Each driver can be separately configured to be installed or not. There are three choices for driver installation:​
  
- * disable the driver completely,​ +  ​* disable the driver completely,​ 
- * build the driver into the main kernel file (vmlinuz), +  * build the driver into the main kernel file (vmlinux), 
- * or build it as a module.+  * or build it as a module.
  
-If you build the driver into the main kernel file, it will be loaded at boot time.  The downside is that the kernel will have to load more code at boot for drivers that may not even correspond to hardware on the system. ​ To avoid this, kernel developers often compile drivers as "​modules"​. ​ A module is a stand-alone .ko driver file that is loaded when the kernel detects hardware that matches the driver. ​ For example, you could configure your wifi driver as a module, and the kernel will load it when it detects the wifi card.+If you build the driver into the main kernel file, it will be loaded at boot time. The downside is that the kernel will have to load more code at boot for drivers that may not even correspond to hardware on the system. To avoid this, kernel developers often compile drivers as "​modules"​. A module is a stand-alone .ko driver file that is loaded when the kernel detects hardware that matches the driver. ​ For example, you could configure your wifi driver as a module, and the kernel will load it when it detects the wifi card.
  
-The Linux kernel make system uses a special file called ​{{{.config}}} that stores what drivers are compiled in, or compiled as modules. ​ Most Linux distributions store the .config file they used to compile your distro kernel in the /boot/ directory:+The Linux kernel make system uses a special file called .config that stores what drivers are compiled in, or compiled as modules. ​ Most Linux distributions store the .config file they used to compile your distro kernel in the /boot/ directory:
  
-{{{ +<​code>​ 
-intern@ubuntu:​~/​git/​kernels/​staging$ ls /boot/ +$ ls /boot 
-System.map-4.8.0-2-amd64  System.map-4.9.0-rc8-amd64  ​config-4.9.0-1-amd64    grub                      initrd.img-4.9.0-1-amd64    lost+found ​            ​vmlinuz-4.9.0-1-amd64 +config-4.18.0-15-generic ​     memtest86+.bin 
-System.map-4.9.0-1-amd64  config-4.8.0-2-amd64        config-4.9.0-rc8-amd64  initrd.img-4.8.0-2-amd64  ​initrd.img-4.9.0-rc8-amd64  ​vmlinuz-4.8.0-2-amd64  ​vmlinuz-4.9.0-rc8-amd64 +config-4.18.0-16-generic ​     memtest86+.elf 
-}}}+config-4.18.0-17-generic ​     memtest86+_multiboot.bin 
 +efi                           ​System.map-4.18.0-15-generic 
 +grub                          System.map-4.18.0-16-generic 
 +initrd.img-4.18.0-15-generic ​ System.map-4.18.0-17-generic 
 +initrd.img-4.18.0-16-generic ​ vmlinuz-4.18.0-15-generic 
 +initrd.img-4.18.0-17-generic ​ ​vmlinuz-4.18.0-16-generic 
 +lost+found ​                   ​vmlinuz-4.18.0-17-generic 
 +</​code>​
  
-You can duplicate the distro'​s configuration by copying one of the config-* files to a .config file in your git tree.  This has already been done for you in the VM image.+You can duplicate the distro'​s configuration by copying one of the **config-*** files to a **.config** file in your git tree.
  
 You can read more about configuring a kernel [[http://​www.linuxjournal.com/​content/​kbuild-linux-kernel-build-system|here]]. You can read more about configuring a kernel [[http://​www.linuxjournal.com/​content/​kbuild-linux-kernel-build-system|here]].
  
-== Compile the kernel == +==== Compile the kernel ​==== 
-Next, you'll need to run {{{make}}} to compile your new kernel. ​ Optionally, make can take a flag that indicates how many threads to spawn to start separate compilations. ​ Usually you want to pick a number that is equal to the number of CPUs you have in your machine. ​ For example, if you had a dual core system, you would run:+Next, you'll need to run "**make**" ​to compile your new kernel. Optionally, make can take a flag that indicates how many threads to spawn to start separate compilations. Usually you want to pick a number that is equal to the number of CPUs you have in your machine. ​ For example, if you had a dual core system, you would run:
  
-{{{ +<​code>​ 
-make -j2}}}+make -j2 
 +</​code>​
  
-That may take a while. ​ I would suggest reading some of the [[http://​lwn.net/​Kernel/​LDD3/​|Linux Device Drivers book]] ​while you're waiting.+That may take a while. ​While you waiting, please read the [[http://​lwn.net/​Kernel/​LDD3/​|Linux Device Drivers book]] ​to get ready for the next step.
  
-= Make a driver change =+==== Make a driver change ​=====
 These next couple of steps will allow you to make a change to a driver, and test that you've correctly compiled and installed the modified driver. These next couple of steps will allow you to make a change to a driver, and test that you've correctly compiled and installed the modified driver.
  
-== Modifying a driver ​under the VM ==+==== Modifying a driver ​on native Linux ==== 
 +Your native Linux system will have many different drivers. Find out which drivers are loaded on your system, and modify one of them.
  
-If you are running Linux in a VMfollow these directions. ​ Otherwise, if you are running Linux natively on your machinego to the next section.+Firstuse "​**lsmod**"​ to see what drivers ​are loadedand pick a name from that list to modify. This example shows making changes ​to uvcvideo.
  
-One driver that's included in all VM images is the e1000 driver, ​the Intel ethernet driver. ​ If you're running Linux natively, you will need to find a different ​driver.  ​See the next driver section for how to find an appropriate ​driver.+Once you have the name of a driver, ​it's time to find out where the .c and .h files for that driver ​are in the Linux kernel repository.  ​You can do that by searching through ​the Makefiles ​to find out what C files are compiled into the driver ​binary. The best way to do that is with "**git grep**"​. Unlike normal grep, git grep only searches through checked-in files in the repository. Normal grep will also search the binary files, and even the .git directory, which isn't useful and wastes your time.
  
-The e1000 driver is found in the networking portion of the kernel:+For example, if you wanted to search for the files that are compiled into the uvcvideo driver, you would run this command:
  
-{{{ +<​code>​ 
-intern@ubuntu:​~/​git/​kernels/​stagingls drivers/net/ethernet/intel/e1000/ +git grep uvcvideo -- '​*Makefile'​ 
-e1000_ethtool.c ​ e1000.h  e1000_hw.c  e1000_hw.h  e1000_main.c  e1000_osdep. e1000_param.c  ​Makefile ​}}}+drivers/media/usb/uvc/Makefile:​uvcvideo-objs ​ := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \ 
 +drivers/​media/​usb/​uvc/​Makefile:​uvcvideo-objs ​ += uvc_entity.
 +drivers/​media/​usb/​uvc/​Makefile:​obj-$(CONFIG_USB_VIDEO_CLASS) += uvcvideo.o 
 +</​code>​
  
-Let's make small change to the probe function of the e1000 driver. ​ A probe function is called when the driver is loaded. ​ Let's edit e1000_main.c:​+uvcvideo is media usb driver.
  
-{{{ +<​code>​ 
-vim drivers/net/ethernet/intel/e1000/​e1000_main.c}}}+ls drivers/media/usb/uvc/ 
 +Kconfig ​    ​uvc_debugfs.c  ​uvc_isight.c ​   uvc_status.c ​ uvcvideo.h 
 +Makefile ​   uvc_driver.c ​  ​uvc_metadata.c ​ uvc_v4l2.c 
 +uvc_ctrl.c ​ uvc_entity.c ​  ​uvc_queue.c ​    ​uvc_video.c 
 +</​code>​
  
-Next, find the probe function. ​ You can search for text by typing '/'​ in standard mode.  ​Once you'​ve ​found the probe functionadd printk line to it:+Once you'​ve ​identified ​the files for your driverlet's make small change ​to the probe function of the uvcvideo driver. A probe function is called when the driver is loaded. Let's edit uvc_driver.c:
  
-{{{ +<​code>​ 
-static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { +vim drivers/​media/​usb/​uvc/​uvc_driver.c 
-         struct net_device *netdev; +</​code>​
-         ​struct e1000_adapter *adapter; +
-         ​struct e1000_hw *hw;+
  
-         ​printk(KERN_DEBUG "I can modify ​the Linux kernel!\n"​)+Find the probe function by searching for _probe text by typing '/'​ in standard mode. Once you've found the probe function, add pr_info(to it:
-         ​static int cards_found = 0; +
-}}}+
  
-Then type {{{:​wq<​enter>}}} to save the file and quit.+<​code>​ 
 +static int uvc_probe(struct usb_interface *intf, 
 +                     const struct usb_device_id *id) 
 +{ 
 +        struct usb_device *udev = interface_to_usbdev(intf);​ 
 +        struct uvc_device *dev; 
 +        const struct uvc_device_info *info = 
 +                (const struct uvc_device_info *)id->driver_info;​ 
 +        int function; 
 +        int ret;
  
-A printk function causes a message to be written to the kernel log bufferwhich can then be viewed using the {{{dmesg}}} command.+        pr_info("​I changed uvcvideo driver in the Linux Kernel\n"​);​ 
 +         
 +        if (id->​idVendor && id->​idProduct) 
 +                uvc_trace(UVC_TRACE_PROBE"​Probing known UVC device %s " 
 +                                "​(%04x:​%04x)\n",​ udev->​devpath,​ id->​idVendor,​ 
 +                                id->​idProduct);​ 
 +        else 
 +                uvc_trace(UVC_TRACE_PROBE,​ "​Probing generic UVC device %s\n",​ 
 +                                udev->​devpath);​ 
 +</​code>​
  
-== Modifying a driver on native Linux == +Then type **:​wq<​enter>​** to save the file and quit.
-Your native Linux system will have many different drivers than the ones loaded on a Linux system running in VMPlayer. ​ You will not necessarily have hardware that the e1000 driver can run on.  Instead, you must find out which drivers are loaded on your system, ​and modify one of them.+
  
-First, use {{{lsmod}}} to see what drivers are loaded, and pick name from that list to modify. ​ If you have a variant of the e1000 driverlike e1000e, you may want to use that.  Or you can find your wireless driver and modify that.+A pr_info() function causes ​message to be written ​to the kernel log bufferwhich can then be viewed using the "​**dmesg**"​ command.
  
-Once you have the name of a driverit's time to find out where the .c and .h files for that driver are in the Linux kernel repository. ​ You can do that by searching through the Makefiles ​to find out what C files are compiled into the driver binary. ​ The best way to do that is with {{{`git grep`}}}. ​ Unlike normal grep, git grep only searches through checked-in files in the repository. ​ Normal grep will also search the binary files, and even the .git directory, which isn't useful and wastes your time.+Now edit drivers/​media/​usb/​uvc/​uvc_video.c, find the _prove function ​and add a pr_info() ​to it.
  
-For example, if you wanted to search for the files that are compiled into the xhci-hcd driver, you would run this command:+<​code>​ 
 +vim drivers/​media/​usb/​uvc/​uvc_video.c 
 +</​code>​
  
-{{{ +<​code>​ 
-git grep xhci-hcd -- '*Makefile'​}}}+int uvc_probe_video(struct uvc_streaming ​*stream, 
 +        struct uvc_streaming_control *probe) 
 +
 +        struct uvc_streaming_control probe_min, probe_max;​ 
 +        u16 bandwidth;​ 
 +        unsigned int i; 
 +        int ret;
  
-Once you've identified the files for your driver, you will need to make a change to the probe function as described ​in the previous section.+        pr_info("​I changed uvcvideo ​driver in the Linux Kernel\n"​);​
  
-== Compile your changes == +        /* Perform probing. The device should adjust the requested values 
-Recompile your kernelby running {{{make}}} ​(with an optional {{{-jN}}} flag):+         * according to its capabilities. Howeversome devices, namely the 
 +         * first generation UVC Logitech webcams, don't implement the Video 
 +         * Probe control properly, and just return the needed bandwidth. For 
 +         * that reason, if the needed bandwidth exceeds the maximum available 
 +         * bandwidth, try to lower the quality. 
 +         */ 
 +        ret = uvc_set_video_ctrl(stream, probe, 1)
 +        if (ret < 0) 
 +                goto done;
  
-{{{ +</​code>​
-make -j2}}}+
  
-You may need to fix some compilation errors. ​ Also fix any new warnings that are due to your changes. ​ In the Linux kernel, we strive to make sure that drivers do not produce warnings on anyone'​s system (this includes 32-bit ​and 64-bit systems, as well as different architectures,​ such as PPC, ARM, or x86).  New features or bug fix patches that add additional warnings may not get merged.+Then type **:​wq<​enter>​** ​to save the file and quit.
  
-== Install your changes ==+A pr_info() function causes a message to be written to the kernel log buffer, which can then be viewed using the "​**dmesg**"​ command. 
 + 
 +==== Compile your changes ==== 
 + 
 +Recompile your kernel, by running **make (with an optional -jN flag)**: 
 + 
 +<​code>​ 
 +make -j2 
 +</​code>​ 
 + 
 +You may need to fix some compilation errors. Also fix any new warnings that are due to your changes. ​ In the Linux kernel, we strive to make sure that drivers do not produce warnings on anyone'​s system (this includes 32-bit and 64-bit systems, as well as different architectures,​ such as PPC, ARM, or x86). New features or bug fix patches that add additional warnings may not get merged. Please read the [[https://​www.kernel.org/​doc/​html/​latest/​process/​submit-checklist.html|Linux Kernel patch submission checklist]] to understand what Linux kernel maintainers expect patch authors to do before sending the patch. 
 + 
 +==== Install your changes ​====
 After you've compiled the driver, you need to install your changes by running: After you've compiled the driver, you need to install your changes by running:
  
-{{{ +<​code>​ 
-sudo make modules_install install}}}+sudo make modules_install install 
 +</​code>​
  
-== Test your changes == +==== Test your changes ​==== 
-Since you've compiled a completely new kernel, you need to reboot into that new kernel in order to test your module changes. ​ Reboot your VM (or computer), and then run:+Since you've compiled a completely new kernel, you need to reboot into that new kernel in order to test your module changes. Reboot your system, and then run:
  
-{{{ +<​code>​ 
-dmesg | less}}}+dmesg | less 
 +</​code>​
  
-Search for your printk ​in the log file by typing "/​I ​can modify"​. ​ You should be able to find this message within the driver output during boot.  If you don't see this message, ask for help on the #kernel-outreachy ​IRC channel ​on irc.oftc.net, or on the [[https://​groups.google.com/​forum/#​!forum/​outreachy-kernel|outreachy-kernel ​mailing list]]+Search for your pr_info ​in the log file by typing "**/I changed**". You should be able to find this message within the driver output during boot. If you don't see this message, ask for help on the #linux-kernel-mentees ​IRC Channel ​on [[https://​freenode.net/​|freenode]] ​irc.freenode.net, or on the linux-kernel-mentees ​mailing list
  
-== Revert your changes == +==== Revert your changes ​==== 
-Since that was just a simple test, and you probably don't want to commit that change, you can revert your changes. ​ Exit out of your editor by typing {{{:​q<​enter>​}}} and running this command:+Since that was just a simple test, and you probably don't want to commit that change, you can revert your changes.
  
-{{{ +<​code>​ 
-git reset --hard HEAD}}}+git reset --hard HEAD 
 +</​code>​
  
-That will revert ​'''​ALL FILES''' ​in your current working directory to the last known commit (the HEAD commit), wiping out all your uncommited ​changes. ​ Read the git reset manual for more information on ways to reset the state for specific files.+That will revert ​**ALL FILES** in your current working directory to the last known commit (the HEAD commit), wiping out all your uncommitted ​changes. ​ Read the git reset manual for more information on ways to reset the state for specific files.
  
-= Start creating your first patch =+==== Start creating your first patch ====
 Next, you'll get to do some useful modifications to the kernel, create your first git commit, and send out your first patch. ​ Before you make your first commit using git, you'll need to do some setup. Next, you'll get to do some useful modifications to the kernel, create your first git commit, and send out your first patch. ​ Before you make your first commit using git, you'll need to do some setup.
  
-== Git post-commit hooks == +==== Git post-commit hooks ==== 
-Git includes some "​hooks"​ for scripts that can be run before or after specific git commands are executed. ​ The "​post-commit"​ hook is run after you make a git commit with the {{{`git commit`}}} command.+Git includes some "​hooks"​ for scripts that can be run before or after specific git commands are executed. ​ The "​post-commit"​ hook is run after you make a git commit with the "**git commit**" ​command.
  
-Linux kernel developers ​have very stringent guidelines for [[http://elixir.free-electrons.com/linux/latest/source/​Documentation/​process/​coding-style.rst|coding style]]. ​ ​They'​re so pickythey created a script called ​[[http://lxr.free-electrons.com/source/​scripts/​checkpatch.pl|checkpatch.pl]] that you can run over your patches to make sure the patch complies with the kernel coding style.+Linux kernel developers ​follow ​[[https://www.kernel.org/doc/html/latest/​process/​coding-style.html|Linux kernel ​coding style]]. ​Once you made changesyou can run [[https://git.kernel.org/​pub/​scm/​linux/​kernel/​git/​torvalds/​linux.git/tree/​scripts/​checkpatch.pl|checkpatch.pl]] that you can run over your patches to make sure the patch complies with the kernel coding style.
  
-To ensure that you create good commits that comply with the coding style, you can run checkpatch.pl over your commit with the "​post-commit"​ hook.  Note that running checkpatch after the commit, checks the patch file you've created - not just the source code diff.  Therefore it will catch more issues - spelling errors in log messages, spacing in log messages, warnings about adding/​removing files, etc.+To ensure that you create good commits that comply with the coding style, you can run checkpatch.pl over your commit with the "​post-commit"​ hook. Note that running checkpatch after the commit, checks the patch file you've created - not just the source code diff.  Therefore it will catch more issues - spelling errors in log messages, spacing in log messages, warnings about adding/​removing files, etc.
  
-If you already have a {{{.git/​hooks/​post-commit}}} file, move it to {{{.git/​hooks/​post-commit.sample}}} git will not execute files with the .sample extension.+If you already have a .git/​hooks/​post-commit file, move it to .git/​hooks/​post-commit.sample. git will not execute files with the .sample extension.
  
-Then edit the {{{.git/​hooks/​post-commit}}} file to contain only the following two lines:+Then edit the .git/​hooks/​post-commit file to contain only the following two lines:
  
-{{{#!bash+<​code>​ 
 +#!bash
 #!/bin/sh #!/bin/sh
-exec git show --format=email HEAD | ./​scripts/​checkpatch.pl --strict --codespell}}}+exec git show --format=email HEAD | ./​scripts/​checkpatch.pl --strict --codespell 
 +</​code>​
  
 Make sure the file is executable: Make sure the file is executable:
  
-{{{ +<​code>​ 
-chmod a+x .git/​hooks/​post-commit}}}+chmod a+x .git/​hooks/​post-commit 
 +</​code>​
  
 If you don't already have /​usr/​share/​codespell/​dictionary.txt,​ get it: If you don't already have /​usr/​share/​codespell/​dictionary.txt,​ get it:
  
-{{{ +<​code>​ 
-apt-get install codespell}}}+apt-get install codespell 
 +</​code>​
  
-After you commit, this hook will output any checkpatch errors or warnings that your patch creates. ​ If you see warnings or errors that you know you added, you can amend the commit by changing the file, using {{{git add}}} to add the changes, and then using {{{git commit --amend}}} to commit the changes.+After you commit, this hook will output any checkpatch errors or warnings that your patch creates. ​ If you see warnings or errors that you know you added, you can amend the commit by changing the file, using "**git add**" ​to add the changes, and then using "**git commit --amend**" ​to commit the changes.
  
-== Checking that the post-commit hook works == +==== Checking that the post-commit hook works ==== 
-You can check that the post-commit hook is working by adding a deliberate change that will trigger checkpatch (such as adding a really long line or adding trailing whitespace to a line), and then attempting to run `git commit` After you commit, you should see the additional checkpatch.pl warning or error.+You can check that the post-commit hook is working by adding a deliberate change that will trigger checkpatch (such as adding a really long line or adding trailing whitespace to a line), and then attempting to run "**git commit**". After you commit, you should see the additional checkpatch.pl warning or error.
  
 Note that you will need to place this hook in any/every tree in which you build patches. Note that you will need to place this hook in any/every tree in which you build patches.
Line 328: Line 442:
 If your post-commit hook is not working, please ask for help on IRC. If your post-commit hook is not working, please ask for help on IRC.
  
-= Understand patch best practices =+==== Understand patch best practices ​=====
 Before you create your patch, you need to understand how to create good patches. ​ Otherwise your patches will be less likely to be accepted by maintainers,​ and you will have to go through more revisions than necessary. Before you create your patch, you need to understand how to create good patches. ​ Otherwise your patches will be less likely to be accepted by maintainers,​ and you will have to go through more revisions than necessary.
  
-First, read about PatchPhilosophy That document will help you create ​patches ​that are easy to read, and have better chance ​of being applied by maintainers ​Please also read [[http://elixir.free-electrons.com/linux/latest/​source/​Documentation/process/coding-style.rst|CodingStyle]] (which ​is also available in the kernel code repository under Documentation). ​ This will help you understand how to write code that the Linux kernel ​community will accept, and the rules here are the basis for the script checkpatch.pl.+The [[https://​www.kernel.org/​doc/​html/​latest/​process/​submitting-patches.html|Submitting patches: the essential guide to getting your code into the kernel]] is collection of suggestions which can greatly increase the chances ​of your change ​being accepted. [[https://www.kernel.org/doc/html/​latest/​process/​development-process.html|A guide to the Kernel Development Process]] is a comprehensive guide to all aspects of the kernel ​development process.
  
-Note that checkpatch.pl ​is failable Use your best judgement when deciding whether it makes sense to make the change checkpatch.pl suggests. ​ The end goal is for the code to be more readable. ​ If checkpatch.pl suggests a change and you think the end result is not more readable, don't make the change. ​ For example, if a line is 81 characters long, but breaking it makes the resulting code look ugly, don't break that line.  Please read the CheckpatchTips page for how to avoid common mistakes when cleaning up drivers.+Note that checkpatch.pl ​might suggest changes that are unnecessary! Use your best judgement when deciding whether it makes sense to make the change checkpatch.pl suggests. The end goal is for the code to be more readable. ​ If checkpatch.pl suggests a change and you think the end result is not more readable, don't make the change. ​ For example, if a line is 81 characters long, but breaking it makes the resulting code look ugly, don't break that line.
  
-= Find a driver to clean up = +==== Find a driver to clean up ===
-The staging tree, in {{{drivers/​staging/​}}} is full of drivers that are not quite up to kernel coding style, or that use deprecated API.  Drivers get placed here in order to get cleaned up.  Some drivers have a TODO file in their parent directory, that lists things that need to be done to it:+The staging tree, in drivers/​staging/​ is full of drivers that are not quite up to kernel coding style, or that use deprecated API.  Drivers get placed here in order to get cleaned up.  Some drivers have a TODO file in their parent directory, that lists things that need to be done to it:
  
-{{{ +<​code>​ 
-find drivers/​staging -name TODO}}}+find drivers/​staging -name TODO 
 +</​code>​
  
 You can either tackle one of those TODO items, or you can do a simple coding style cleanup. You can either tackle one of those TODO items, or you can do a simple coding style cleanup.
  
-drivers/​staging contains both drivers that are on their way into the kernel and those that are on their way out of the kernel. ​ It would be better to avoid working on the latter. ​ Some drivers that are on their way out of the kernel as of February 2015 are+drivers/​staging contains both drivers that are on their way into the kernel and those that are on their way out of the kernel. It would be better to avoid working on the latter.
  
-{{{ +==== Running checkpatch.pl ​====
-i2o +
-line6 +
-media/​parport +
-media/​tlg2300 +
-media/​vino +
-}}} +
- +
-== Running checkpatch.pl ==+
 If you pick a driver in staging, you can run the script that checks whether a file conforms to kernel coding style: If you pick a driver in staging, you can run the script that checks whether a file conforms to kernel coding style:
  
-{{{ +<​code>​ 
-perl scripts/​checkpatch.pl -f drivers/​staging/​android/​* | less}}}+perl scripts/​checkpatch.pl -f drivers/​staging/​android/​* | less 
 +</​code>​
  
-Pick a warning, and try to fix it.  For your first patch, only pick one warning. ​ In the future you can group multiple changes into one patch, but only if you follow ​the PatchPhilosophy of breaking each patch into logical changes.+Pick a warning, and try to fix it. For your first patch, only pick one warning. In the future you can group multiple changes into one patch after reading ​the  ​[[https://​www.kernel.org/​doc/​html/​latest/​process/​5.Posting.html#​patch-preparation|Patch preparation]] and understanding how to break a patch into logical changes.
  
 Note that there is a lot of variation in the warnings generated by checkpatch. ​ Sometimes the code is clearly not ideal and the fix is obvious. ​ Other cases might be a matter of personal preference, or might require specialized knowledge about the code to make the correct change. ​ It may be helpful to look back at old messages on the mailing list, to see if a similar change has been rejected, and why. Note that there is a lot of variation in the warnings generated by checkpatch. ​ Sometimes the code is clearly not ideal and the fix is obvious. ​ Other cases might be a matter of personal preference, or might require specialized knowledge about the code to make the correct change. ​ It may be helpful to look back at old messages on the mailing list, to see if a similar change has been rejected, and why.
  
-'''​Please avoid sending patches for the Licence related checkpatch.pl warnings. It requires lot more discussion by driver authors and companies before doing so and is not often preferred by maintainers to accept them when sent by newbies'''​+**Please avoid sending patches for the Licence related checkpatch.pl warnings**. It requires lot more discussion by driver authors and companies before doing so and is not often preferred by maintainers to accept them when sent by newbies.
  
-In addition to checkpatch cleanups, you can also try other bug finding tools in the kernel. ​ Here is some information on using [[https://​github.com/​nerdyvaishali/​Talks/​blob/​master/​LinuxCon_Japan/​Introduction%20to%20Coccinelle.pdf|Coccinelle]] +==== Recompiling the driver ​====
- +
-== Recompiling the driver ==+
 You'll need to make sure the driver you're changing is configured as a module. ​ Run: You'll need to make sure the driver you're changing is configured as a module. ​ Run:
  
-{{{ +<​code>​ 
-make menuconfig}}}+make menuconfig 
 +</​code>​
  
 This opens up a text-based GUI that allows you to explore the configuration options. This opens up a text-based GUI that allows you to explore the configuration options.
  
-Use the arrow keys to go to {{{Device Drivers -> }}} and hit <​enter>​. Then go down to {{{Staging drivers}}} At any time, you can hit '?',​ which will show you the help text for that kernel configuration option. ​ You can search for the driver you're modifying by '/',​ in order to get the driver'​s longer name. Make sure the driver you're working on is compiled as a module ('​M'​),​ instead of being built-in ('​*'​). ​ You can change a driver to being compiled as a module by typing '​m'​ when the driver is selected in the menu.  Hitting <​enter>​ will change the driver to being built-in.+Use the arrow keys to go to Device Drivers -> and hit <​enter>​. Then go down to Staging drivers. At any time, you can hit '?',​ which will show you the help text for that kernel configuration option. ​ You can search for the driver you're modifying by '/',​ in order to get the driver'​s longer name. Make sure the driver you're working on is compiled as a module ('​M'​),​ instead of being built-in ('​*'​). ​ You can change a driver to being compiled as a module by typing '​m'​ when the driver is selected in the menu.  Hitting <​enter>​ will change the driver to being built-in.
  
 Once you've enabled the driver you're modifying, use <tab> or the right arrow key to move the cursor from '​Select'​ to '​Exit'​ and hit <​enter>​. ​ Continue to do this until you get to the main menu.  When it asks you to save your configuration,​ chose '​Yes'​. Once you've enabled the driver you're modifying, use <tab> or the right arrow key to move the cursor from '​Select'​ to '​Exit'​ and hit <​enter>​. ​ Continue to do this until you get to the main menu.  When it asks you to save your configuration,​ chose '​Yes'​.
Line 381: Line 488:
 Then recompile the kernel with: Then recompile the kernel with:
  
-{{{ +<​code>​ 
-make -j2}}}+make -j2 
 +</​code>​
  
-You should reboot your kernel, load the driver with {{{modprobe}}}.  You'll be able to see that the driver is loaded by running ​{{{lsmod}}}.  Loading the driver at least makes sure that the driver probe function works.+You should reboot your kernel, load the driver with "**modprobe**".  You'll be able to see that the driver is loaded by running ​"**lsmod**".  Loading the driver at least makes sure that the driver probe function works.
  
- '''​Note:''' ​Do not work on drivers that show that they depend on CONFIG_BROKEN. ​ If you search for a driver after running ​{{{`make menuconfig`}}}, and you notice the "​Depends on:" line includes BROKEN, do not work on this driver.+**Note:** Do not work on drivers that show that they depend on CONFIG_BROKEN. ​ If you search for a driver after running ​"**make menuconfig**", and you notice the "​Depends on:" line includes BROKEN, do not work on this driver.
  
-== Compiling only part of the kernel ==+==== Compiling only part of the kernel ​====
  
 There are several ways to compile only part of the kernel: There are several ways to compile only part of the kernel:
Line 394: Line 502:
  * make path/​file.o:​ This compiles only a single file.  It may not be sufficient to check changes that affect interactions with other files. It is possible to build files that are disabled in .config this way, but that can fail in some cases, e.g. when the file includes architecture-specific headers.  * make path/​file.o:​ This compiles only a single file.  It may not be sufficient to check changes that affect interactions with other files. It is possible to build files that are disabled in .config this way, but that can fail in some cases, e.g. when the file includes architecture-specific headers.
  
- * make path, e.g. {{{make drivers/​staging}}}: This always succeeds. It does nothing at all because the directory exists.+ * make path, e.g. make drivers/​staging:​ This always succeeds. It does nothing at all because the directory exists.
  
- * make path/, e.g. {{{make drivers/​staging/​}}}: This descends into that directory to build all the files in it, but does not try to link the modules.+ * make path/, e.g. make drivers/​staging/:​ This descends into that directory to build all the files in it, but does not try to link the modules.
  
- ​* ​{{{make M=drivers/​staging}}}: This seems to try to link the modules in a previously build vmlinux file. After changing options in .config or rebasing on a newer git tree, this can fail unless all other files are built once using {{{make -j2}}}.+ * make M=drivers/​staging:​ This seems to try to link the modules in a previously build vmlinux file. After changing options in .config or rebasing on a newer git tree, this can fail unless all other files are built once using make -j2.
  
-Make path/ could be a reasonable choice for a localized change within a single driver, or for a change localized to drivers staging. ​ In any case, as a minimum always check that compilation produces a .o file for every file that your patch changes. ​ If there is no .o file, you have not compiled the file, and you need to look for other compiler options.+Make path/ could be a reasonable choice for a localized change within a single driver, or for a change localized to drivers staging. In any case, as a minimum always check that compilation produces a .o file for every file that your patch changes. ​ If there is no .o file, you have not compiled the file, and you need to look for other compiler options.
  
-== Driver dependencies == +==== Driver dependencies ​==== 
-Sometimes it's hard to find your driver. ​ Maybe you searched for the CONFIG option, but you can't find it in the menus where it should be.  This may be because a driver or subsystem it depends on is not enabled, and so this driver is hidden from the menu.  You need to enable all the dependencies in order to make the menu option visible, and then you can enable the driver you're modifying.+Sometimes it's hard to find your driver. Maybe you searched for the CONFIG option, but you can't find it in the menus where it should be.  This may be because a driver or subsystem it depends on is not enabled, and so this driver is hidden from the menu. You need to enable all the dependencies in order to make the menu option visible, and then you can enable the driver you're modifying.
  
 For example, say I was modifying drivers/​usb/​host/​xhci-ring.c. ​ If I look in the Kconfig file in the parent directory (drivers/​usb/​host/​Kconfig),​ I can see an option for the xHCI driver: For example, say I was modifying drivers/​usb/​host/​xhci-ring.c. ​ If I look in the Kconfig file in the parent directory (drivers/​usb/​host/​Kconfig),​ I can see an option for the xHCI driver:
  
-{{{+<​code>​
 config USB_XHCI_HCD config USB_XHCI_HCD
          ​tristate "xHCI HCD (USB 3.0) support"​          ​tristate "xHCI HCD (USB 3.0) support"​
Line 416: Line 524:
  
            To compile this driver as a module, choose M here: the            To compile this driver as a module, choose M here: the
-           ​module will be called xhci-hcd.}}}+           ​module will be called xhci-hcd. 
 +</​code>​
  
-Now, I run {{{`make menuconfig`}}} and type '/' ​to search for USB_XHCI_HCD. ​ The search entry shows:+Now, I run "**make menuconfig**" ​and type "**/**" ​to search for USB_XHCI_HCD. ​ The search entry shows:
  
-{{{+<​code>​
 Symbol: USB_XHCI_HCD [=m] Symbol: USB_XHCI_HCD [=m]
  ​Type ​ : tristate  ​Type ​ : tristate
Line 428: Line 537:
  ​(1) ​  -> USB support (USB_SUPPORT [=y]  ​(1) ​  -> USB support (USB_SUPPORT [=y]
    ​Defined at drivers/​usb/​host/​Kconfig:​20    ​Defined at drivers/​usb/​host/​Kconfig:​20
-   ​Depends on: USB_SUPPORT [=y] && USB [=n] && USB_ARCH_HAS_XHCI [=y])}}}+   ​Depends on: USB_SUPPORT [=y] && USB [=n] && USB_ARCH_HAS_XHCI [=y]) 
 +</​code>​
  
-Look at the "​Depends on" line.  This is a boolean equation that represents the driver dependencies that need to be enabled in order to even show the driver option in the menus. ​ A '​y'​ means the driver or subsystem is built into the kernel and an '​m'​ means the driver is built as a module. ​ Both these options are equivalent to '​1'​ in boolean logic. ​ A '​n'​ means the driver or subsystem is disabled. ​ An '​n'​ is equivalent to a '​0'​ in boolean logic.+Look at the "​Depends on" line.  This is a boolean equation that represents the driver dependencies that need to be enabled in order to even show the driver option in the menus. ​ A **'​y'​** means the driver or subsystem is built into the kernel and an '​m'​ means the driver is built as a module. ​ Both these options are equivalent to **'​1'​** in boolean logic. ​ A **'​n'​** means the driver or subsystem is disabled. An **'​n'​** is equivalent to a **'​0'​** in boolean logic.
  
- Tip: If you don't know boolean logic, you can take a look at these [[http://​www.youtube.com/​watch?​v=gj8QmRQtVao|tutorials]]. ​ If you just need a brush up on boolean logic, here's a [[http://​stackoverflow.com/​questions/​7583853/​true-and-false-for-logic-and-logic-table|crib sheet]]. ​ If you're lazy, here's a boolean algebra [[http://​www.wolframalpha.com/​examples/​BooleanAlgebra.html|calculator]],​ or you can use the "​Programming Mode" for the calculator application installed in Ubuntu by default.+Tip: If you don't know boolean logic, you can take a look at these [[http://​www.youtube.com/​watch?​v=gj8QmRQtVao|tutorials]]. ​ If you just need a brush up on boolean logic, here's a [[http://​stackoverflow.com/​questions/​7583853/​true-and-false-for-logic-and-logic-table|crib sheet]]. ​ If you're lazy, here's a boolean algebra [[http://​www.wolframalpha.com/​examples/​BooleanAlgebra.html|calculator]],​ or you can use the "​Programming Mode" for the calculator application installed in Ubuntu by default.
  
-In this case, the xHCI driver config option is not being shown in the menus because USB is set to '​n'​. ​ If I search for USB, I see lots of results, and finally find this relevant one:+In this case, the xHCI driver config option is not being shown in the menus because USB is set to **'​n'​**.  If I search for USB, I see lots of results, and finally find this relevant one:
  
-{{{+<​code>​
 Symbol: USB [=n]  ​ Symbol: USB [=n]  ​
  ​Type ​ : tristate  ​Type ​ : tristate
Line 445: Line 555:
    ​Defined at drivers/​usb/​Kconfig:​51    ​Defined at drivers/​usb/​Kconfig:​51
    ​Depends on: USB_SUPPORT [=n] && USB_ARCH_HAS_HCD [=n]    ​Depends on: USB_SUPPORT [=n] && USB_ARCH_HAS_HCD [=n]
-}}}+</​code>​
  
-If I look under the Device Drivers menu, I can find "USB Support"​ and set it to '​m'​. ​ Once that's done, I can find CONFIG_XHCI_HCD under the "USB Support"​ menu.+If I look under the Device Drivers menu, I can find "USB Support"​ and set it to **'​m'​**.  Once that's done, I can find CONFIG_XHCI_HCD under the "USB Support"​ menu.
  
 It may take recursively enabling several different configuration options before you can even see your driver in the menu.  Ask for help if you're stuck. It may take recursively enabling several different configuration options before you can even see your driver in the menu.  Ask for help if you're stuck.
  
- '''​Note:''' ​Do not work on drivers that show that they depend on CONFIG_BROKEN. ​ If you search for a driver after running ​{{{`make menuconfig`}}}, and you notice the "​Depends on:" line includes BROKEN, do not work on this driver.+Note: Do not work on drivers that show that they depend on CONFIG_BROKEN. ​ If you search for a driver after running ​"**make menuconfig**", and you notice the "​Depends on:" line includes BROKEN, do not work on this driver.
  
-== Reloading modules == +Please read [[https://​www.kernel.org/doc/Documentation/​kbuild/​kconfig-language.txt|Kconfig Language]] for details.
-If you're running a kernel ​that has the same release version ({{{`uname -r`}}}) as the new code you're compiling, you can test your changes without rebootingSimply install the module in /lib/modules, and unload and reload the driver:+
  
-{{{+==== Reloading modules ==== 
 +If you're running a kernel that has the same release version (**uname -r**) as the new code you're compiling, you can test your changes without rebooting. Simply install the module in /​lib/​modules,​ and unload and reload the driver: 
 + 
 +<​code>​
 make -j2 && sudo make modules_install make -j2 && sudo make modules_install
 sudo modprobe -r <​module_name>​ sudo modprobe -r <​module_name>​
-sudo modprobe <​module_name> ​}}}+sudo modprobe <​module_name>​ 
 +</​code>​
  
-How do you know what the module name is?  If you've compiled the driver as a module, there should be a .ko file in the parent directory. ​ For example, after we configure the android driver to be compiled as a module, we can run this command:+How do you know what the module name is? If you've compiled the driver as a module, there should be a .ko file in the parent directory. ​ For example, after we configure the android driver to be compiled as a module, we can run this command:
  
-{{{ +<​code>​ 
-intern@ubuntu:​~/​git/​kernel/​staging$ ls drivers/​staging/​android/​*.ko +$ ls drivers/​staging/​android/​*.ko 
- ​drivers/​staging/​android/​alarm-dev.ko ​ drivers/​staging/​android/​logger.ko ​}}}+ ​drivers/​staging/​android/​alarm-dev.ko ​ drivers/​staging/​android/​logger.ko 
 +</​code>​
  
-So, there are two drivers that we need to load with modprobe. ​ You can load those drivers one at a time by passing modprobe the base filename:+So, there are two drivers that we need to load with **modprobe**. You can load those drivers one at a time by passing ​**modprobe** the base filename:
  
-{{{ +<​code>​ 
-sudo modprobe alarm-dev}}}+sudo modprobe alarm-dev 
 +<​code>​
  
 To ensure the driver got loaded, you can run: To ensure the driver got loaded, you can run:
  
-{{{ +<​code>​ 
-lsmod | less}}}+lsmod | less 
 +</​code>​
  
-= Committing your changes =+==== Committing your changes ​====
 In this example, assume we've addressed a warning in the android driver, modified the file, recompiled the driver, and tested our changes. In this example, assume we've addressed a warning in the android driver, modified the file, recompiled the driver, and tested our changes.
  
-== Viewing your changes == +==== Viewing your changes ​==== 
-Git keeps track of changes in the working directory. ​ Git can be told to ignore binary files (like .o or .ko files), so it won't track changes to those files. ​ You can see which files have been modified by running:+Git keeps track of changes in the working directory. ​ Git can be told to ignore binary files (like .o or .ko files), so it won't track changes to those files. You can see which files have been modified by running:
  
-{{{ +<​code>​ 
-git status}}}+git status 
 +</​code>​
  
 git can also show you a diff stat of what changed: git can also show you a diff stat of what changed:
  
-{{{ +<​code>​ 
-git diff}}}+git diff 
 +</​code>​
  
-== Commit your changes ==+==== Commit your changes ​====
 Assuming we want to include all of our changes in one git commit, you can use git to add the changed file to the list of changes to be committed (the "​staging area"​):​ Assuming we want to include all of our changes in one git commit, you can use git to add the changed file to the list of changes to be committed (the "​staging area"​):​
  
-{{{ +<​code>​ 
-git add <​file>​}}}+git add <​file>​ 
 +</​code>​
  
-If you run {{{`git diff`}}} again, you'll notice it doesn'​t list any changed files. ​ That's because, by default, git diff only shows you the unstaged changes. ​ If you run this command instead, you'll see the staged changes:+If you run "**git diff**" ​again, you'll notice it doesn'​t list any changed files. That's because, by default, git diff only shows you the unstaged changes. If you run this command instead, you'll see the staged changes:
  
-{{{ +<​code>​ 
-git diff --cached}}}+git diff --cached 
 +</​code>​
  
 That command will show you the changes to be committed. That command will show you the changes to be committed.
  
-== Reverting your staged changes ==+==== Reverting your staged changes ​====
 If you don't want to commit those changes, you can remove those changes from the staging area by running: If you don't want to commit those changes, you can remove those changes from the staging area by running:
  
-{{{ +<​code>​ 
-git reset <​file>​}}}+git reset <​file>​ 
 +</​code>​
  
-== Committing parts of files ==+==== Committing parts of files ====
 You can also add parts of files to the staging area by using the following flag: You can also add parts of files to the staging area by using the following flag:
-{{{ +<​code>​ 
-git add -p}}}+git add -p 
 +</​code>​
  
 That will allow you to add hunks of the file to the staging area, or even edit hunks that you want to commit. ​ This is useful, for instance, if you've made whitespace changes, and also made a camel-case variable name fix, but those changes are on the same line.  You can edit the line to revert the camel-case name change, and just add the whitespace change to the staging area.  Then when you commit, you will just be committing the whitespace change. That will allow you to add hunks of the file to the staging area, or even edit hunks that you want to commit. ​ This is useful, for instance, if you've made whitespace changes, and also made a camel-case variable name fix, but those changes are on the same line.  You can edit the line to revert the camel-case name change, and just add the whitespace change to the staging area.  Then when you commit, you will just be committing the whitespace change.
  
-== Committing changes ==+==== Committing changes ​====
 Finally, you can commit your staged changes: Finally, you can commit your staged changes:
  
-{{{ +<​coce>​ 
-git commit -s -v}}}+git commit -s -v 
 +</code}
  
 That will add the Signed-off-by line that is needed at the end of your patch description. ​ The -v flag will show you the diff that you're committing. ​ This is very useful to decide whether you are committing the correct code. That will add the Signed-off-by line that is needed at the end of your patch description. ​ The -v flag will show you the diff that you're committing. ​ This is very useful to decide whether you are committing the correct code.
  
-Make sure that when you create ​your patch, you follow the PatchPhilosophy guidelines Make sure to include a blank line between your short description (what will become the Subject line of your patch) and the body of your patch. ​ Make sure there is a blank line between the body of your patch and your Signed-off-by line.  '''​Again,​ make sure you read PatchPhilosophy before you make your first commit.'''​+Please follow the [[https://​www.kernel.org/​doc/​html/​latest/​process/​submitting-patches.html|Submitting patches: the essential guide to getting your code into the kernel]] guidelines ​when you create ​patch. Make sure to include a blank line between your short description (what will become the Subject line of your patch) and the body of your patch. ​ Make sure there is a blank line between the body of your patch and your Signed-off-by line.
  
-== Editing your commits == +==== Editing your commits ​==== 
-If you should need to edit your commits, please see the [[GitTips|"​Editing commits"​ and "​Editing patchsets"​ sections]].+If you should need to edit your commits, please see the [[https://​kernelnewbies.org/​GitTips|"​Editing commits"​ and "​Editing patchsets"​ sections]].
  
-== Viewing your commit ==+==== Viewing your commit ​====
 Make sure your commit looks fine by running these commands: Make sure your commit looks fine by running these commands:
  
-{{{ +<​code>​ 
-git show HEAD}}}+git show HEAD 
 +</​code>​
  
-This will show the latest commit. ​ If you want git to show a different commit, you can pass the commit ID (the long number that's shown in {{{`git log`}}}, or the short number that's shown in {{{`git log --pretty=oneline --abbrev-commit`}}}).  Read the "​Specifying Revisions section"​ of the {{{`git rev-parse`}}} manual page for more details on what you can in place of a commit ID.+This will show the latest commit. If you want git to show a different commit, you can pass the commit ID (the long number that's shown in "**git log**", or the short number that's shown in "**git log --pretty=oneline --abbrev-commit**".  Read the "​Specifying Revisions section"​ of the "**git rev-parse**" ​manual page for more details on what you can in place of a commit ID.
  
 You'll also want to make sure your commit looks fine when you run these two commands: You'll also want to make sure your commit looks fine when you run these two commands:
  
-{{{ +<​code>​ 
-git log}}}+git log 
 +</​code>​
  
-{{{ +<​code>​ 
-git log --pretty=oneline --abbrev-commit}}}+git log --pretty=oneline --abbrev-commit 
 +</​code>​
  
-<<​Anchor(submit_a_patch)>>​ +==== Submit a patch ====
-= Submit a patch =+
  
-The first step to sending a patch is to figure out who to send it to.  For this, you need to find the maintainer of the code you're patching, and Cc the correct mailing list.  If you simply ​send it off to LKML, it will get ignored The perl script in the kernel ​source directory ``scripts/get_maintainer.pl`` will either take a git commit or a file, and tell you who to send your patch to:+When you are ready to send your patch, you will have to determine whom to send the patch to. [[https://​www.kernel.org/doc/​html/​latest/​process/​submitting-patches.html#​select-the-recipients-for-your-patch|Select the recipients for your patch]] walks you though the process.
  
-{{{+<​code>​
 $ git show --pretty=oneline --abbrev-commit HEAD $ git show --pretty=oneline --abbrev-commit HEAD
 cb9a537 staging: most: constify snd_pcm_ops structure cb9a537 staging: most: constify snd_pcm_ops structure
Line 572: Line 697:
 $ perl scripts/​get_maintainer.pl --separator , --nokeywords --nogit --nogit-fallback --norolestats --nol -f drivers/​staging/​most/​aim-sound/​sound.c $ perl scripts/​get_maintainer.pl --separator , --nokeywords --nogit --nogit-fallback --norolestats --nol -f drivers/​staging/​most/​aim-sound/​sound.c
 Greg Kroah-Hartman <​gregkh@linuxfoundation.org>​ Greg Kroah-Hartman <​gregkh@linuxfoundation.org>​
-}}}+</​code>​
  
-The many arguments to get_maintainer.pl cause the output to be in the form of a comma-separated list and cause only the actual maintainers of the affected files to be included. ​ However, for IIO drivers, please also include linux-iio@vger.kernel.org. ​ On the other hand, the maintainers of staging/​vc04_services would prefer not to be CCd on Outreachy ​patches. ​ Please CC Greg explicitly on these patches: ​ Greg KH <​gregkh@linuxfoundation.org>​. More generally, for non-outreachy ​patches, drop the -nol argument, to include mailing lists.+The many arguments to get_maintainer.pl cause the output to be in the form of a comma-separated list and cause only the actual maintainers of the affected files to be included. ​ However, for IIO drivers, please also include linux-iio@vger.kernel.org. ​ On the other hand, the maintainers of staging/​vc04_services would prefer not to be CCd on Linux Kernel Mentorship ​patches. ​ Please CC Greg explicitly on these patches: ​ Greg KH <​gregkh@linuxfoundation.org>​. More generally, for non-Linux Kernel Mentorship ​patches, drop the -nol argument, to include mailing lists.
  
-The second step to submitting a patch is to create and send a patch as an email. ​ You cannot send patches as attachments to the mailing list.  Instead, you will have to craft a special email, and send the patch inline.+The second step to submitting a patch is to create and send a patch as an email. You cannot send patches as attachments to the mailing list. Instead, you will have to craft a special email, and send the patch inline. Please follow [[https://​www.kernel.org/​doc/​html/​latest/​process/​submitting-patches.html#​no-mime-no-links-no-compression-no-attachments-just-plain-text|No MIME, no links, no compression,​ no attachments. Just plain text]] guidelines.
  
-There are two ways to send a patch. ​ Either way is correct, and we suggest you get comfortable with sending ​patches ​both ways We suggest sending your first patch to yourself, in order to make sure it works.+Use git send-email ​to send patches. ​Please send the patch to yourself ​and/or a friend ​to test your setup.
  
-== Creating a patch to send with mutt == +==== Sending patches with git send-email ==== 
-First, create ​a patch that describes ​the change, using {{{`git format-patch`}}}.  That command takes a starting commit ID (and optionally) an ending commit IDin order to create patches for the commit '''​after'''​ the starting ​commit ID.  We want to create a patch for the first commit in our history (the HEAD commit). ​ To specify the commit before the HEAD commit, ​you can use either ​"HEAD^" ​or "​HEAD~"​.+You can also send a patch with the command-line tool "**git send-email**"​. You can either pass it the file that "**git format-patch**" generatedor you can give it the same commit ID range you gave "**git format-patch**":
  
-{{{ +<code
-git format-patch -o /tmp/ HEAD^}}} +git send-email --annotate HEAD^ 
- +</code>
-The -o flag specifies where to put the patch. ​ If you've run the command correctly, you should see the command output a filename in /​tmp/​. ​ If it outputs nothing, you've forgotten the '​^'​. +
- +
-== Sending your patch with mutt == +
-Next, tell mutt to use that patch as a draft email, with the -H flag: +
- +
-{{{ +
-mutt -H /tmp/0001-<whatever your filename is>}}} +
- +
-Send this first patch to yourself. ​ Leave the Subject line intact. ​ Now you can see how your patch translates to an inline email. ​ The git short description becomes the email subject line, and the patch body and diff become the body of the email. +
- +
-Write the mail, quit out of vim, and send the mail with '​y'​. +
- +
-== Sending patches with git send-email == +
-You can also send a patch with the command-line tool {{{`git send-email`}}}. ​ You can either pass it the file that {{{`git format-patch`}}} generated, or you can give it the same commit ID range you gave {{{`git format-patch`}}}:​ +
- +
-{{{ +
-git send-email --annotate HEAD^}}} +
- +
-You will need to add the following information to your .gitconfig file: +
- +
-{{{ +
-[sendemail] +
-   ​smtpserver = /usr/​bin/​esmtp}}}+
  
 +You should already have all the information in your **.gitconfig** at the beginning in **Setup git** section of this document.
  
 git send email will prompt you with who to send the message to, and other odd questions: git send email will prompt you with who to send the message to, and other odd questions:
  
-{{{+<​code>​
 Who should the emails be sent to (if any)? Who should the emails be sent to (if any)?
 Message-ID to be used as In-Reply-To for the first email (if any)? Message-ID to be used as In-Reply-To for the first email (if any)?
-}}}+</​code>​
  
 Put in your mentor'​s address in the first line, and leave the second blank unless you want it to appear as a thread in an existing conversation. Put in your mentor'​s address in the first line, and leave the second blank unless you want it to appear as a thread in an existing conversation.
  
-At this point {{{`git send-email`}}} will look for Cc: lines in your commit message, and include them in the email headers. ​ It will then show you the resulting email header, and ask you to confirm:+At this point "**git send-email**" ​will look for Cc: lines in your commit message, and include them in the email headers. It will then show you the resulting email header, and ask you to confirm:
  
-{{{+<​code>​
 Send this email? ([y]es|[n]o|[q]uit|[a]ll):​ Send this email? ([y]es|[n]o|[q]uit|[a]ll):​
-}}}+</​code>​
  
 [[https://​vthakkar1994.wordpress.com/​2017/​01/​21/​sending-patches-with-the-git-send-email/​|More help with git send-email]] [[https://​vthakkar1994.wordpress.com/​2017/​01/​21/​sending-patches-with-the-git-send-email/​|More help with git send-email]]
Line 632: Line 735:
 Send with '​y'​ (or '​a':​ git send-email can be used to send multiple commits at once). Send with '​y'​ (or '​a':​ git send-email can be used to send multiple commits at once).
  
-== Tips and Tricks == +==== Tips and Tricks ​==== 
-Please read the [[PatchTipsAndTricks|patch tips and tricks]] page for an explanation of patch tags (e.g. Reviewed-by and Signed-off-by),​ and when to use [PATCH] vs. [RFC] in your patch subject prefix.+Please read the [[https://​kernelnewbies.org/​PatchTipsAndTricks|patch tips and tricks]] page for an explanation of patch tags (e.g. Reviewed-by and Signed-off-by),​ and when to use [PATCH] vs. [RFC] in your patch subject prefix.
  
-<<​Anchor(send-patch-to-mentor)>>​ +==== Send your patch to your mentors ​====
-= Send your patch to your mentors =+
 Once you've send your patch to your own email, and ensured that it looks fine, it's time to send your patch off. Once you've send your patch to your own email, and ensured that it looks fine, it's time to send your patch off.
  
 Send your patch to the maintainer and lists that the get_maintainer.pl script tells you to. Send your patch to the maintainer and lists that the get_maintainer.pl script tells you to.
  
-If you are an Outreachy applicant, please additionally send your patches ​to [[https://​groups.google.com/​forum/#​!forum/​outreachy-kernel|outreachy-kernel ​mailing list]].+Please send you patch to **linux-kernel-mentees** ​mailing list
  
-= Responding to emails =+==== Responding to emails ​====
  
-When responding to emails on the mailing list, it's important to use a communication style consistent with what the open source community expects. ​ Please make sure you use one of the standard email clients listed in [[https://​www.kernel.org/​doc/​html/​v4.12/​process/​email-clients.html]]. ​ Do NOT use the gmail web interface to respond to patch feedback, as it line-wraps the mail (even when in plain text mode). ​ Do NOT use outlook, as it mangles patches (turns tabs into spaces).+When responding to emails on the mailing list, it's important to use a communication style consistent with what the open source community expects. ​ Please make sure you use one of the standard email clients listed in [[https://​www.kernel.org/​doc/​html/​v4.12/​process/​email-clients.html]]. Do NOT use the gmail web interface to respond to patch feedback, as it line-wraps the mail (even when in plain text mode). Do NOT use outlook, as it mangles patches (turns tabs into spaces).
  
 Don't include quotes in your signature. Don't include quotes in your signature.
  
-== Responding inline ==+==== Responding inline ​====
  
 When responding to email, make sure you respond inline, rather than top-posting. ​ This is a [[http://​marc.info/?​l=linux-usb&​m=139325835826056&​w=2|good example of responding inline]]. When responding to email, make sure you respond inline, rather than top-posting. ​ This is a [[http://​marc.info/?​l=linux-usb&​m=139325835826056&​w=2|good example of responding inline]].
Line 659: Line 761:
 Take a look at this example email with three people who are responding inline: Take a look at this example email with three people who are responding inline:
  
-{{{+<​code>​
 From: Kludge Crufty <​example@email.com>​ From: Kludge Crufty <​example@email.com>​
 Subject: Design decisions for next release Subject: Design decisions for next release
Line 673: Line 775:
  
 Kludge Kludge
-}}}+</​code>​
  
 The email was sent by Kludge. ​ Kludge is responding to an email sent by Baz at 3PM.  Baz was responding to an email sent from Foo at 2:30PM. The email was sent by Kludge. ​ Kludge is responding to an email sent by Baz at 3PM.  Baz was responding to an email sent from Foo at 2:30PM.
  
 From this snippet of mail, we can tell who said what by looking at the number of '>'​ symbols in front of each line: From this snippet of mail, we can tell who said what by looking at the number of '>'​ symbols in front of each line:
- * Kludge wants to do Z, because their dialog has no '>'​ in front of it. +  ​* Kludge wants to do Z, because their dialog has no '>'​ in front of it. 
- * Baz wants to do Y, because their dialog has one '>'​ in front, and we follow that '>'​ level up to Baz's "​wrote"​ line. +  * Baz wants to do Y, because their dialog has one '>'​ in front, and we follow that '>'​ level up to Baz's "​wrote"​ line. 
- * Foo wants to do X, because their dialog has two '> >' in front, and we follow the last '>'​ up to Foo's "​wrote"​ line.+  * Foo wants to do X, because their dialog has two '> >' in front, and we follow the last '>'​ up to Foo's "​wrote"​ line.
  
 Another point to notice is that each responding person has put a blank line before and after their response. ​ This makes it easier to find where some new text has been added. Another point to notice is that each responding person has put a blank line before and after their response. ​ This makes it easier to find where some new text has been added.
Line 686: Line 788:
 Note that following inline conversation responses can be very difficult if your mail client or terminal isn't configured to show text in fixed-width fonts. ​ This is one of the many reasons that kernel developers prefer text-based mail clients like mutt. Note that following inline conversation responses can be very difficult if your mail client or terminal isn't configured to show text in fixed-width fonts. ​ This is one of the many reasons that kernel developers prefer text-based mail clients like mutt.
  
-= Revising your patches =+==== Revising your patches ​====
  
-== Editing your commits == +==== Editing your commits ​==== 
-If you should need to edit your commits, please see the [[GitTips|"​Editing commits"​ and "​Editing patchsets"​ sections]].+If you should need to edit your commits, please see the [[https://​kernelnewbies.org/​GitTips|"​Editing commits"​ and "​Editing patchsets"​ sections]].
  
-== Versioning one patch revision ==+==== Versioning one patch revision ​====
  
 If you receive feedback on a patch, and were asked to update the patch, you need to version the patches that you re-send. ​ A new version number lets reviewers know you made changes to the patch, and they should review it again. If you receive feedback on a patch, and were asked to update the patch, you need to version the patches that you re-send. ​ A new version number lets reviewers know you made changes to the patch, and they should review it again.
Line 697: Line 799:
 An example of what this would look like is: An example of what this would look like is:
  
-{{{+<​code>​
 [PATCH] Foo: Fix these things [PATCH] Foo: Fix these things
-}}}+</​code>​
  
 And the updated versioning for a second revision: And the updated versioning for a second revision:
  
-{{{+<​code>​
 [PATCH v2] Foo: Fix these things better [PATCH v2] Foo: Fix these things better
-}}}+</​code>​
  
-It's fairly simple to accomplish this, and there'​s certainly a few ways to do this.  If you generate your patches using {{{`git format-patch`}}}, then it's simple to do this.  Just add the --subject-prefix option like this:+It's fairly simple to accomplish this, and there'​s certainly a few ways to do this.  If you generate your patches using "**git format-patch**", then it's simple to do this. Just add the --subject-prefix option like this:
  
-{{{+<​code>​
 git format-patch --subject-prefix="​PATCH v2" git format-patch --subject-prefix="​PATCH v2"
-}}}+</​code>​
  
 or whatever version you are currently on (3, 4, etc.). or whatever version you are currently on (3, 4, etc.).
Line 717: Line 819:
 Make sure to include a summary of what changed from one version of the patch (or patchset) to the next.  Do not include a version change log in the patch description,​ because it won't make sense when the final version of the patch makes it into the kernel. ​ Instead, edit your patches before you send them to include a change log below the "​---"​ line.  Git will ignore this change log when the patch is applied. ​ Here's a [[http://​marc.info/?​l=linux-usb&​m=139277576606875&​w=2|good example of a patch]] with a change log: Make sure to include a summary of what changed from one version of the patch (or patchset) to the next.  Do not include a version change log in the patch description,​ because it won't make sense when the final version of the patch makes it into the kernel. ​ Instead, edit your patches before you send them to include a change log below the "​---"​ line.  Git will ignore this change log when the patch is applied. ​ Here's a [[http://​marc.info/?​l=linux-usb&​m=139277576606875&​w=2|good example of a patch]] with a change log:
  
-{{{+<​code>​
 Subject: [PATCH v2 1/2] USB: at91: fix the number of endpoint parameter Subject: [PATCH v2 1/2] USB: at91: fix the number of endpoint parameter
  
Line 735: Line 837:
  
 diff --git a/​drivers/​usb/​gadget/​atmel_usba_udc.c b/​drivers/​usb/​gadget/​atmel_usba_udc.c diff --git a/​drivers/​usb/​gadget/​atmel_usba_udc.c b/​drivers/​usb/​gadget/​atmel_usba_udc.c
-}}}+</​code>​
  
-'''​Update''' ​In case of more than 2 versions, make sure to include what has changed in each version below the -- so that there is a logical flow and the maintainers do not have to dig up previous versions. The most recently changed version should be described first followed by the subsequent changes. Have a look at this [[https://​lkml.org/​lkml/​2018/​2/​22/​972| patch example]] with 3 versions to get a better idea.+Update In case of more than 2 versions, make sure to include what has changed in each version below the -- so that there is a logical flow and the maintainers do not have to dig up previous versions. The most recently changed version should be described first followed by the subsequent changes. Have a look at this [[https://​lkml.org/​lkml/​2018/​2/​22/​972| patch example]] with 3 versions to get a better idea.
  
-== Versioning patchsets == +==== Versioning patchsets ​==== 
-When you send out a new version of a patchset, you could either indicate on each patch what has changed or you could include the changes in a coverletter. If you plan to indicate the changes in each patch, you need to specify what has changed in each version like in this [[https://​lkml.org/​lkml/​2018/​2/​23/​287|patch example]] and indicate ​'''​No change''' ​explicitly for patch versions that are unaltered. In case you decide to indicate the changes in a coverletter,​ here is an [[http://​marc.info/?​l=linux-usb&​m=139302798628519&​w=2|Example cover letter.]] ​ You can include a coverletter in your patchset by using the `--cover-letteroption to `git format-patch`, e.g.+When you send out a new version of a patchset, you could either indicate on each patch what has changed or you could include the changes in a coverletter. If you plan to indicate the changes in each patch, you need to specify what has changed in each version like in this [[https://​lkml.org/​lkml/​2018/​2/​23/​287|patch example]] and indicate ​"**No change**" ​explicitly for patch versions that are unaltered. In case you decide to indicate the changes in a coverletter,​ here is an [[http://​marc.info/?​l=linux-usb&​m=139302798628519&​w=2|Example cover letter.]] ​ You can include a coverletter in your patchset by using the "**--cover-letter**" ​option to "**git format-patch**", e.g.
  
-{{{+<​code>​
 git format-patch -n --subject-prefix="​PATCH vY" --cover-letter git format-patch -n --subject-prefix="​PATCH vY" --cover-letter
-}}}+</​code>​
  
 where Y is the version of the patch you are currently sending. ​ The cover-letter option will create a "PATCH 0/Y" that you can add a change log to.  Make sure to change the SUBJECT HERE on the coverletter subject line.  Note that cover letters are discarded when applying patches, so any information that you want to preserve in the git log should be in the patch descriptions,​ not the cover letter. ​ The cover letter is for introducing what problem you're trying to solve, and including version change logs. where Y is the version of the patch you are currently sending. ​ The cover-letter option will create a "PATCH 0/Y" that you can add a change log to.  Make sure to change the SUBJECT HERE on the coverletter subject line.  Note that cover letters are discarded when applying patches, so any information that you want to preserve in the git log should be in the patch descriptions,​ not the cover letter. ​ The cover letter is for introducing what problem you're trying to solve, and including version change logs.
  
-'''​Make sure to include all of the patches you sent in the patchset before''' ​(i.e. if you sent three patches and you had to revise the second patch, send all three again).+Make sure to include all of the patches you sent in the patchset before (i.e. if you sent three patches and you had to revise the second patch, send all three again).
  
 An example of what this would look like is: An example of what this would look like is:
  
-{{{+<​code>​
 [PATCH 0/3] comedi: Fix these things [PATCH 0/3] comedi: Fix these things
 [PATCH 1/3] comedi: Fix the first thing [PATCH 1/3] comedi: Fix the first thing
 [PATCH 2/3] comedi: Fix the second thing [PATCH 2/3] comedi: Fix the second thing
 [PATCH 3/3] comedi: Fix the third thing [PATCH 3/3] comedi: Fix the third thing
-}}}+</​code>​
  
 And the updated versioning for a second revision: And the updated versioning for a second revision:
  
-{{{+<​code>​
 [PATCH v2 0/3] comedi: Fix these things [PATCH v2 0/3] comedi: Fix these things
 [PATCH v2 1/3] comedi: Fix the first thing [PATCH v2 1/3] comedi: Fix the first thing
 [PATCH v2 2/3] comedi: Fix the second thing [PATCH v2 2/3] comedi: Fix the second thing
 [PATCH v2 3/3] comedi: Fix the third thing [PATCH v2 3/3] comedi: Fix the third thing
-}}}+</​code>​
  
-= Submitting a patchset =+==== Submitting a patchset ​====
  
 Sometimes you need to send multiple related patches. ​ This is useful for grouping, say, to group driver clean up patches for one particular driver into a set, or grouping patches that are part of a new feature into one set. Sometimes you need to send multiple related patches. ​ This is useful for grouping, say, to group driver clean up patches for one particular driver into a set, or grouping patches that are part of a new feature into one set.
Line 774: Line 876:
 For example, take a look at this patch set: For example, take a look at this patch set:
  
- * [[http://​marc.info/?​l=linux-doc&​m=136604732318550&​w=2|cover letter]] +  ​* [[http://​marc.info/?​l=linux-doc&​m=136604732318550&​w=2|cover letter]] 
- * [[http://​marc.info/?​l=linux-kernel&​m=136604728318534&​w=2|PATCH 1/7]] +  * [[http://​marc.info/?​l=linux-kernel&​m=136604728318534&​w=2|PATCH 1/7]] 
- * [[http://​marc.info/?​l=linux-doc&​m=136751167021547&​w=2|PATCH 2/7]] +  * [[http://​marc.info/?​l=linux-doc&​m=136751167021547&​w=2|PATCH 2/7]] 
- * [[http://​marc.info/?​l=linux-doc&​m=136751167021548&​w=2|PATCH 3/7]] +  * [[http://​marc.info/?​l=linux-doc&​m=136751167021548&​w=2|PATCH 3/7]] 
- * [[http://​marc.info/?​l=linux-doc&​m=136751167821552&​w=2|PATCH 4/7]] +  * [[http://​marc.info/?​l=linux-doc&​m=136751167821552&​w=2|PATCH 4/7]] 
- * [[http://​marc.info/?​l=linux-doc&​m=136751168121553&​w=2|PATCH 5/7]] +  * [[http://​marc.info/?​l=linux-doc&​m=136751168121553&​w=2|PATCH 5/7]] 
- * [[http://​marc.info/?​l=linux-doc&​m=136751168421557&​w=2|PATCH 6/7]] +  * [[http://​marc.info/?​l=linux-doc&​m=136751168421557&​w=2|PATCH 6/7]] 
- * [[http://​marc.info/?​l=linux-doc&​m=136751168521559&​w=2|PATCH 7/7]]+  * [[http://​marc.info/?​l=linux-doc&​m=136751168521559&​w=2|PATCH 7/7]]
  
 Typically, the subject prefix for patches in the patchset are [PATCH X/Y] or [RFC X/Y], where Y is the total number of patches, and X is the current patch number. ​ Patchsets often have a "cover letter"​ that is [PATCH 0/Y] or [RFC 0/Y].  A cover letter is used to explain why the patchset is necessary, and provide an overview of the end result of the patches. ​ Cover letters are also great places to ask for help in reviewing specific patches in the patchset. Typically, the subject prefix for patches in the patchset are [PATCH X/Y] or [RFC X/Y], where Y is the total number of patches, and X is the current patch number. ​ Patchsets often have a "cover letter"​ that is [PATCH 0/Y] or [RFC 0/Y].  A cover letter is used to explain why the patchset is necessary, and provide an overview of the end result of the patches. ​ Cover letters are also great places to ask for help in reviewing specific patches in the patchset.
  
-In order to create patchsets like this, you will need to use either ​{{{`git send-email``}}} or {{{`git format-patch`}}} These tools will generate the right "​In-Reply-To"​ Headers, so that in a text mail client, the patches will appear next to each other, rather than having unrelated email in between. ​ Otherwise, patches may get jumbled, depending on when they were received.+In order to create patchsets like this, you will need to use either ​"**git send-email**" ​or "**git format-patch**". These tools will generate the right "​In-Reply-To"​ Headers, so that in a text mail client, the patches will appear next to each other, rather than having unrelated email in between. ​ Otherwise, patches may get jumbled, depending on when they were received.
  
-== Using git format-patch to send patchsets ==+==== Using git format-patch to send patchsets ​====
  
-First, use {{{`git log --pretty=oneline --abbrev-commit`}}} to figure out the first commit ID you want to send.  For example, say that my tree had this git log history:+First, use "**git log --pretty=oneline --abbrev-commit**" ​to figure out the first commit ID you want to send.  For example, say that my tree had this git log history:
  
-{{{+<​code>​
 b7ca36a Docs: Move ref to Frohwalt Egerer to end of REPORTING-BUGS b7ca36a Docs: Move ref to Frohwalt Egerer to end of REPORTING-BUGS
 bf6adaf Docs: Add a tips section to REPORTING-BUGS. bf6adaf Docs: Add a tips section to REPORTING-BUGS.
Line 801: Line 903:
 bb33db7 Merge branches '​timers-urgent-for-linus',​ '​irq-urgent-for-linus'​ and '​core-urgent-for-linus'​ of git://​git.kernel.org/​pub/​scm/​linux/​kernel/​git/​tip/​tip bb33db7 Merge branches '​timers-urgent-for-linus',​ '​irq-urgent-for-linus'​ and '​core-urgent-for-linus'​ of git://​git.kernel.org/​pub/​scm/​linux/​kernel/​git/​tip/​tip
 41ef2d5 Linux 3.9-rc7 41ef2d5 Linux 3.9-rc7
-}}}+</​code>​
  
-The first commit I want to send as part of the patchset has commit ID 3b12c21. ​ The last patch I want to send has commit ID b7ca36a. ​ So, I want to pass the commit range {{{3b12c21^..b7ca36a}}} to {{{git format-patch}}}.  (Remember, the {{{git format-patch}}} range starting commit must be the commit ''​before''​ the first commit you want to send, so we use the '​^'​ to specify the patch before commit 3b12c21.) ​ The command will look something like this:+The first commit I want to send as part of the patchset has commit ID 3b12c21. ​ The last patch I want to send has commit ID b7ca36a. ​ So, I want to pass the commit range 3b12c21^..b7ca36a to git format-patch. ​ (Remember, the git format-patch range starting commit must be the commit ''​before''​ the first commit you want to send, so we use the '​^'​ to specify the patch before commit 3b12c21.) ​ The command will look something like this:
  
-{{{ +<​code>​ 
-git format-patch -o /tmp/ --cover-letter -n --thread=shallow --cc="​linux-usb@vger.kernel.org"​ 3b12c21^..b7ca36a}}}+git format-patch -o /tmp/ --cover-letter -n --thread=shallow --cc="​linux-usb@vger.kernel.org"​ 3b12c21^..b7ca36a 
 +</​code>​
  
 Again, the -o flag specifies where to put the email files. ​ The -n flag says to add numbering to each patch (e.g. [PATCH 2/​5]). ​ The --thread=shallow flag specifies that all patches will be In-Reply-To your cover letter. Again, the -o flag specifies where to put the email files. ​ The -n flag says to add numbering to each patch (e.g. [PATCH 2/​5]). ​ The --thread=shallow flag specifies that all patches will be In-Reply-To your cover letter.
  
 That will output files into /tmp, and you can edit them in mutt in multiple terminal tabs: That will output files into /tmp, and you can edit them in mutt in multiple terminal tabs:
-{{{+<​code>​
 /​tmp/​0000-cover-letter.patch /​tmp/​0000-cover-letter.patch
 /​tmp/​0001-Trivial-docs-Remove-six-space-indentation-in-REPORTI.patch /​tmp/​0001-Trivial-docs-Remove-six-space-indentation-in-REPORTI.patch
Line 820: Line 923:
 /​tmp/​0006-Docs-Add-a-tips-section-to-REPORTING-BUGS.patch /​tmp/​0006-Docs-Add-a-tips-section-to-REPORTING-BUGS.patch
 /​tmp/​0007-Docs-Move-ref-to-Frohwalt-Egerer-to-end-of-REPORTING.patch /​tmp/​0007-Docs-Move-ref-to-Frohwalt-Egerer-to-end-of-REPORTING.patch
-}}} +</​code>​ 
-Please send patch to linux-kernel-mentees mailing list.+ 
 +Please send patch to **linux-kernel-mentees** mailing list.
  
  
  
  
lkmp/lkmp_first_kernel_patch.1554482174.txt.gz · Last modified: 2019/04/05 16:36 by ShuahKhanLF