Development Process

Linux Kernel Development at Handhelds.org

Getting the Linux Kernel Sources

See Sources.

Example 9. Linux Kernel Sources from Patch Files

	    bash$ wget http://www.us.kernel.org/pub/linux/kernel/v2.4/linux-2.4.9.tar.gz
	    bash$ wget ftp://ftp.arm.linux.org.uk/pub/armlinux/kernel/v2.4/patch-2.4.19-rmk4.tar.gz
	    bash$ wget ftp://ftp.arm.linux.org.uk/pub/armlinux/people/nico/diff-2.4.19-rmk4-pxa2.tar.gz
	    bash$ wget ftp://ftp.handhelds.org/pub/linux/kernel/patch-2.4.19-rmk4-pxa2-hh10.gz
	    bash$ tar -zxvf linux-2.4.19.tar.gz
	    bash$ mv linux linux-2.4.19-rmk4-pxa2-hh10
	    bash$ cd linux-2.4.19-rmk4-pxa2-hh10
	    bash$ zcat ../patch-2.4.19-rmk4.gz | patch -p1
	    bash$ zcat ../diff-2.4.19-rmk4-pxa2.gz | patch -p1
	    bash$ zcat ../patch-2.4.19-rmk4-pxa2-hh10.gz | patch -p1
	  

Example 10. CVS checkout of a latest kernel version

See the Section called Using CVS for more details on using CVS.

	    bash$ export CVSROOT=:pserver:anoncvs@cvs.handhelds.org:/cvs
	    bash$ cvs login
	    password: anoncvs
	    bash$ cvs checkout linux/kernel
	    bash$ cd linux/kernel
	    bash$ kerneldir=$PWD
	  

Example 11. CVS checkout of a particular kernel version

	    bash$ TAG=K`echo 2.4.19-rmk4-pxa2-hh10 | sed s/./-/g`
	    bash$ cvs checkout -r $TAG linux/kernel
	    bash$ cd linux/kernel
	    bash$ kerneldir=$PWD
	  

Building the Linux kernel

	  bash$ kerneldir=$PWD
	  bash$ make h3600_config
	  bash$ make oldconfig
	  bash$ make dep
	  bash$ make zImage modules
	

Packaging the kernel

	  bash# mkdir ipkgs; cd ipkgs
	  bash# ../scripts/ipkg-make-kernel-packages $PWD/.. 2.4.19-rmk3 hh21
	

Making task-bootstrap.jffs2

Perform the following on an ipaq, where /mnt/hda is mounted on an IDE drive:

Example 12. Creating task-bootstrap images

	    bash# cd /mnt/hda
	    bash# ipkg -o bootstrap update
	    bash# ipkg -o bootstrap install task-bootstrap-2.4.19-rmk3
	    bash# pushd bootstrap
	    bash#   rm -fr tmp
	    bash#   ln -s mnt/ramfs/tmp tmp
	    bash# popd
	    bash# mkfs.jffs2 -r bootstrap -o bootstrap.jff2 -e 0x40000 -p
	    bash# tar -zcvf task-bootstrap.tar.gz bootstrap
	  

Using CVS

CVS (Concurrent Version System) is a powerful tool with many options. This section will discuss the most common ways to use CVS for development on handhelds.org projects. There are many other resources that explain all of these options, including:

Please refer to these for an in-depth discussion.

CVS Repositories and Working Copies

The basic concept behind CVS is that there is a repository that stores all versions of all the files associated with a project. Any of the versions can be checked out of the repository. Modified files can be committed, or checked in to the repository as new versions.

To work with a project in CVS, you check out a working copy of the files in a repository. When you check out a copy, you can either get a fixed snapshot, termed a sticky version, or you can check out the head of the main thread of development or one of the branches.

Specifying a CVS Repository

The CVS repository can be indicated to a CVS command in one of three ways:

  • Via the -d flag to CVS commands

  • From the current snapshot. Each directory in a checked out snapshot contains the file CVS/Root, which indicates the repository from which it was checked out.

  • Via the CVSROOT environment variable

