Quilt Patching Hints

From RidgeRun Developer Wiki


Introduction

The RidgeRun SDK uses patch files to modify the source code in Open Source packages (either libraries like GStreamer or applications like ntpd). To manage the set of patch files applied to an Open Source package, the tool quilt is used.

When you install the RidgeRun SDK, you end up with a development directory (called DEVDIR in the documentation). The DEVDIR contains all the RidgeRun SDK build system (mainly contained in Makefiles and $DEVDIR/bsp/classes), installer logic (in $DEVDIR/installer), examples (in $DEVDIR/myapps), proprietary software (n $DEVDIR/proprietary), and Open Source package integration directories (in $DEVDIR/fs/apps).

Why patch Open Source packages

The simple answer as to why RidgeRun modifies an Open Source package's source code is to make it work. Typical problems we encounter include the package does not properly support cross-compliation, we need a feature that is not supported by the package, or we have a bug fix.

RidgeRun could put all the source to the Open Source package in the SDK (which we don't) and then just modify the source. So why isn't this simple, easy to understand process used? Three reasons:

  1. How can anyone tell what changes RidgeRun made? For some Open Source packages, like the Linux kernel, we might have 30 or more patches. If we just gave you the patched Linux kernel, it is difficult to track exactly what you have.
  2. Most changes are unrelated, for example, one fixes a USB defect and the other add supports for another video resolution. When you are looking at the code, how do you know what changes to make, if say you want to add yet another video resolution?
  3. If you want to update to a newer version of an Open Source package, how do you know what changes were made?

By organizing changes to Open Source packages as individual, stand alone patches, it is easy to see what RidgeRUn used as the starting point (which pristine version of the Open Source package), what changes were made, and reviewing the changes is manageable (some say easy after you get used to reading patch files).

SDK patch process

Some patches always apply to an Open Source package, say a patch for a bug fix. Some patches only apply to a specific SoC (called arch in the RidgeRun SDK), say a patch to use a hardware feature. Finally some patches only apply to a specific board design (called mach in the RidgeRun SDK), say a GPIO pin configuration.

Thus patches are organized into three sets: always apply, apply for specific architectures, and apply for specific machines. The order the sets of patches are applied is:

  1. Patches listed in patches/arch/series.
  2. Patches listed in patches/mach/series.
  3. Patches listed in patches/series.

The SDK build system automatically takes the contents of the 3 series files listed above (if they exist) and then generates a single series file outside of the patches directory that looks as follows:

## ARCH SERIES ##
arch/fix_int_ll64_path.patch
## END OF ARCH SERIES ##
## MACH SERIES ##
mach/0001-MXC-Add-a-driver-for-the-FLIR-Tau-640-camera-sensor.patch
mach/0002-MXC-Add-a-driver-for-the-FLIR-Tau-640-camera-sensor.patch
## END OF MACH SERIES ##
## SERIES ##
rrsdk_integration.patch

Note: This series file is autogenerated and used by quilt to track the current patches, however, you should never modify it, instead, any addition or modification to the patches series should be done on the series files into the patches directory.

You will find the patches/ directory in the root of each Open Source package, below are some examples:

  • Bootloader
$DEVDIR/bootloader/u-boot-2015.04/patches/
  • Linux Kernel
$DEVDIR/kernel/patches/
  • Open Source application (e.g. Gstreamer)
$DEVDIR/fs/apps/gstreamer-1.8.1/patches/

So that, each patches directory includes all the changes for the source code on the inner directories.

How to create a patch

Let's assume we need to create a patch to track the changes on a specific file within the Linux kernel, being $PATCH_NAME the name of your patch and $FILE_NAME the name of the file (or files) you want to track down.

Step 1:

Go to the kernel directory

quilt new mach/$PATCH_NAME.patch #create the patch

Step2:

quilt add $FILE_NAME #add a file to be patched -- add the file before changing it

Step 3:

Edit files

Step 4:

quilt refresh #update the patch

Note: Patch name is created by adding the arch/ or mach/ to the beginning of the patch name:

How to edit an existing patch - approach 1

Step 1:

Make sure that no patch is applied.

cd $DEVDIR/kernel 
make unpatch

Step 2:


quilt push

with an example output of pushing a patch shown below:

Applying patch rrsdk_integration.patch
patching file linux-3.0.35-4.0.0/drivers/i2c/algos/Kconfig
patching file linux-3.0.35-4.0.0/drivers/media/common/tuners/Kconfig
patching file linux-3.0.35-4.0.0/drivers/media/dvb/frontends/Kconfig
patching file linux-3.0.35-4.0.0/drivers/media/video/Kconfig
patching file linux-3.0.35-4.0.0/drivers/staging/echo/Kconfig
patching file linux-3.0.35-4.0.0/drivers/staging/echo/Makefile
patching file linux-3.0.35-4.0.0/drivers/net/tokenring/Kconfig
patching file linux-3.0.35-4.0.0/Makefile

Now at patch rrsdk_integration.patch

Step 3:

When you see the name of the patch you want to edit at Now at patch ...,

edit the desired files (for example linux-3.0.35-4.0.0/drivers/i2c/algos/Kconfig)

and when you finish editing the file


quilt refresh

to update the patch.

Step 4:

Then you can do

quilt pop

to remove the patches one by one until no patch is applied and you should be ready to go.

How to edit an existing patch - approach 2

For example how to edit a source file (mt9p031.c) which is already in a patch file called 'add_mt9p031_sensor_support.patch'

Step 1:

Change to

$DEVDIR/kernel

and do

quilt applied

This command tells you what patches already applied. For example, you can find 'add_mt9p031_sensor_support.patch' in the list of applied patch files.

Step 2:

and then run

quilt pop #remove the patches one by one

Repeat above pop command until until you are in the 'add_mt9p031_sensor_support.patch'

Step 3:

Edit the changes in the 'mt9p031.c' file in the above mentioned patch file.

Step 4:

do

quilt refresh #update the patch

Step 5:

After that just to verify that the change did not affect any other patch, do

quilt push #apply patches one by one 

Repeat the Step 5 until all the patches were applied.

Step 6:

do

make clean #for this example we are in $DEVDIR/kernel

Step 7:

goto $DEVDIR

and then run

cd $DEVDIR
make

Points to remember when creating a new patch

One of the thins you have to make sure is when you create a new patch it has to be in the corresponding series file in order to be applied. For example, for the Tau camera, the series file would be:

0001-MXC-Add-a-driver-for-the-FLIR-Tau-640-camera-sensor.patch
0002-MXC-Add-a-driver-for-the-FLIR-Tau-640-camera-sensor.patch

Finally, if you see the kernel/series file after patching you'll see:

## ARCH SERIES ##
arch/fix_int_ll64_path.patch
## END OF ARCH SERIES ##
## MACH SERIES ##
mach/0001-MXC-Add-a-driver-for-the-FLIR-Tau-640-camera-sensor.patch
mach/0002-MXC-Add-a-driver-for-the-FLIR-Tau-640-camera-sensor.patch
## END OF MACH SERIES ##
## SERIES ##
rrsdk_integration.patch

which tell you the applied patches.

Patch folding

If you need to merge 2 patches into a single one the fold command allows you to do just that, consider the following example,

Assuming that you have patches '1', '2' and '3' applied, and want to merge '2' and '3'; you would do:

quilt pop
quilt delete 3
quilt fold < patches/3
# Verify that it worked OK, quilt diff should show '2' and '3' merged
rm patches/3