Difference between revisions of "Kernel Size Tuning Guide"

From eLinux.org
Jump to: navigation, search
(Measuring the kernel)
m (Remove link to LinuxTiny page on selenic.com, redirecting to elinux.org now)
 
(39 intermediate revisions by 6 users not shown)
Line 8: Line 8:
 
== Measuring the kernel ==
 
== Measuring the kernel ==
 
There are 3 aspects of kernel size which are important:
 
There are 3 aspects of kernel size which are important:
#the size of the kernel image stored in flash (or other persistent storage)
+
<ol><li>the size of the kernel image stored in flash (or other persistent storage)</li>
#the static size of kernel image in RAM (usually, this will be the size of the uncompressed image)
+
<li>the static size of kernel image in RAM (usually, this will be the size of the uncompressed image)</li>
:* This includes the text, data, and BSS segments of the kernel at the time it is loaded.  The text and BSS segments will stay the same size for the kernel throughout it execution.  However, the data and stack segments may grow according to the needs of the system.
+
:*This includes the text, data, and BSS segments of the kernel at the time it is loaded.  The text and BSS segments will stay the same size for the kernel throughout it execution.  However, the data and stack segments may grow according to the needs of the system.
#the amount of dynamic RAM used by the kernel.
+
<li>the amount of dynamic RAM used by the kernel.</li>
:*This will fluctuate during system execution.  However, there is a baseline amount of memory which is allocated at system startup. Application-specific RAM can be calculated to be above this minimal amount of required RAM.
+
:*This will fluctuate during system execution.  However, there is a baseline amount of memory which is allocated at system startup. Application-specific RAM can be calculated to be above this minimal amount of required RAM.</ol>
  
 
For now, this document ignores Execute-In-Place (XIP) and Data-Read-In-Place (DRIP) techniques, the use of which have an impact on the amount of flash and RAM used by the kernel. See the following online resources for more information about these techniques:
 
