Quilt Patching Hints
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:
- 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.
- 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?
- 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:
- Patches listed in patches/arch/series.
- Patches listed in patches/mach/series.
- 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