Part III - Kernel
This is the third part of our tour through the NetBSD source tree. After we have talked about the various components that build up the userland, we will concentrate on the kernel source now. It is located in /usr/src/sys, with the /sys symlink being a well-known abbreviation to reach the system's kernel source.Let's remember what happens when building a kernel: after editing the kernel config file located in /sys/arch/<arch>/conf and running config(8) on it, a number of files are created in /sys/arch/<arch>/compile/KERNELNAME. The header files contain data about what and how many devices to include, as well as other data for the system's configuration. Besides that, a Makefile is created, that is used to build the kernel from source. The interesting point to note here is that there is only one Makefile that will locate and compile all the needed sources and place the object files in the .../compile/KERNELNAME directory. In NetBSD, there is no recursive tree-walk of the whole source tree utilizing several Makefiles to build the various sub-trees of the kernel source. This allows building kernels for several configurations and platforms from the same source, without different builds tripping across each other.
Still, the various parts of the NetBSD kernel are placed in various subdirectories that we will have a closer look at now. Under /usr/src/sys, there are:
- adosfs, coda, filecorefs, isofs, msdosfs, nfs, ntfs:
- These are various filesystems used directly by NetBSD to access data. Some of the filesystems' primary goal is to help in exchanging data between the machine's native operating system (AmigaOS's adosfs, Acorn Computers RISC OS's filecorefs, ...), while others implement filesystems that can be found on many systems (isofs, nfs, ...).
- ufs:
- The Unix (User) File System is the base of the native filesystem used in NetBSD. Ancient (AT&T) Unix filesystems only allowed up to 14 chars long filenames, there were no symlinks etc. The problems were solved by the Berkely computer scientists implementing BSD Unix. Their filesystem implementation serves as a base for several filesystems based on it these days, using various ways of data layout on the disk.
The filesystems are stored in the "ufs" subdirectory, filesystems contained in there include
- ext2fs: Linux' ext2fs
- lfs: Log structured filesystem
- mfs: Memory filesystem, for things like in-core /tmp
- ufs: The native NetBSD filesystem
- ffs: General routines of the Berkeley Fast File System, utilized by the other UFS-based filesystems, including things like softdeps.
- miscfs:
- This directory contains further filesystems that aren'd directly related to physical storage. Instead they implement various layered filesystems for services like data translation or routines for implementing kernel features. Using the virtual filesystem operations table, it is easy to change behaviour of a operation upon certain conditions, e.g. mapping operations to deadfs on a file who's filedescriptors were revoke(2)'d.
The filesystems included here are:
- deadfs: Implements operations that don't modify any data and instead return indications of invalid IO. Used to revoke(2) file descriptors.
- fdesc: Maps a process' file descriptors into filesystem space, depending on the accessing process. Can be mounted on /dev/fd using mount_fdesc(8).
- fifofs: Implements FIFOs using Unix domain sockets internally
- genfs: Generic filesystem functions that mostly return errors of some kind - bad filedescriptor, bad operation, or just does no operation at all. Used for implementing deadfs etc.
- kernfs: This filesystem is usually mounted under /kern and provides various informations about the running system, like kernel version, system time etc.
- nullfs: Used to "mirror" one directory tree onto another directory, providing the same tree on both mount points. Also known as loopback mount - see mount_null(8) for more information.
- overlay: The operation of this filesystem is similar to the null filesystem, the implementation allows using this filesystem as a base for further layered filesystems though, as all VFS operations are defined. See mount_overlay(8) for more information.
- portal: The portal filesystem provides an service that allows descriptors such as sockets to be made available in the filesystem namespace following conversion rules given in a config file. See the mount_portal(8) manpage for further information.
- procfs: Similar to kernfs, this filesystem is usually mounted on /proc and allows accessing various data about processes. It is used by ps(1) and other utilities. See mount_proc(8) for more information.
- specfs: Implements routines to access special devices. The filesystem provides a filesystem interface, and calls the device-specific routines depending on the device's type, major and minor number.
- syncfs: Operations used to implement the ioflush kernel thread that writes out modified pages to disk.
- umapfs: A filesystem for re-mapping UIDs/GIDs, useful e.g. when mounting a NFS volume from a server that has a different set of UIDs/GIDs than the local machine.
- union: This layered filesystem allows merging two filesystems, providing a view as if they were mounted on the same mountpoint. Modifications go either to the "upper" or to the "lower" layer, which allows mounting a CDROM (read-only :), and mounting an empty but writable directory over it, making it e.g. possible to do a compile on a source expanded on the CDROM. See mount_union(8) for further details.
- deadfs: Implements operations that don't modify any data and instead return indications of invalid IO. Used to revoke(2) file descriptors.
- compat:
- This directory contains code for emulating binary compatibility with various non-NetBSD operating systems as well as with old NetBSD binaries. It includes:
- aout: This subsystem is used to run native NetBSD a.out binaries on systems that made the transition to the ELF executable format. As for most emulations, the shared library loader ld.so, shared libs etc. are looked for in /etc/aout first.
- common: Various common routines used by all emulations like system call table translation routines; also contains compat code for prior NetBSD releases, see the COMPAT_* kernel options in options(4).
- freebsd: mostly a few glue routines for running FreeBSD/i386 a.out and ELF binaries; See the compat_freebsd(8) manpage for details on setting things up!
- hpux: To run native HP/UX programs on the Motorola based hp300/hp400 machines. Adjusts a fair number of calls, including terminal IO, signals, IO, etc.
- ibcs2: This code implements the Intel Binary Compatibility Suite version2 used for running SCO programs on i386, but also for general compatibility with AT&T System V.3 which is used on the VAX port. Maybe it should have been named COMPAT_SVR3 - the compat_ibcs2(8) manpage contains more data.
- linux: Code to run a.out and ELF Linux binaries for a number of hardware platforms, including alpha, arm32, i386, powerpc, mips, m68k, sparc and sparc64. One of the special things of the Linux emulation is that Linux uses a different system call table on each port, which makes maintaining things a bit more interesting. The code is seperated in a "common" directory that applies to all platforms, and various architecture specific directories for different CPUs. The compat_linux(8) manpage contains more information on using the system, and there are also several packages in pkgsrc that help in setting up the necessary shared libraries etc. to run Linux binaries like Netscape or Acrobat Reader.
- m68k4k: Some of the m68k ports used to use a pagesize of 4k instead of the 8k common today. This code helps in maintaining binary compatibility with old binaries that still use 4k.
- netbsd32: Used by 64bit systems like sparc64 to run native 32bit binaries, mapping the programs' 32bit args to the 64bit args used by LP64 systems' kernels.
- aout: This subsystem is used to run native NetBSD a.out binaries on systems that made the transition to the ELF executable format. As for most emulations, the shared library loader ld.so, shared libs etc. are looked for in /etc/aout first.