If no -d argument is passed, then it looks for CVS/Root. If that is not present, the cvs uses the CVSROOT environment variable. If that is not present, the command fails.

Accessing a CVS Repository via pserver

At handhelds.org, we use two ways to access a CVS repository. The first way is only used for anonymous, read-only access to a repository. This uses the CVS pserver protocol. The pserver sends passwords as cleartext, so we do not use it for anything other than anonymous access. Here is how to connect to a CVS repository using pserver and specifying the repository using the CVSROOT environment variable:

Example 13. Using pserver and CVSROOT

            bash$ export CVSROOT=:pserver:anoncvs@cvs.handhelds.org:/cvs
            bash$ cvs login
            Logging in to :pserver:anoncvs@cvs.handhelds.org:2401/cvs
            CVS Password: anoncvs
            bash$ 
          

You can also use the -d flag to specify the repository:

Example 14. Using pserver and -d cvsroot

            bash$ cvs -d :pserver:anoncvs@cvs.handhelds.org:/cvs login
            Logging in to :pserver:anoncvs@cvs.handhelds.org:2401/cvs
            CVS Password: anoncvs
            bash$ 
          

Accessing a CVS Repository via ssh

Because pserver sends passwords over the network as clear text, we do not allow its use for anyone with write access to the repository. For that, we use ssh. There is no cvs login step required when using ssh. The normal ssh login mechanisms are used when any of the other cvs commands are executed. See the Section called SSH Login Mechanisms for details.

Example 15. CVS via ssh using RSH

Access to the repository can be specified by using the rsh form of CVSROOT along with the environment variable CVS_RSH:
              bash$ export CVSROOT=jamey@cvs.handhelds.org:/cvs
              bash$ export CVS_RSH=ssh
            

As before, the CVS repository can be passed to individual commands with the -d flag:
              bash$ cvs -d jamey@cvs.handhelds.org:/cvs checkout bootldr
              ...
            

Example 16. CVS via ssh using :ext:

Use of ssh can also be specified with the :ext form of CVSROOT:
              bash$ export CVSROOT=:ext:jamey@cvs.handhelds.org:/cvs
              bash$ cvs checkout bootldr
              ...
            

Alternatively:
              bash$ cvs -d :ext:jamey@cvs.handhelds.org:/cvs checkout bootldr
            

CVS Checkout

