Tips

Coding Tips

This section is adapted from the old kernelhacking-HOWTO by Rusty Russell.

No memory protection

If you corrupt memory the whole machine will crash. Are you sure you can't do what you want in userspace? Consider the consequences of corrupting a RAM copy of a filesystems super block just before it is written back to disk... Consider the number of recent kernel releases with filesystem corruption bugs; it really isn't that hard to do!

No floating point or MMX

The FPU context is not saved; you would mess with some user process' FPU. If you really want to do this, you would have to explicitly save/restore the full FPU state (and avoid context switches). It is generally a bad idea; use fixed point arithmetic first.

A rigid stack limit

The stack is about 8K in 2.4, some is used by the process descriptor and the rest is shared with interrupts so you can't use it all. Avoid deep recursion and huge local arrays on the stack (allocate them dynamically instead).

Portable Code

The Linux kernel is portable; let's keep it that way. Your code should be 64-bit clean, and endian-independent (FIXME: expand on what this means in practice). You should also minimize CPU specific code, so inline assembly should be cleanly encapsulated and minimized (hence put in the architecture specific parts of the source tree) to ease porting.

Proving Code

Kernel programming is by nature challenging; you have few of the "safety nets" that user space programmers take for granted. The write-test cycle is also longer, meaning each line of kernel code takes longer to produce.

You can save yourself a lot of time by writing, debugging and testing as much of your code as possible in userspace before incorporating it into the kernel. Obviously, not all code can be developed this way, but a significant proportion can.

Coding Style

Hopefully, you will be aiming to get some of your code into the kernel at some stage. Even if you don't, there is a good chance you will post some of your code to the Linux Kernel Mailing List at some stage, perhaps as part of a request for help, after you have done your homework of course. You can improve the chances of a successful submission/help request by using the "right" coding style.

Understandably, Linus wants a consistent coding style throughout the source tree, so expects contributions that follow his preferred conventions. Although you may not agree with them, you had better get used to using them! Take a good at and inwardly digest Documentation/CodingStyle.

Commenting Code

Your emphasis here should be on explaining why your code does what it does, not how. If you feel the need to explain how your code works, consider re-writing it! You may find it helpful to deliberately over comment your code during development/debugging then trim it back before submission. The idea here is that the comments may jog your memory during the debugging phase, concerning logic, approach, rationale and assumptions used as the code was written.

Protect Data Structures

During development it is often a good idea to protect important data structures with "magic numbers". Magic numbers consist of a field in the data structure which holds a random number, of your choice. When accessing or modifying the data structure, the magic number field can be checked for the expected value. If the correct value is not found, the data structure may have been corrupted, or the pointer to that data structure may be corrupted.

Magic numbers can be used to detect critical conditions and take appropriate action e.g. invoke an "Oops". Suppose that the copy of a filesystems super block in memory has become corrupted by an array over-run. Writing that corrupted data structure back to the disk would catastrophic. If the data structure had been protected by a magic number, the corruption would probably have been detected and the disastrous write prevented. For super critical data structures, it may be worth placing two different magic numbers, one at the start and one at the end.

A list of magic numbers already in use can be found in ~/Documentation/magic-number.txt. If you use any magic numbers, you should add them to the list, especially for code that may be submitted.

General Development Tips

Keep a log book

It is good practice to keep a step by step record of your work. Eventually, you will need all the juicy details of something you did two months ago and unless you happen to be gifted with an exceptional memory, recalling everything will be near on impossible. It is usually the "gotchas" that are especially valuable later on. A detailed work log can also be very useful when it comes to helping another member of the kernel community. The Kernel debugging part of this document started life as hand written notes in a log book!

Whether you maintain a hard, written copy or an electronic copy is up to you; both approaches have advantages.

Maintaining a stable system

Staying on the bleeding edge of kernel development is a risky business, however it is possible to contribute to current kernel development and minimise the risk of serious problems by:

  • Making regular backups.

  • Exercising caution before applying incremental patches. Obviously, more caution should be exercised for more critical systems.

More to come on this, possibly a flow diagram of recommended practice.

Avoiding RSI

Mention of RSI (Repetitive Strain Injury) may seem out of place in this document. Unfortunately, some of the most talented, long term contributors to the kernel are plagued by RSI; you should take note of this and take appropriate preventive action.

One of the best sources of information on this subject is the Typing Injury FAQ.

Choosing Your First Project

Some people will be reading this document simply out of interest or to find out if kernel programming is of interest. Others may have a particular goal in mind; writing a new device driver or filesystem perhaps. Whichever scenario is true of you, this chapter contains information relevant to those thinking of embarking on their first kernel programming project.