Where to Get The Linux Kernel SourcesAll of the major Linux distributions ( Craftworks, Debian, Slackware, Red Hat etcetera) include the kernel sources in them. Usually the Linux kernel that got installed on your Linux system was built from those sources. By their very nature these sources tend to be a little out of date so you may want to get the latest sources from one of the web sites mentioned in chapter www-appendix. They are kept on ftp://ftp.cs.helsinki.fi and all of the other web sites shadow them. This makes the Helsinki web site the most up to date, but sites like MIT and Sunsite are never very far behind.
$ cd /usr/src/linux $ patch -p1 < patch-2.0.30
How The Kernel Sources Are ArrangedAt the very top level of the source tree /usr/src/linux you will see a number of directories:
- The arch subdirectory contains all of the architecture specific kernel code. It has further subdirectories, one per supported architecture, for example i386 and alpha.
- The include subdirectory contains most of the include files needed to build the kernel code. It too has further subdirectories including one for every architecture supported. The include/asm subdirectory is a soft link to the real include directory needed for this architecture, for example include/asm-i386. To change architectures you need to edit the kernel makefile and rerun the Linux kernel configuration program.
- This directory contains the initialization code for the kernel and it is a very good place to start looking at how the kernel works.
- This directory contains all of the memory management code. The architecture specific memory management code lives down in arch/*/mm/, for example arch/i386/mm/fault.c.
- All of the system's device drivers live in this directory. They are further sub-divided into classes of device driver, for example block.
- This directory contains the kernels inter-process communications code.
- This is simply a directory used to hold built modules.
- All of the file system code. This is further sub-divided into directories, one per supported file system, for example vfat and ext2.
- The main kernel code. Again, the architecture specific kernel code is in arch/*/kernel.
- The kernel's networking code.
- This directory contains the kernel's library code. The architecture specific library code can be found in arch/*/lib/.
- This directory contains the scripts (for example awk and tk scripts) that are used when the kernel is configured.
Where to Start LookingA large complex program like the Linux kernel can be rather daunting to look at. It is rather like a large ball of string with no end showing. Looking at one part of the kernel often leads to looking at several other related files and before long you have forgotten what you were looking for. The next subsections give you a hint as to where in the source tree the best place to look is for a given subject.
System Startup and InitializationOn an Intel based system, the kernel starts when either loadlin.exe or LILO has loaded the kernel into memory and passed control to it. Look in arch/i386/kernel/head.S for this part. Head.S does some architecture specific setup and then jumps to the main() routine in init/main.c.
Memory ManagementThis code is mostly in mm but the architecture specific code is in arch/*/mm. The page fault handling code is in mm/memory.c and the memory mapping and page cache code is in mm/filemap.c. The buffer cache is implemented in mm/buffer.c and the swap cache in mm/swap_state.c and mm/swapfile.c.
KernelMost of the relevent generic code is in kernel with the architecture specific code in arch/*/kernel. The scheduler is in kernel/sched.c and the fork code is in kernel/fork.c. The bottom half handling code is in include/linux/interrupt.h. The task_struct data structure can be found in include/linux/sched.h.
PCIThe PCI pseudo driver is in drivers/pci/pci.c with the system wide definitions in include/linux/pci.h. Each architecture has some specific PCI BIOS code, Alpha AXP's is in arch/alpha/kernel/bios32.c.
Interprocess CommunicationThis is all in ipc. All System V IPC objects include an ipc_perm data structure and this can be found in include/linux/ipc.h. System V messages are implemented in ipc/msg.c, shared memory in ipc/shm.c and semaphores in ipc/sem.c. Pipes are implemented in ipc/pipe.c.
Interrupt HandlingThe kernel's interrupt handling code is almost all microprocessor (and often platform) specific. The Intel interrupt handling code is in arch/i386/kernel/irq.c and its definitions in include/asm-i386/irq.h.
Device DriversMost of the lines of the Linux kernel's source code are in its device drivers. All of Linux's device driver sources are held in drivers but these are further broken out by type:
- block device drivers such as ide (in ide.c). If you want to look at how all of the devices that could possibly contain file systems are initialized then you should look at device_setup() in drivers/block/genhd.c. It not only initializes the hard disks but also the network as you need a network to mount nfs file systems. Block devices include both IDE and SCSI based devices.
- This the place to look for character based devices such as ttys, serial ports and mice.
- All of the CDROM code for Linux. It is here that the special CDROM devices (such as Soundblaster CDROM) can be found. Note that the ide CD driver is ide-cd.c in drivers/block and that the SCSI CD driver is in scsi.c in drivers/scsi.
- This are the sources for the PCI pseudo-driver. A good place to look at how the PCI subsystem is mapped and initialized. The Alpha AXP PCI fixup code is also worth looking at in arch/alpha/kernel/bios32.c.
- This is where to find all of the SCSI code as well as all of the drivers for the scsi devices supported by Linux.
- This is where to look to find the network device drivers such as the DECChip 21040 PCI ethernet driver which is in tulip.c.
- This is where all of the sound card drivers are.