System Minimization

Strategies for reducing Linux's footprint, leaving more resources for the application or letting engineers further reduce the hardware cost of the device.
Additional Kernel Tweaking Recommendations

Although the Linux-tiny Project covers a lot of ground, several additional configuration changes will result in substantial footprint reductions:

  1. Remove ext2/3 support and use a different filesystem: the ext2/3 filesystem is large, a little more than 32K. Most engineers enable a Flash filesystem, but don't disable ext2/3, wasting memory in the process.

  2. Remove support for sysctl: sysctl allows the user to tweak kernel parameters at runtime. In most embedded devices, the kernel configuration is known and won't change, making this feature a wasted 1K.

  3. Reduce IPC options: most systems can do without SysV IPC features (grep your code for msgget, msgct, msgsnd and msgrcv) and POSIX message queues (grep for mq_*[a-z]), and removing them scores another 18K.

Seeing the Effect of Your Changes

The size command reports the amount of code and data in an object file. This is different from the output of the ls command, which reports the number of bytes in the filesystem.

For example, a kernel compiled with an armv5l cross-compiler reports the following:

# armv5l-linux-size vmlinx

   text    data     bss     dec     hex filename
2080300   99904   99312 2279516  22c85c vmlinux

The text section is the code (discovering the historical reason the code is in the text section is an exercise left to the reader) emitted by the compiler. The data section contains the values for globals and other values used to initialize static symbols. The bss section contains static data that is zeroed out as part of initialization.

Although this data is revealing, it doesn't show what parts of the system are consuming memory. There isn't a way to query vmlinux for that information, but looking at the files linked together to create vmlinux is the next best thing. To get this information, use find to locate the built-in.o files in the kernel project and pass those results to size:

# find . -name "built-in.o" | xargs armv5l-linux-size 
 ↪--totals | sort -n -k4

The output of this command is similar to the following:

   text    data     bss     dec     hex filename
 189680   16224   33944  239848   3a8e8 ./kernel/built-in.o
 257872   10056    5636  273564   42c9c ./net/ipv4/built-in.o
 369396    9184   34824  413404   64edc ./fs/built-in.o
 452116   15820   11632  479568   75150 ./net/built-in.o
 484276   36744   14216  535236   82ac4 ./drivers/built-in.o
3110478  180000  159241 3449719  34a377 (TOTALS) 

This technique makes spotting code that occupies a large amount of space obvious, so engineers working on a project can remove those features first. When taking this approach, users shouldn't forget to do a clean make between builds, as dropping a feature from the kernel doesn't mean that the object file from the prior build will be deleted.

For those new to the Linux kernel, a common question is how to associate some built-in.o file with an option in the kernel configuration program. This can be done by looking at the Makefile and the Kconfig file in the directory. The Makefile will contain a line that looks like this:

obj-$(CONFIG_ATALK)     += p8022.o psnap.o

which will result in the files on the right-hand side being built when the user sets the configuration variable CONFIG_ATALK. However, the kernel configuration tool typically doesn't readily expose the underling configuration variable names. To find the link between the variable name and what's visible, look for the variable name, sans the CONFIG_, in the files (Kconfig) used to drive the kernel configuration editor:

find . -name Kconfig -exec fgrep -H -C3 "config ATALK" {} \;

which produces the following output:

./drivers/net/appletalk/Kconfig-# Appletalk driver configuration
./drivers/net/appletalk/Kconfig:config ATALK
./drivers/net/appletalk/Kconfig-  tristate "Appletalk protocol support"
./drivers/net/appletalk/Kconfig-        select LLC
./drivers/net/appletalk/Kconfig-        ---help---

There's still some hunting to do, as the user needs to find where “Appletalk protocol support” appears in the configuration hierarchy, but at least there's a clear idea of what's being sought.