For now, this document ignores Execute-In-Place (XIP) and Data-Read-In-Place (DRIP) techniques, the use of which have an impact on the amount of flash and RAM used by the kernel. See the following online resources for more information about these techniques:
[[http://tree.celinuxforum.org/CelfPubWiki/KernelXIP Kernel XIP]]
+
[[Kernel XIP]] and [[Data Read In Place]]
and
 
[[http://tree.celinuxforum.org/CelfPubWiki/DataReadInPlace Data Read In Place]]
 
  
 
==== Measuring the kernel image size ====
 
==== Measuring the kernel image size ====
The compressed kernel image is what is stored in the flash or ROM of the target device.  The size of this image can be obtained by examining the size of the image file in the host filesystem with the '<pre>ls -l</pre>' command:
+
The compressed kernel image is what is stored in the flash or ROM of the target device.  The size of this image can be obtained by examining the size of the image file in the host filesystem with the '<tt>ls -l</tt>' command:
*for example: '<pre>ls -l vmlinuz</pre>' or '<pre>ls -l bzImage</pre>' (or whatever the compressed image name is for your platform.)
+
*for example: '<tt>ls -l vmlinuz</tt>' or '<tt>ls -l bzImage</tt>' (or whatever the compressed image name is for your platform.)
  
 
==== Measuring the kernel text, data and bss segments ====
 
==== Measuring the kernel text, data and bss segments ====
Use the <pre>size</pre> command to determine the size of the text, data, and BSS segments of a kernel image.
+
Use the <tt>size</tt> command to determine the size of the text, data, and BSS segments of a kernel image.
  
 
'''Note''' that the BSS segment is not stored in the kernel image because it can be synthesized at boot time by filling a block of memory with zeros.  Note also that portions of the kernel text and data are set aside in special initialization segments, which are discarded when the kernel finishes booting. Because of these factors, the size command does not give you an exactly correct value for the static kernel RAM size.  However, it can be used as a reasonable estimate.
 
'''Note''' that the BSS segment is not stored in the kernel image because it can be synthesized at boot time by filling a block of memory with zeros.  Note also that portions of the kernel text and data are set aside in special initialization segments, which are discarded when the kernel finishes booting. Because of these factors, the size command does not give you an exactly correct value for the static kernel RAM size.  However, it can be used as a reasonable estimate.
  
To use the size command, run it with the filename of the uncompressed kernel image (which is usually <pre>vmlinux</pre>).
+
To use the size command, run it with the filename of the uncompressed kernel image (which is usually <tt>vmlinux</tt>).
*for example: '<pre>size vmlinux</pre>'
+
* for example: '<tt>size vmlinux</tt>'
  
 
Example output:
 
Example output:
Line 37: Line 35:
 
</pre>
 
</pre>
  
====== Measuring and comparing sub-parts of the kernel ======
+
==== Measuring and comparing sub-parts of the kernel ====
 
In order to find areas where the kernel size can be reduced, it is often useful to break down
 
In order to find areas where the kernel size can be reduced, it is often useful to break down
 
the static size of the kernel by sub-system or by kernel symbol.  The following sections describe how to see the size of each kernel sub-system, how to see the size of individual kernel symbols, and how to compare the size of symbols between two kernel versions.  This is useful because as you make changes to the kernel configuration you can determine what part of the kernel is affected by the change.  From this information you may be able to predict what the affect of the change will be, and decide whether the change is acceptable.
 
the static size of the kernel by sub-system or by kernel symbol.  The following sections describe how to see the size of each kernel sub-system, how to see the size of individual kernel symbols, and how to compare the size of symbols between two kernel versions.  This is useful because as you make changes to the kernel configuration you can determine what part of the kernel is affected by the change.  From this information you may be able to predict what the affect of the change will be, and decide whether the change is acceptable.
  
======== Measuring major kernel subsystems ========
+
===== Measuring major kernel subsystems =====
The major sub-systems of the kernel are put into library object files named <pre>built-in.o</pre> in the corresponding sub-directory for that sub-system within the kernel build directory.  The major sub-directories, at the time of this writing (for kernel 2.6.17) are:
+
The major sub-systems of the kernel are put into library object files named <tt>built-in.o</tt> in the corresponding sub-directory for that sub-system within the kernel build directory.  The major sub-directories, at the time of this writing (for kernel 2.6.17) are:
<pre>init, user, kernel, mm, fs, ipc, security, crypto, block, ltt, drivers, sound, net, lib</pre>
+
<tt>init, user, kernel, mm, fs, ipc, security, crypto, block, ltt, drivers, sound, net, lib</tt>
  
To see the size of the major kernel sections (code, data, and BSS), use the <pre>size</pre> command, with a wildcard for the first level of sub-directory:
+
To see the size of the major kernel sections (code, data, and BSS), use the <tt>size</tt> command, with a wildcard for the first level of sub-directory:
*<pre>size */built-in.o</pre>
+
*<tt>size */built-in.o</tt>
  
You can pipe this output through <pre>sort</pre> to sort by the largest libraries:
+
You can pipe this output through <tt>sort</tt> to sort by the largest libraries:
*<pre>size */built-in.o | sort -n -r -k 4</pre>
+
*<tt>size */built-in.o | sort -n -r -k 4</tt>
  
 
Example output:
 
Example output:
Line 68: Line 66:
 
</pre>
 
</pre>
  
To see even greater detail, you can examine the size of <pre>built-in.o</pre> files even deeper in the kernel build hierarchy, using the <pre>find</pre> command:
+
To see even greater detail, you can examine the size of <tt>built-in.o</tt> files even deeper in the kernel build hierarchy, using the <tt>find</tt> command:
*<pre>find . -name "built-in.o" | xargs size | sort -n -r -k 4 </pre>
+
*<tt>find . -name "built-in.o" | xargs size | sort -n -r -k 4 </tt>
  
 
Example output:
 
Example output:
Line 81: Line 79:
 
</pre>
 
</pre>
  
[[Image:Alert.gif]] '''Note: Please be careful interpreting the results from the size of the <pre>built-in.o</pre> files in sub-directories.  In general, the object files are aggregated into the libraries of parent directories, meaning that many object files will have their size counted twice.  You cannot simply add the columns for an indication of the total kernel size'''
+
{|style="padding: 0 0 0 1em; background-color:#ffcccc;"
 +
|[[Image:Alert.gif]] '''Note: Please be careful interpreting the results from the size of the <tt>built-in.o</tt> files in sub-directories.  In general, the object files are aggregated into the libraries of parent directories, meaning that many object files will have their size counted twice.  You cannot simply add the columns for an indication of the total kernel size'''
 +
|}
  
======== Measuring individual kernel symbols ========
+
===== Measuring individual kernel symbols =====
 
You can measure the size of individual kernel symbols using the 'nm' command.
 
You can measure the size of individual kernel symbols using the 'nm' command.
Using the  <pre>nm --size -r vmlinux</pre>
+
Using the  <tt>nm --size -r vmlinux</tt>
 
<pre>
 
<pre>
 
[tbird@crest ebony]$ nm --size -r vmlinux | head -10
 
[tbird@crest ebony]$ nm --size -r vmlinux | head -10
Line 110: Line 110:
 
*'d' or 'D' for a symbol in the data segment.
 
*'d' or 'D' for a symbol in the data segment.
  
Use '<pre>man nm</pre>' for additional information on the '<pre>nm</pre>' command.
+
Use '<tt>man nm</tt>' for additional information on the '<tt>nm</tt>' command.
  
======== Comparing kernel symbols between two kernel images ========
+
===== Comparing kernel symbols between two kernel images =====
Use the bloat-o-meter command, found in the kernel source <pre>scripts</pre> directory, to compare the symbol sizes between two kernel images.
+
Use the bloat-o-meter command, found in the kernel source <tt>scripts</tt> directory, to compare the symbol sizes between two kernel images.
  
* ''<kernel-src>''<pre>/scripts/bloat-o-meter vmlinux.default vmlinux.altconfig</pre>
+
* ''<kernel-src>''<tt>/scripts/bloat-o-meter vmlinux.default vmlinux.altconfig</tt>
  
 
If you get an error: 'chmod a+x <kernel-src>/scripts/bloat-o-meter'
 
If you get an error: 'chmod a+x <kernel-src>/scripts/bloat-o-meter'
  
Example output:
+
Example output, comparing a baseline kernel to one configured with CONFIG_PRINTK=n:
 +
 
 
<pre>
 
<pre>
[FIXTHIS - need bloat-o-meter output]
+
[] $ ../../linux/scripts/bloat-o-meter vmlinux.baseline vmlinux.no-printk
 +
add/remove: 5/23 grow/shrink: 8/1541 up/down: 1141/-199824 (-198683)
 +
function                                    old    new  delta
 +
proc_ioctl_default                            -    610    +610
 +
proc_reapurb                                  -    296    +296
 +
proc_disconnectsignal                          -      88    +88
 +
proc_releaseinterface                          -      72    +72
 +
proc_claiminterface                            -      36    +36
 +
xprt_adjust_cwnd                            169    182    +13
 +
do_timer                                    1052    1063    +11
 +
i8042_controller_reset                        78      84      +6
 +
serio_init                                  167    172      +5
 +
usb_exit                                      80      81      +1
 +
early_uart_console_init                      45      46      +1
 +
console_unblank                              103    104      +1
 +
console_conditional_schedule                  21      22      +1
 +
parse_early_param                            102    101      -1
 +
machine_emergency_restart                    249    248      -1
 +
console_callback                            239    238      -1
 +
arch_align_stack                              45      44      -1
 +
quirk_p64h2_1k_io                            183    181      -2
 +
printk_time                                    4      -      -4
 +
printk_cpu                                    4      -      -4
 +
oops_timestamp.7                              4      -      -4
 +
neigh_resolve_output                        733    729      -4
 +
msg_level.4                                    4      -      -4
 +
...
 +
de_dump_status                            1586    313    -1273
 +
decode_getfattr                            3156    1748  -1408
 +
ext3_fill_super                            5980    4545  -1435
 +
usbdev_ioctl                                6476    4846  -1630
 +
usb_get_configuration                      4001    1878  -2123
 +
proc_submiturb                              2294      -  -2294
 +
__log_buf                                131072      - -131072
 
</pre>
 
</pre>
  
Line 130: Line 164:
 
The Linux-tiny patch set is a set of patches maintained by Matt Mackall developed with the intent to help a developer reduce the size of the Linux kernel.
 
The Linux-tiny patch set is a set of patches maintained by Matt Mackall developed with the intent to help a developer reduce the size of the Linux kernel.
  
The CELF wiki page describing these patches is at:  
+
These patches are described at: [[Linux Tiny]]
[[Linux Tiny]]
 
  
 
The Linux-tiny patch set includes a number of different patches to allow the kernel to be reduced in size.  Sometimes, the size reductions are accomplished by reducing the number of objects for a particular features (like the number of possible swap areas, or the number of tty discipline structures).  Sometimes, the size reductions are achieved by removing features or functions from the kernel.
 
The Linux-tiny patch set includes a number of different patches to allow the kernel to be reduced in size.  Sometimes, the size reductions are accomplished by reducing the number of objects for a particular features (like the number of possible swap areas, or the number of tty discipline structures).  Sometimes, the size reductions are achieved by removing features or functions from the kernel.
  
Here is a list of the individual Linux-tiny patches that are available for the 2.6.16 kernel:
+
Here is a list of the individual Linux-tiny patches that are available for the 2.6.22 kernel at [[Linux Tiny Patch Details]]
 +
 
  
{| border="1" cellpadding="5" cellspacing="0" align="center"
 
!style="background:#D0E0FF;"|patch
 
!style="background:#D0E0FF;"|type
 
!style="background:#D0E0FF;"|description
 
!style="background:#D0E0FF;"|kernel option
 
|-
 
|use-funit-at-a-time.patch||compiler flag||Add -funit-at-a-time to the gcc compilation flags for building the kernel||None
 
|-
 
|config-net-small.patch||add option||Add CONFIG_NET_SMALL configuration option||Adds CONFIG_NET_SMALL
 
|-
 
|cache_defer_hash.patch||smaller data ||Reduce RPC cache hash table size from PageSize to 512||Uses CONFIG_NET_SMALL
 
|-
 
|unix_socket_table.patch||smaller data||Reduce AF_UNIX socket hash table from 256 to 16 entries                ||Uses CONFIG_NET_SMALL
 
|-
 
|inet_protos.patch||smaller data||Reduce number of internet protocols supported from 256 to 32          ||Uses CONFIG_NET_SMALL
 
|-
 
|flow-cache-small.patch||smaller data||Reduce flow cache hash table from 2^10 (1024) to 2^3 (8)              ||Uses CONFIG_NET_SMALL
 
|-
 
|tg3-oops.patch||bugfix||Handle tg3 ring allocation correctly||None
 
|-
 
|namei-inlines.patch||smaller code||Uninline various functions in namei.c||None
 
|-
 
|buffer-inlines.patch||smaller code||Uninline function in buffer.c||None
 
|-
 
|ext2namei-inlines.patch||smaller code||Uninline ext2_add_nondir function||None
 
|-
 
|kmalloc-accounting.patch||measurement feature||Add kmalloc accounting feature||CONFIG_KMALLOC_ACCOUNTING
 
|-
 
|audit-bootmem.patch||measurement feature||Cause bootmem code to print callers and sizes for allocations||CONFIG_AUDIT_BOOTMEM
 
|-
 
|deprecate-inline.patch||measurement feature||Add system for counting inline usage by generating deprecation warnings||CONFIG_MEASURE_INLINES
 
|-
 
|func-size.patch||measurement feature||Adds a script to count inline function sizes||None
 
|-
 
|tiny-panic.patch||reduced debug feature||Add option to use smaller panic code||CONFIG_FULL_PANIC
 
|-
 
|nopanic.patch||omit debug feature||Make code for kernel panic configurable||CONFIG_PANIC
 
|-
 
|tiny-crc.patch||smaller data ||Allow using function instead of table for CRC32 calculations          ||CONFIG_CRC32_TABLES
 
|-
 
|threadinfo-ool.patch||smaller code ||Inline current() and current_thread_info() on UP (configurable)||CONFIG_INLINE_THREADINFO
 
|-
 
|slob-accounting.patch||measurement feature||Add kmalloc accounting to SLOB allocator||Uses CONFIG_SLOB, CONFIG_KMALLOC_ACCOUNTING
 
|-
 
|mempool-shrink.patch||reduced feature ||Allow disabling mempool allocator feature||CONFIG_MEMPOOL
 
|-
 
|no-translations.patch||omit feature ||Allow omitting support for console charset translation                ||CONFIG_CONSOLE_TRANSLATIONS
 
|-
 
|sysenter.patch||omit feature||Allow disabling syscalls via sysenter (x86-only)||CONFIG_SYSENTER
 
|-
 
|no-aio.patch||omit feature ||Allow disabling Asynchronous IO syscalls and support||CONFIG_AIO
 
|-
 
|no-xattr.patch||omit feature ||Allow disabling Extended Attributes syscalls and support||CONFIG_XATTR
 
|-
 
|fslock.patch||omit feature ||Allow disabling POSIX file locking syscalls and support||CONFIG_FILE_LOCKING
 
|-
 
|ethtool.patch||omit feature ||Allow disabling support for configuring network devices with ethtool program||CONFIG_ETHTOOL
 
|-
 
|inetpeer.patch||omit feature||Allow disabling INET peer data tracking||CONFIG_INETPEER
 
|-
 
|net-filter.patch||omit feature||Allow disabling old-style packet filtering support||CONFIG_NET_SK_FILTER
 
|-
 
|dev_mcast.patch||omit feature ||Allow disabling netdev multicast support||CONFIG_NET_DEV_MULTICAST
 
|-
 
|igmp.patch||omit feature ||Allow disabling IGMP (Internet Group Management Protocol) support - used for multicasts||CONFIG_IGMP
 
|-
 
|binfmt-script.patch||omit feature ||Allow disabling support to run shell scripts via standard "#!" syntax  ||CONFIG_BINFMT_SCRIPT
 
|-
 
|elf-no-aout.patch||omit feature ||Allow disabling support for ELF programs with a.out format loader or libraries||CONFIG_BINFMT_ELF_AOUT
 
|-
 
|max-swapfiles.patch||smaller data ||Make the number of swapfiles configurable||CONFIG_MAX_SWAPFILES_SHIFT
 
|-
 
|ldiscs.patch||smaller data ||Make the number of tty line disciplines configurable||CONFIG_NR_LDISCS
 
|-
 
|max_user_rt_prio.patch||smaller data ||Make the number of RT priority O(1) scheduling queues configurable||CONFIG_MAX_USER_RT_PRIO
 
|-
 
||ide-hwif.patch||smaller data ||Make the number of supported IDE interfaces configurable||CONFIG_IDE_HWIFS
 
|-
 
||sbf.patch||omit feature ||Allow disabling simple bootflag support (x86-only)||CONFIG_BOOTFLAG
 
|-
 
|serial-pci.patch||omit feature||Allow disabling support for PCI serial devices||CONFIG_SERIAL_PCI
 
|-
 
|dmi_blacklist.patch||omit feautre||Allow disabling DMI scanning (x86-only)||CONFIG_DMI_SCAN
 
|-
 
|pci-quirks.patch||omit feature ||Allow disabling of workarounds for various PCI chipset bugs and quirks ||CONFIG_PCI_QUIRKS
 
|-
 
|tsc.patch||omit feature ||Allow disabling use of TSC as kernel timer (x86-only)||CONFIG_X86_TSC_TIMER
 
|-
 
|cpu-support.patch||omit feature ||Allow disabling vendor-specific x86 CPU features (x86-only)  ||CONFIG_PROCESSOR_SELECT, CONFIG_CPU_SUP_* (many)
 
|-
 
|mtrr.patch||continuation patch ||Make MTRR support depend on vendor-specific CPU selection (x86-only)||None
 
|-
 
|movsl-mask.patch||continuation patch||Make movsl mask usage depend on vendor-specific CPU selection (x86-only)||None
 
|-
 
|do-printk.patch||reduced feature||Allow fine-grained control of printk message compilation||CONFIG_PRINTK_FUNC, uses CONFIG_PRINTK
 
|}
 
  
Please note that the last patch in this list ("do-printk") is available separately from the main Linux-tiny patch set.  Please find this patch at: [[http://tree.celinuxforum.org/CelfPubWiki/DoPrintk Do Printk]]
+
Please note that the last patch in this list ("do-printk") is available separately from the main Linux-tiny patch set.  Please find this patch at: [[Do Printk]]
  
 
The patches listed in this table represent patches that can be applied to a 2.6.16 Linux kernel.  However, as of version 2.6.16, many options for reducing the kernel were already
 
The patches listed in this table represent patches that can be applied to a 2.6.16 Linux kernel.  However, as of version 2.6.16, many options for reducing the kernel were already
Line 288: Line 226:
 
|-
 
|-
 
|CONFIG_MAX_USER_RT_PRIO||number of RT priority levels (schedule slots)||100  ||5
 
|CONFIG_MAX_USER_RT_PRIO||number of RT priority levels (schedule slots)||100  ||5
|-
+
|- style="background:#ffcc00;"
|style="background:#ffcc00;"|Other config options  ||These are not in Linux-tiny, but help with size||default||small
+
|Other config options  ||These are not in Linux-tiny, but help with size||default||small
 
|-
 
|-
 
|CONFIG_KALLSYMS      ||load all symbols for debugging/kksymoops      ||Y    ||N
 
|CONFIG_KALLSYMS      ||load all symbols for debugging/kksymoops      ||Y    ||N
Line 341: Line 279:
 
|CONFIG_SCSI          ||support for SCSI devices                      ||Y    ||N +
 
|CONFIG_SCSI          ||support for SCSI devices                      ||Y    ||N +
 
|}
 
|}
 +
  
 
Legend:
 
Legend:
Line 350: Line 289:
 
==== Special Instructions for some kernel options ====
 
==== Special Instructions for some kernel options ====
 
===== How to use CONFIG_PRINTK =====
 
===== How to use CONFIG_PRINTK =====
If the "do-printk" patch is applied, there are two options which control the compilation of printk elements in the kernel:  CONFIG_PRINTK_FUNC and CONFIG_PRINTK.  You can use these options to control how much printk support the kernel provides, and to control on a global basis whether any printk messages at all are compiled into the kernel.  Another special preprocessor variable is also available, called DO_PRINTK, which provides the ability to enable
+
If the "do-printk" patch is applied, there are two options which control the compilation of printk elements in the kernel:  CONFIG_PRINTK_FUNC and CONFIG_PRINTK.  You can use these options to control how much printk support the kernel provides, and to control on a global basis whether any printk messages at all are compiled into the kernel.  Another special preprocessor variable is also available, called DO_PRINTK, which provides the ability to enable printk messages inside a single C compilation unit, even if printk messages are disabled globally.
printk messages inside a single C compilation unit, even if printk messages are disabled globally.
 
  
 
This section explains how to use these features to reduce the kernel size, while still enabling sufficient printk messages to be useful during development and deployment.
 
This section explains how to use these features to reduce the kernel size, while still enabling sufficient printk messages to be useful during development and deployment.
Line 357: Line 295:
 
The CONFIG_PRINTK option disables all of the kernel printk calls.  By setting this option to 'N' in your kernel configuration, all uses of "printk" throughout the kernel source are turned into empty statements, and omitted when the program is compiled. This provides a substantial size savings, since the kernel messages often account for more than 100 kilobytes of  space in the kernel image.  Setting this option to 'N' will not, however, remove the actual <pre>printk</pre> code itself (just the calls to <pre>printk</pre>).
 
The CONFIG_PRINTK option disables all of the kernel printk calls.  By setting this option to 'N' in your kernel configuration, all uses of "printk" throughout the kernel source are turned into empty statements, and omitted when the program is compiled. This provides a substantial size savings, since the kernel messages often account for more than 100 kilobytes of  space in the kernel image.  Setting this option to 'N' will not, however, remove the actual <pre>printk</pre> code itself (just the calls to <pre>printk</pre>).
  
The CONFIG_PRINTK_FUNC option controls whether the <pre>printk</pre> function and various helper functions are compiled into the Linux kernel.  When this is set to 'N', CONFIG_PRINTK
+
The CONFIG_PRINTK_FUNC option controls whether the <pre>printk</pre> function and various helper functions are compiled into the Linux kernel.  When this is set to 'N', CONFIG_PRINTK is automatically set to 'N', and no printk messages are compiled into the kernel.  This usually saves about another 4K of size in the kernel image.
is automatically set to 'N', and no printk messages are compiled into the kernel.  This  
 
usually saves about another 4K of size in the kernel image.
 
  
 
By using both CONFIG_PRINTK and CONFIG_PRINTK_FUNC, you can reduce the size of the kernel image (and that flash and RAM it requires). However, there is a drawback to eliminating all the messages.  Obviously, it is then not possible to get any status, diagnostic or debug messages from the kernel!  Another mechanism is available, which allows you to control on a per-file basis which printk calls are compiled into the kernel.  This is the pre-processor variable DO_PRINTK.
 
By using both CONFIG_PRINTK and CONFIG_PRINTK_FUNC, you can reduce the size of the kernel image (and that flash and RAM it requires). However, there is a drawback to eliminating all the messages.  Obviously, it is then not possible to get any status, diagnostic or debug messages from the kernel!  Another mechanism is available, which allows you to control on a per-file basis which printk calls are compiled into the kernel.  This is the pre-processor variable DO_PRINTK.
  
 
To use DO_PRINTK, set CONFIG_PRINTK to 'N' and CONFIG_PRINTK_FUNC to 'Y' in your kernel configuration.  This will globally disable all printk calls in the kernel. Now, determine the C files where you wish to enable printk messages, and add the line:
 
To use DO_PRINTK, set CONFIG_PRINTK to 'N' and CONFIG_PRINTK_FUNC to 'Y' in your kernel configuration.  This will globally disable all printk calls in the kernel. Now, determine the C files where you wish to enable printk messages, and add the line:
 +
 
<pre>
 
<pre>
 
#define DO_PRINTK 1
 
#define DO_PRINTK 1
 
</pre>
 
</pre>
 +
 
at the top of each file.  Now, the printk calls in those files will be compiled normally. Printk calls in other modules will be omitted.
 
at the top of each file.  Now, the printk calls in those files will be compiled normally. Printk calls in other modules will be omitted.
  
[[Image:Alert.gif]] - '''Important Note: The DO_PRINTK variable controls how the preprocessor will treat printk statements in the code.[[BR]]For this reason, this statement '''MUST''' appear at the top of the file, before any <pre>#include</pre> lines.'''
+
[[Image:Alert.gif]] - '''Important Note:''' The DO_PRINTK variable controls how the preprocessor will treat printk statements in the code. For this reason, this statement '''MUST''' appear at the top of the file, before any <pre>#include</pre> lines.
  
 
In order to change the set of printk messages preserved in the code, you will need to modify the <pre>DO_PRINTK</pre> lines, and recompile the kernel.  (There is no runtime control of the printk calls.) This is a simple mechanism, but it does provide a way to omit '''most''' of the printk messages from the kernel while still preserving some messages that may be useful during
 
In order to change the set of printk messages preserved in the code, you will need to modify the <pre>DO_PRINTK</pre> lines, and recompile the kernel.  (There is no runtime control of the printk calls.) This is a simple mechanism, but it does provide a way to omit '''most''' of the printk messages from the kernel while still preserving some messages that may be useful during
Line 377: Line 315:
  
 
{| border="1" cellpadding="5" cellspacing="0" align="center"
 
{| border="1" cellpadding="5" cellspacing="0" align="center"
! style="background:#ffffcc;" rowspan=".5" colspan="3"|'''Settings'''
+
!style="background:#ffffcc;" colspan="2"|'''Settings'''
! style="background:#ffffcc;"|'''Explanation'''
+
!style="background:#ffffcc;" rowspan="2"|'''Explanation'''
! style="background:#ffffcc;" rowspan=".5"|'''CONFIG_PRINTK_FUNC'''
 
! style="background:#ffffcc;" rowspan=.5"|'''CONFIG_PRINTK'''
 
 
|-
 
|-
 +
!style="background:#ffffcc;"|'''CONFIG_PRINTK_FUNC'''
 +
!style="background:#ffffcc;"|'''CONFIG_PRINTK'''
 +
|-
 +
|Y||Y||This is the default setting for the kernel configuration.  In this setting the <code>printk</code> code is compiled into the kernel, and all printk calls throughout the entire source code are also compiled as part of the kernel.
 +
|-
 +
|Y||N||This leaves the actual printk() routine in the kernel, but disables all calls to printk throughout the entire source code.  However, you can use DO_PRINTK in individual modules to enable the printk calls from those modules.
 +
|-
 +
|N||N||This removes the printk() routine from the kernel, and disables all kernel printk messages, and gives the smallest kernel code and data size.  DO_PRINTK will NOT enable any module-specific printk calls.
 
|}
 
|}
|Y                ||Y            ||This is the default setting for the kernel configuration.  In this setting the <pre>printk</pre> code is compiled into the kernel, and all printk calls throughout the entire source code are also compiled as part of the kernel.||
 
||Y                ||N            ||This leaves the actual printk() routine in the kernel, but disables all calls to printk throughout the entire source code.  However, you can use DO_PRINTK in individual modules to enable the printk calls from those modules.||
 
||N                ||N            ||This removes the printk() routine from the kernel, and disables all kernel printk messages, and gives the smallest kernel code and data size.  DO_PRINTK will NOT enable any module-specific printk calls.||
 
  
 
==== Booting without SysFS ====
 
==== Booting without SysFS ====
 +
 
(copied from linux-tiny wiki)
 
(copied from linux-tiny wiki)
  
Turning off sysfs support can save a substantial amount of memory in some setups. One big
+
Turning off sysfs support can save a substantial amount of memory in some setups. One big downside is that it breaks the normal boot process because the kernel can no longer mapa symbolic device name to the internal device numbers.
downside is that it breaks the normal boot process because the kernel can no longer map
 
a symbolic device name to the internal device numbers.
 
  
Thus, you will need to pass a numeric device number in hex. For example, to boot off
+
Thus, you will need to pass a numeric device number in hex. For example, to boot off /dev/hda1, which has major number 3 and minor 1, you'll need to append a root== option like this:
/dev/hda1, which has major number 3 and minor 1, you'll need to append a root== option
 
like this:
 
  
 
<pre>/boot/vmlinuz root==0x0301 ro
 
<pre>/boot/vmlinuz root==0x0301 ro
Line 402: Line 340:
  
 
==== Booting without /proc fs ====
 
==== Booting without /proc fs ====
It is also possible to boot with <pre>/proc</pre> fs, but many programs expect this psuedo-filesystem
+
It is also possible to boot with <pre>/proc</pre> fs, but many programs expect this psuedo-filesystem to be present and mounted.  For example, <pre>free</pre> and <pre>ps</pre> are two commands which retrieve information from <pre>/proc</pre> in order to run.
to be present and mounted.  For example, <pre>free</pre> and <pre>ps</pre> are two commands which retrieve
 
information from <pre>/proc</pre> in order to run.
 
  
[[list some workarounds here]]
+
'''list some workarounds here'''
  
 
==== Using kernel memory measurement features ====
 
==== Using kernel memory measurement features ====
[FIXTHIS - need instruction on kmalloc accounting, bootmem auditing and counting inlines]
+
[[Image:Alert.gif]] FIXTHIS - need instruction on bootmem auditing and counting inlines - need more detail for kmalloc accounting
====== Kmalloc Accounting ======
+
===== Kmalloc Accounting =====
====== Bootmem Auditing ======
+
This is a features of Linux-tiny, which tracks callers of kmalloc and kfree, and produces
====== Counting Inlines ======
+
summary statistics for kernel memory allocations, as well as detailed information about
 +
specific kmalloc callers.
 +
 
 +
This was first published by Matt Mackall in February of 2005, but was not mainlined at
 +
that time.
 +
 
 +
To see results for kernel allocations, follow these steps:
 +
* turn on the CONFIG_KMALLOC option.  This will show up on the kernel configuration menus as "Enabled accounting of kmalloc/kfree allocations?"
 +
* recompile your kernel
 +
* boot the kernel
 +
* periodically, examine the accounting stats
 +
** cat /proc/kmalloc
 +
 +
See http://lwn.net/Articles/124374/
 +
 
 +
===== Bootmem Auditing =====
 +
===== Counting Inlines =====
  
 
== Outline ==
 
== Outline ==
[FIXTHIS - need to review outline and fill in missing material]
+
[[Image:Alert.gif]] FIXTHIS - need to review outline and fill in missing material
* Tuning the kernel
+
*Tuning the kernel
  * how to measure kernel size
+
:*how to measure kernel size
    * in-kernel size reporting - kmalloc accounting
+
::*in-kernel size reporting - kmalloc accounting
    * bloat-o-meter
+
::* bloat-o-meter
 
      
 
      
  * kernel configuration options
+
*kernel configuration options
    * mainline options
+
:* mainline options
    * optional features
+
:* optional features
    * minimal config
+
:* minimal config
    * sufficient API?
+
:* sufficient API?
      * POSIX compliance
+
::* POSIX compliance
      * LSB compliance
+
::* LSB compliance
      * LTP compliance
+
::* LTP compliance
  * file systems
+
*file systems
    * comparison of file system sizes
+
:*comparison of file system sizes
  * compiler options for reducing size
+
*compiler options for reducing size
    * gcc -os
+
:*gcc -os
    * gcc -whole-program
+
:*gcc -whole-program
    *
+
* online resources:
+
*online resources:
    * bloatwatch
+
:*bloatwatch
    * kconfigsize
+
:*kconfigsize
  
 
== References ==
 
== References ==
* Linux-tiny project web site: http://www.selenic.com/linux-tiny/
+
* eLinux wiki Linux-tiny page: [[Linux Tiny]]
* CELF page about Linux-tiny: http://tree.celinuxforum.org/CelfPubWiki/LinuxTiny
+
* Matt Mackall's {{pdf|linux tiny.pdf|Linux-tiny presentation}}
* Matt Mackall's [http://tree.celinuxforum.org/CelfPubWiki/TechConference2005Docs?action==AttachFile&do==get&target==linux-tiny.pdf Linux-tiny presentation]
+
* CE Linux Forum resources for reducing system size: [[System Size]]
* CE Linux Forum resources for reducing system size: http://tree.celinuxforum.org/CelfPubWiki/SystemSizeResources
 
  
 
== Appendices ==
 
== Appendices ==
Line 450: Line 401:
  
 
==== Appendix B - Configuration Option Details ====
 
==== Appendix B - Configuration Option Details ====
[Want to fill in this section with deails about configuration options]
+
[[Image:Alert.gif]]Want to fill in this section with details about configuration options.
  
 
For each option, would like to document:
 
For each option, would like to document:
* what is size affect for different option values
+
*what is size affect for different option values
  * KernelSizeTuningGuide/ConfigOptionImpact describes kernel size and RAM usage impact affected by each configuration option listed in "Kernel Configuration Options" above, on i386.
+
:*This page & [[Kernel Size Tuning Guide Config Option Impact]] describe kernel size and RAM usage impact affected by each configuration option listed in "Kernel Configuration Options" above, on i386.
  
* what is affect of performance, functionality, etc.
+
*what is affect of performance, functionality, etc.
* what programs (if any) will stop working if option is turned off (or reduced)
+
*what programs (if any) will stop working if option is turned off (or reduced)
  
 
==== Appendix C - Things to research ====
 
==== Appendix C - Things to research ====
* miniconfigs
+
*miniconfigs
* how to use an initramfs (to avoid using NFS-mounted rootfs)
+
*how to use an initramfs (to avoid using NFS-mounted rootfs)
* how to use a local fs (to avoid using NFS-mounted rootfs)
+
*how to use a local fs (to avoid using NFS-mounted rootfs)
* Eric Biederman's turning off CONFIG_BLOCK - will any FS work after this??
+
*Eric Biederman's turning off CONFIG_BLOCK - will any FS work after this??
  * he got a 2.6.1 kernel (presumably all_no) to: "191K bzImage and a 323K text segment".  See [http://groups.google.com/group/linux.kernel/browse_frm/thread/d688fe97611dcc7e/7e685339b152b7f3?hl==en&lr==&ie==UTF-8&rnum==1&prev==/groups%3Fhl%3Den%26lr%3D%26ie%3DUTF-8%26selm%3D19Kuz-872-3%2540gated-at.bofh.it#7e685339b152b7f3 here].
+
:*he got a 2.6.1 kernel (presumably all_no) to: "191K bzImage and a 323K text segment".  See [http://groups.google.com/group/linux.kernel/browse_frm/thread/d688fe97611dcc7e/7e685339b152b7f3?hl==en&lr==&ie==UTF-8&rnum==1&prev==/groups%3Fhl%3Den%26lr%3D%26ie%3DUTF-8%26selm%3D19Kuz-872-3%2540gated-at.bofh.it#7e685339b152b7f3 here].
* why is networking so big??
+
*why is networking so big??
* why are file systems so big??
+
*why are file systems so big??
* capture serial output from kernel for size measurement (see grabserial program)
+
*capture serial output from kernel for size measurement (see grabserial program)
  
== Modification History ==
+
[[Category:Kernel Size Tuning Guide]]
||<:rowbgcolor=="#88ccff"> '''Date'''||<:> '''Version'''||<:> '''Description'''||
+
[[Category:System Size]]
||2006-11-01 ||0.5.1||Added link to configuration option impact data page on appendix B||
 
||2006-10-27 ||0.5.0||Renamed appendix B, small modifications for Jamboree 11 presentation||
 
||2006-09-14 ||0.4.1||Moved to CELF public wiki for forum collaboration ||
 
||2006-09-14 ||0.4.0||Added linux-tiny patch table, config option table, and CONFIG_PRINTK usage||
 
||2006-09-11 ||0.2.0||Added content for memory measurement||
 
||2006-09-07 ||0.1.0||Created document and initial outline.||
 

Latest revision as of 03:26, 4 February 2017

This document describes how to configure the Linux kernel to use a small amount of memory and flash.

Alert.gif Note: This document is a work in progress. Please feel free to add material anywhere you have additional information or data. Sections of this document which need additional work are denoted with [FIXTHIS] markers.

Introduction

One big problem area when using Linux in an embedded project is the size of the Linux kernel.

Measuring the kernel

There are 3 aspects of kernel size which are important:

  1. the size of the kernel image stored in flash (or other persistent storage)
  2. the static size of kernel image in RAM (usually, this will be the size of the uncompressed image)
    • This includes the text, data, and BSS segments of the kernel at the time it is loaded. The text and BSS segments will stay the same size for the kernel throughout it execution. However, the data and stack segments may grow according to the needs of the system.
  3. the amount of dynamic RAM used by the kernel.
    • This will fluctuate during system execution. However, there is a baseline amount of memory which is allocated at system startup. Application-specific RAM can be calculated to be above this minimal amount of required RAM.

For now, this document ignores Execute-In-Place (XIP) and Data-Read-In-Place (DRIP) techniques, the use of which have an impact on the amount of flash and RAM used by the kernel. See the following online resources for more information about these techniques: Kernel XIP and Data Read In Place

Measuring the kernel image size

The compressed kernel image is what is stored in the flash or ROM of the target device. The size of this image can be obtained by examining the size of the image file in the host filesystem with the 'ls -l' command:

  • for example: 'ls -l vmlinuz' or 'ls -l bzImage' (or whatever the compressed image name is for your platform.)

Measuring the kernel text, data and bss segments

Use the size command to determine the size of the text, data, and BSS segments of a kernel image.

Note that the BSS segment is not stored in the kernel image because it can be synthesized at boot time by filling a block of memory with zeros. Note also that portions of the kernel text and data are set aside in special initialization segments, which are discarded when the kernel finishes booting. Because of these factors, the size command does not give you an exactly correct value for the static kernel RAM size. However, it can be used as a reasonable estimate.

To use the size command, run it with the filename of the uncompressed kernel image (which is usually vmlinux).

  • for example: 'size vmlinux'

Example output:

   text    data     bss     dec     hex filename
2921377  369712  132996 3424085  343f55 vmlinux

Measuring and comparing sub-parts of the kernel

In order to find areas where the kernel size can be reduced, it is often useful to break down the static size of the kernel by sub-system or by kernel symbol. The following sections describe how to see the size of each kernel sub-system, how to see the size of individual kernel symbols, and how to compare the size of symbols between two kernel versions. This is useful because as you make changes to the kernel configuration you can determine what part of the kernel is affected by the change. From this information you may be able to predict what the affect of the change will be, and decide whether the change is acceptable.

Measuring major kernel subsystems

The major sub-systems of the kernel are put into library object files named built-in.o in the corresponding sub-directory for that sub-system within the kernel build directory. The major sub-directories, at the time of this writing (for kernel 2.6.17) are: init, user, kernel, mm, fs, ipc, security, crypto, block, ltt, drivers, sound, net, lib

To see the size of the major kernel sections (code, data, and BSS), use the size command, with a wildcard for the first level of sub-directory:

  • size */built-in.o

You can pipe this output through sort to sort by the largest libraries:

  • size */built-in.o | sort -n -r -k 4

Example output:

 731596   53144   33588  818328   c7c98 drivers/built-in.o
 687960   24972    2648  715580   aeb3c fs/built-in.o
 547844   19508   28052  595404   915cc net/built-in.o
 184072    6256   32440  222768   36630 kernel/built-in.o
 141956    3300    2852  148108   2428c mm/built-in.o
  68048    1804    1096   70948   11524 block/built-in.o
  26216     768       0   26984    6968 crypto/built-in.o
  17744    2412    2124   22280    5708 init/built-in.o
  20780     292     124   21196    52cc ipc/built-in.o
  18768      68       0   18836    4994 lib/built-in.o
   2116       0       0    2116     844 security/built-in.o
    134       0       0     134      86 usr/built-in.o
   text    data     bss     dec     hex filename

To see even greater detail, you can examine the size of built-in.o files even deeper in the kernel build hierarchy, using the find command:

  • find . -name "built-in.o" | xargs size | sort -n -r -k 4

Example output:

 731596   53144   33588  818328   c7c98 ./drivers/built-in.o
 687960   24972    2648  715580   aeb3c ./fs/built-in.o
 547844   19508   28052  595404   915cc ./net/built-in.o
 260019    9824    4944  274787   43163 ./net/ipv4/built-in.o
 184072    6256   32440  222768   36630 ./kernel/built-in.o
...
Alert.gif Note: Please be careful interpreting the results from the size of the built-in.o files in sub-directories. In general, the object files are aggregated into the libraries of parent directories, meaning that many object files will have their size counted twice. You cannot simply add the columns for an indication of the total kernel size
Measuring individual kernel symbols

You can measure the size of individual kernel symbols using the 'nm' command. Using the nm --size -r vmlinux

[tbird@crest ebony]$ nm --size -r vmlinux | head -10
00008000 b read_buffers
00004000 b __log_buf
00003100 B ide_hwifs
000024f8 T jffs2_garbage_collect_pass
00002418 T journal_commit_transaction
00002400 b futex_queues
000021a8 t jedec_probe_chip
00002000 b write_buf
00002000 D init_thread_union
00001e6c t tcp_ack

Legend: The columns of this output are:

  1. size in bytes (in hexadecimal)
  2. symbol type
  3. symbol name.

The symbol type is usually one of:

  • 'b' or 'B' for a symbol in the BSS segment (uninitialized data),
  • 't' or 'T' for a symbol in the text segment (code), or
  • 'd' or 'D' for a symbol in the data segment.

Use 'man nm' for additional information on the 'nm' command.

Comparing kernel symbols between two kernel images

Use the bloat-o-meter command, found in the kernel source scripts directory, to compare the symbol sizes between two kernel images.

  • <kernel-src>/scripts/bloat-o-meter vmlinux.default vmlinux.altconfig

If you get an error: 'chmod a+x <kernel-src>/scripts/bloat-o-meter'

Example output, comparing a baseline kernel to one configured with CONFIG_PRINTK=n:

[] $ ../../linux/scripts/bloat-o-meter vmlinux.baseline vmlinux.no-printk
add/remove: 5/23 grow/shrink: 8/1541 up/down: 1141/-199824 (-198683)
function                                     old     new   delta
proc_ioctl_default                             -     610    +610
proc_reapurb                                   -     296    +296
proc_disconnectsignal                          -      88     +88
proc_releaseinterface                          -      72     +72
proc_claiminterface                            -      36     +36
xprt_adjust_cwnd                             169     182     +13
do_timer                                    1052    1063     +11
i8042_controller_reset                        78      84      +6
serio_init                                   167     172      +5
usb_exit                                      80      81      +1
early_uart_console_init                       45      46      +1
console_unblank                              103     104      +1
console_conditional_schedule                  21      22      +1
parse_early_param                            102     101      -1
machine_emergency_restart                    249     248      -1
console_callback                             239     238      -1
arch_align_stack                              45      44      -1
quirk_p64h2_1k_io                            183     181      -2
printk_time                                    4       -      -4
printk_cpu                                     4       -      -4
oops_timestamp.7                               4       -      -4
neigh_resolve_output                         733     729      -4
msg_level.4                                    4       -      -4
...
de_dump_status                             1586     313    -1273
decode_getfattr                             3156    1748   -1408
ext3_fill_super                             5980    4545   -1435
usbdev_ioctl                                6476    4846   -1630
usb_get_configuration                       4001    1878   -2123
proc_submiturb                              2294       -   -2294
__log_buf                                 131072       - -131072

Kernel Size Tuning features

The Linux kernel includes a number of options for to control the features and options it supports. The kernel, over time, has accumulated a large set of features and capabilities. But many features are not needed in Consumer Electronics products. By carefully tuning the kernel options, you can omit many parts of the kernel and save memory in your product.

Linux-tiny patches

The Linux-tiny patch set is a set of patches maintained by Matt Mackall developed with the intent to help a developer reduce the size of the Linux kernel.

These patches are described at: Linux Tiny

The Linux-tiny patch set includes a number of different patches to allow the kernel to be reduced in size. Sometimes, the size reductions are accomplished by reducing the number of objects for a particular features (like the number of possible swap areas, or the number of tty discipline structures). Sometimes, the size reductions are achieved by removing features or functions from the kernel.

Here is a list of the individual Linux-tiny patches that are available for the 2.6.22 kernel at Linux Tiny Patch Details


Please note that the last patch in this list ("do-printk") is available separately from the main Linux-tiny patch set. Please find this patch at: Do Printk

The patches listed in this table represent patches that can be applied to a 2.6.16 Linux kernel. However, as of version 2.6.16, many options for reducing the kernel were already available in Linux. A list of options, both from these patches and from existing code, which are interesting for tuning the kernel size is provided in the section: "Kernel configuration Options"

How to configure the kernel

[FIXTHIS - need detailed kernel configuration instructions]

  • use 'make menuconfig'
  • perform thorough testing of your library and applications with the smaller config
  • development vs. deployment configurations
  • describe all_no config - most times it won't boot.

Kernel Configuration Options

Here is a table of kernel configuration options, including a description, the default value for a kernel, and the recommended value for a smaller configuration of the kernel:


CONFIG option Description Default Small
CONFIG_CORE_SMALL tune some kernel data sizes N Y
CONFIG_NET_SMALL tune some net-related data sizes N Y
CONFIG_KMALLOC_ACCOUNTING turn on kmalloc accounting N Y *
CONFIG_AUDIT_BOOTMEM print out all bootmem allocations N Y *
CONFIG_DEPRECATE_INLINES cause compiler to emit info about inlines N Y *
CONFIG_PRINTK allow disable of printk code and message data Y N
CONFIG_BUG allow elimination of BUG (and BUG_ON??) code Y N
CONFIG_ELF_CORE allow disabling of ELF core dumps Y N
CONFIG_PROC_KCORE allow disabling of /proc/kcore Y N
CONFIG_AIO allow disabling of async IO syscalls Y N
CONFIG_XATTR allow disabling of xattr syscalls Y N
CONFIG_FILE_LOCKING allow disabling of file locking syscalls Y N
CONFIG_DIRECTIO allow disabling of direct IO support Y N
CONFIG_MAX_SWAPFILES_SHIFT number of swapfiles 5 0
CONFIG_NR_LDISCS number of tty line disciplines 16 2
CONFIG_MAX_USER_RT_PRIO number of RT priority levels (schedule slots) 100 5
Other config options These are not in Linux-tiny, but help with size default small
CONFIG_KALLSYMS load all symbols for debugging/kksymoops Y N
CONFIG_SHMEM allow disabling of shmem filesystem Y N +
CONFIG_SWAP allow disabling of support for a swap segment (virtual memory) Y N
CONFIG_SYSV_IPC allow disabling of support for System V IPC Y N +
CONFIG_POSIX_MQUEUE allow disabling of POSIX message queue support Y N +
CONFIG_SYSCTL allow disabling of sysctl support Y N +
CONFIG_LOG_BUF_SHIFT control size of kernel printk buffer 14 11
CONFIG_UID16 allow support for 16-bit uids Y ??
CONFIG_CC_OPTIMIZE_FOR_SIZE Use gcc -os to optimize for size Y Y
CONFIG_MODULES allow support for kernel loadable modules Y N +
CONFIG_KMOD allow support for automatic kernel module loading Y N
CONFIG_PCI allow support for PCI bus and devices Y Y -
CONFIG_XIP_KERNEL allow support for kernel Execute-in-Place N N
CONFIG_MAX_RESERVE_AREA ?? ?? ??
CONFIG_BLK_DEV_LOOP support for loopback block device Y Y -
CONFIG_BLK_DEV_RAM support for block devices for RAM filesystems Y Y -
CONFIG_BLK_DEV_RAM_COUNT Number of block devices for RAM filesystems 16 2?
CONFIG_BLK_DEV_RAM_SIZE Size of block device struct for RAM filesystems 4096 ??
CONFIG_IOSCHED_AS Include Anticipatory IO scheduler Y Y
CONFIG_IOSCHED_DEADLINE Include Deadline IO scheduler Y N +
CONFIG_IOSCHED_CFQ Include CFQ IO scheduler Y N +
CONFIG_IP_PNP support for IP autoconfiguration Y N +
CONFIG_IP_PNP_DHCP support for IP autoconfiguration via DHCP Y N +
CONFIG_IDE support for IDE devices Y N +
CONFIG_SCSI support for SCSI devices Y N +


Legend:

  • "Y *" - Set to 'Y' for measurement during development, and set to 'N' for deployment.
  • "N +" - Whether you can set this to 'N' depends on whether this feaure is needed by your applications.
  • "Y -" - You probably need this, but it might we worth checking to see if you don't.

Special Instructions for some kernel options

How to use CONFIG_PRINTK

If the "do-printk" patch is applied, there are two options which control the compilation of printk elements in the kernel: CONFIG_PRINTK_FUNC and CONFIG_PRINTK. You can use these options to control how much printk support the kernel provides, and to control on a global basis whether any printk messages at all are compiled into the kernel. Another special preprocessor variable is also available, called DO_PRINTK, which provides the ability to enable printk messages inside a single C compilation unit, even if printk messages are disabled globally.

This section explains how to use these features to reduce the kernel size, while still enabling sufficient printk messages to be useful during development and deployment.

The CONFIG_PRINTK option disables all of the kernel printk calls. By setting this option to 'N' in your kernel configuration, all uses of "printk" throughout the kernel source are turned into empty statements, and omitted when the program is compiled. This provides a substantial size savings, since the kernel messages often account for more than 100 kilobytes of space in the kernel image. Setting this option to 'N' will not, however, remove the actual

printk

code itself (just the calls to

printk

). The CONFIG_PRINTK_FUNC option controls whether the

printk

function and various helper functions are compiled into the Linux kernel. When this is set to 'N', CONFIG_PRINTK is automatically set to 'N', and no printk messages are compiled into the kernel. This usually saves about another 4K of size in the kernel image.

By using both CONFIG_PRINTK and CONFIG_PRINTK_FUNC, you can reduce the size of the kernel image (and that flash and RAM it requires). However, there is a drawback to eliminating all the messages. Obviously, it is then not possible to get any status, diagnostic or debug messages from the kernel! Another mechanism is available, which allows you to control on a per-file basis which printk calls are compiled into the kernel. This is the pre-processor variable DO_PRINTK.

To use DO_PRINTK, set CONFIG_PRINTK to 'N' and CONFIG_PRINTK_FUNC to 'Y' in your kernel configuration. This will globally disable all printk calls in the kernel. Now, determine the C files where you wish to enable printk messages, and add the line:

#define DO_PRINTK 1

at the top of each file. Now, the printk calls in those files will be compiled normally. Printk calls in other modules will be omitted.

Alert.gif - Important Note: The DO_PRINTK variable controls how the preprocessor will treat printk statements in the code. For this reason, this statement MUST appear at the top of the file, before any

#include

lines. In order to change the set of printk messages preserved in the code, you will need to modify the

DO_PRINTK

lines, and recompile the kernel. (There is no runtime control of the printk calls.) This is a simple mechanism, but it does provide a way to omit most of the printk messages from the kernel while still preserving some messages that may be useful during

development or on a deployed product.

In review, there are basically 3 different settings combinations for CONFIG_PRINTK_FUNC and CONFIG_PRINTK that make sense:

Settings Explanation
CONFIG_PRINTK_FUNC CONFIG_PRINTK
Y Y This is the default setting for the kernel configuration. In this setting the printk code is compiled into the kernel, and all printk calls throughout the entire source code are also compiled as part of the kernel.
Y N This leaves the actual printk() routine in the kernel, but disables all calls to printk throughout the entire source code. However, you can use DO_PRINTK in individual modules to enable the printk calls from those modules.
N N This removes the printk() routine from the kernel, and disables all kernel printk messages, and gives the smallest kernel code and data size. DO_PRINTK will NOT enable any module-specific printk calls.

Booting without SysFS

(copied from linux-tiny wiki)

Turning off sysfs support can save a substantial amount of memory in some setups. One big downside is that it breaks the normal boot process because the kernel can no longer mapa symbolic device name to the internal device numbers.

Thus, you will need to pass a numeric device number in hex. For example, to boot off /dev/hda1, which has major number 3 and minor 1, you'll need to append a root== option like this:

/boot/vmlinuz root==0x0301 ro

Booting without /proc fs

It is also possible to boot with

/proc

fs, but many programs expect this psuedo-filesystem to be present and mounted. For example,

free

and

ps

are two commands which retrieve information from

/proc

in order to run.

list some workarounds here

Using kernel memory measurement features

Alert.gif FIXTHIS - need instruction on bootmem auditing and counting inlines - need more detail for kmalloc accounting

Kmalloc Accounting

This is a features of Linux-tiny, which tracks callers of kmalloc and kfree, and produces summary statistics for kernel memory allocations, as well as detailed information about specific kmalloc callers.

This was first published by Matt Mackall in February of 2005, but was not mainlined at that time.

To see results for kernel allocations, follow these steps:

  • turn on the CONFIG_KMALLOC option. This will show up on the kernel configuration menus as "Enabled accounting of kmalloc/kfree allocations?"
  • recompile your kernel
  • boot the kernel
  • periodically, examine the accounting stats
    • cat /proc/kmalloc

See http://lwn.net/Articles/124374/

Bootmem Auditing
Counting Inlines

Outline

Alert.gif FIXTHIS - need to review outline and fill in missing material

  • Tuning the kernel
  • how to measure kernel size
  • in-kernel size reporting - kmalloc accounting
  • bloat-o-meter
  • kernel configuration options
  • mainline options
  • optional features
  • minimal config
  • sufficient API?
  • POSIX compliance
  • LSB compliance
  • LTP compliance
  • file systems
  • comparison of file system sizes
  • compiler options for reducing size
  • gcc -os
  • gcc -whole-program
  • online resources:
  • bloatwatch
  • kconfigsize

References

Appendices

Appendix A - Sample minimum configuration for ARM

[FIXTHIS - need ARM minimum config.]

Appendix B - Configuration Option Details

Alert.gifWant to fill in this section with details about configuration options.

For each option, would like to document:

  • what is size affect for different option values
  • what is affect of performance, functionality, etc.
  • what programs (if any) will stop working if option is turned off (or reduced)

Appendix C - Things to research

  • miniconfigs
  • how to use an initramfs (to avoid using NFS-mounted rootfs)
  • how to use a local fs (to avoid using NFS-mounted rootfs)
  • Eric Biederman's turning off CONFIG_BLOCK - will any FS work after this??
  • he got a 2.6.1 kernel (presumably all_no) to: "191K bzImage and a 323K text segment". See here.
  • why is networking so big??
  • why are file systems so big??
  • capture serial output from kernel for size measurement (see grabserial program)