For normal development, one checks out the head of the main thread of development. For example, to check out the bootldr source code, assuming the CVSROOT environment variable is set. (See the Section called Specifying a CVS Repository

          bash: cvs checkout bootldr
        

CVS Update

One of the features of CVS is the ability to track changes that have been committed to the repository. One uses the cvs update for this:. In this example, we pass the -d flag to cvs update so that it will check out any new directories that might have been committed.

          bash$ cd bootldr
          bash$ cvs update -d
          jamey@rockhopper:/home/jamey/bootldr$ cvs update
          ? bootldr-2.18.26.bin
          cvs server: Updating .
          M Makefile
          P sa1100.h
          U serial.c
          C vfat.c
        

The '?' before bootldr-2.18.26.bin indicates that there is not a copy of this file in the repository.

The 'M' before Makefile indicates that the copy in the working directory is modified relative to what was checked out from the repository.

The 'P' before sa1100.h indicates that the checked out copy was updated via patch.

The 'U' before serial.c indicates that the local copy was updated by fetching a fresh copy of the file. This method is use by CVS for new files and sometimes also for existing files.

The 'C' before vfat.c indicates that there was a local modification on the same line as a modification committed to the repository. This will have to be resolved using an editor, looking for lines bracketed as follows:
            <<<<<<<<
              local change
            ========
              repository change
            >>>>>>>>
          

CVS Commit

Once you have made and tested a change in your working copy, you can commit that change to the repository if you have write-access to the repository using the cvs commit.

It is very important to test changes before committing them, because anyone using cvs update will get the changed code. It is definitely considered bad form to propagate broken code to other people.

In the following example, I pass a changelog message to the cvs commit command with the -m flag. If you do not use this flag, it will start a browser, but I find that one line changelog entries are appropriate for the CVS log. This message, and more detail if necessary, should be put in the projects CHANGELOG file.

          bash$ cvs commit -m 'added FAT12 filesystem support' vfat.c
          Checking in vfat.c;
          /cvs/bootldr/vfat.c,v  <--  vfat.c
          new revision: 1.11; previous revision: 1.10
          done
          bash$ 
        

Of course, the modified CHANGELOG will also have to be committed. It is very important to commit all the files that constitute a patch or change set so that someone who receives these changes via cvs update continues to have a consistent snapshot.

CVS add

In the previous section, cvs update reported a file that was not present in the repository. New files and directories are marked to be added with the cvs add. Once the files are marked, the addition must be committed.

          bash$ cvs add foo.c
          bash$cvs add foo.c
          cvs server: scheduling file `foo.c' for addition
          cvs server: use 'cvs commit' to add this file permanently
          bash$ cvs commit -m 'a test add' foo.c
          RCS file: /cvs/bootldr/doc/foo.c,v
          done
          Checking in foo.c;
          /cvs/bootldr/doc/foo.c,v  <--  foo.c
          initial revision: 1.1
          done
        

CVS remove

Obsolete files are marked to be removed from the repository with the cvs remove and then actually removed with the cvs commit. Of course, because CVS keeps a complete history of all the files that are or ever were active, the file is not actually removed from the repository. It is just marked so that it is no longer checked out from the current version. It can be checked out by checking out previous versions.

          bash$ rm foo.c
          bash$ cvs remove foo.c
          cvs server: scheduling `foo.c' for removal
          cvs server: use 'cvs commit' to remove this file permanently
          bash$ cvs commit -m 'removing obsolete file' foo.c
          Removing foo.c;
          /cvs/bootldr/doc/foo.c,v  <--  foo.c
          new revision: delete; previous revision: 1.1
          done
          bash$
        

CVS log

It is often useful to look at history of a file. The cvs log command will display a list of all the versions of a file, all the tags associated with the file, and the history of all the actions performed on the file.

          bash$ cvs log foo.c
          RCS file: /cvs/bootldr/doc/Attic/foo.c,v
          Working file: foo.c
          head: 1.2
          branch:
          locks: strict
          access list:
          symbolic names:
          keyword substitution: kv
          total revisions: 2;     selected revisions: 2
          description:
          ----------------------------
          revision 1.2
          date: 2002/03/21 14:45:37;  author: jamey;  state: dead;  lines: +0 -0
          removing obsolete file
          ----------------------------
          revision 1.1
          date: 2002/03/21 14:42:08;  author: jamey;  state: Exp;
          a test add
          =============================================================================
        

CVS status command

The cvs status command will report on the current version of a file in the snapshot:

          bash$ cvs status vfat.c
          ===================================================================
          File: vfat.c            Status: Up-to-date

          Working revision:    1.11
          Repository revision: 1.11    /cvs/bootldr/vfat.c,v
          Sticky Tag:          (none)
          Sticky Date:         (none)
          Sticky Options:      (none)
        

CVS diff

To find out more about the changes made to a file, we can use the cvs diff.

          bash$ cvs diff -r 1.10 vfat.c
          Index: vfat.c
          ===================================================================
          RCS file: /cvs/bootldr/vfat.c,v
          retrieving revision 1.10
          retrieving revision 1.11
          diff -r1.10 -r1.11
          280,281c280,283
          <     while (dir->attr) {
          <         if ((dir->attr & vfat_attr_long_name) != vfat_attr_long_name) {
          ---
          >     while (dir->name[0]) {
          >         if (dir->name[0] == 0xE5) {
          >             /* skip deleted entries */
          >         } else if ((dir->attr & vfat_attr_long_name) != vfat_attr_long_name) {
        

The cvs diff command accepts the standard diff options.

Using SSH

SSH Login Mechanisms

This section will describe ssh login mechanisms.