Memory Savers

Updated 30/08/95

Paul Gortmaker

Linux Memory Savers

This page has various Linux memory saver patches that I have put together.

There are still lots of people out there running Linux on 386 boxes with 4MB ram and older/smaller hard disks. These patches implement options that will allow these users to trim some excess (unused) functionality from their kernels and reclaim some of that valuable memory for running applications. Note that memory taken up by the kernel is hardwired to RAM and can't be swapped to disk, thus reducing the amount of real memory available to run user programs and the like.

Most of these patches are against the current 1.2.x kernel, as it is a bit smaller than the 1.3.x kernels to begin with. If you are tight on memory, you are best to run the latest 1.2.x kernel as opposed to the latest 1.3.x development series.

Here are some of the areas where you can "trim the fat".

The RAM Disk
The "old" Disk Driver
The Modules Code
The Old init Code
The Serial Driver
The Floppy Driver
The ne2000 Driver
The 3c503 Driver
The SCSI Blacklist
The printk() Ring Buffer
The Kswap Patches
Removing IBM ThinkPad Support
The `-m386' GCC option

As a more drastic alternative, you can `downgrade' to a 1.0.9 kernel. For those that can't recall, this was the last (i.e. stable) release of the 1.0 series before starting the 1.1 development series. As a quick test, I compiled a 1.0.9 kernel `out of the box' to see how it compared memorywise against my trimmed 1.2.13 kernel. It beat it hands down! For my config, the trimmed 1.2.13 kernel weighed in at 512k code and 148kB data. The stock 1.0.9 kernel with the same config weighed in at a mere 388kB code and 168kB data. I then quickly applied by hand some of the above list (ram / modules / init / serial / ne2k / printk) and had it down to a lean-n-mean 384kB code and 152kB data!! That is a 104kB saving over the trimmed 1.2.13 kernel. This is an excellent kernel to run on 4MB machines. Here is a patch against the 1.0.9 tree that incorporates the above five from the list. Note that some (such as the Thinkpad hack or the reduced hd driver) don't apply to the 1.0.9 kernels, as they weren't in there yet to begin with, so there is nothing to `fix' so to speak.

The RAM disk

Patch to make the ramdisk a config option. Face it, you never use it except for boot/recovery disks and the like. Available for v1.2.12. With this in place, the file ramdisk.c is not even compiled unless you select ramdisk support. This should be another small memory saving that will help low memory machines.

The "old" disk driver

A patch to remove all IDE support from the "old" hard disk driver. Seeing as ide.c now uses all the IDE specific features in addition to the standard ST-506 hard disk specification, the old disk driver may as well return to its original featureless ST-506 form. This will be a good choice for users with MFM/RLL or ESDI drives that can use the memory savings a lot more than the IDE features. Users that don't wish to use the extended features of their IDE drive(s) can also use this patch as well. There should be no risk in using this patch, as all it mainly does is remove code that is IDE specific. I have tested it in a two drive IDE system and a one drive MFM system. Just compare the compiled sizes of hd.c with my patch, hd.c without my patch, and ide.c as seen below, for 1.3.14. (This also doesn't account for the extra 1/2kB per IDE drive that was dynamically allocated to to store the IDE drive information.)

# size drivers/block/hd.o.patched
text data bss dec hex
5440 2228 4 7672 1df8
# size drivers/block/hd.o.orig
text data bss dec hex
8992 2324 48 11364 2c64
# size drivers/block/ide.o
text data bss dec hex
17992 4488 96 22576 5830

The "low-fat-diet" hard disk driver is available for v1.2.12 kernels.

The Modules Code

A patch to remove all module support for those that are on low memory machines, or those that never use modules. This is done by using ``#ifdef CONFIG_MODULES'' and adding it as a make config option. Note that this patch is for 1.2.x kernels. I will eventually update it for the 1.3.x kernels.

For those who were complaining about the modules stuff adding bloat, it can be pulled out quite easily. A big win is dumping modules.c, ksyms.c and a good chunk of scsi.c for loading and unloading host adaptors. Also gone are (un)register_netdev, unregister_filesystem and (un)register_binfmt. Note that you *can't* dump register_fiesystem, (un)register_blkdev and (un)register_chrdev because these are also used by non-modules. (However, this could be easily changed...) Of course /proc/ksyms and /proc/modules disappear as well.

The only files that didn't include <linux/config.h> already were scsi.c and modules.c (ironic huh?) Of course the module syscalls are still listed in unistd.h and entry.S, but they are just dummies that return -ENOSYS like those in kernel/sys.c, so that running insmod on a non-module kernel doesn't do anything silly. Hopefully this can go into 1.3.x someday.

The Old init Code

Many moons ago, when more people had heard of Minix than Linux, Linux did not have Poe's or MvS's init packages. The kernel would look for "/etc/rc" and/or "/bin/sh" to start as process number one. Even now that "/etc/init" and lately "/sbin/init" have been in widespread use for a long time, this old code still remains in the kernel. This patch against 1.2.x kernels removes that old code, along with a 1kB static buffer that it used. Ideally this old code should be removed from distribution kernels as well. (Thanks to Michael A. Griffith for reminding me of this one.)

The Serial driver

Almost all people have only two (or four) serial ports. Yet in drivers/char/serial.c there is a large table of possible serial devices called rs_table. This table has 37 entries. You can safely delete all but the ones you are using, that being the top two, or four if you have four serial ports installed. (Thanks to Alan Cox for mentioning this one.)

The Floppy driver

The average person has at either a 1.44MB 3.5" drive, and/or a 1.2MB 5.25" drive. And they usually never use any strange floppy formats. The usual formats are 360kB, 720kB, 1.2MB and 1.44MB, and none of the others are used. This patch removes the support for 2.88MB drives, and for all the 30 or so other formats that 99% of us never use.

The ne2000 driver

For ne2000 users, you can make a one line change to drivers/net/ne.c that will get rid of a large table of non-conforming cards, and its associated code. If you don't have a "bad clone" you can just delete or comment out the line that says


The 3c503 driver

As you may or may not know, the 3c503 has the ability to support PIO transfers to the card (akin to a ne2000) instead of the standard (read faster/better) shared memory implementation. However, since it is slower, you shouldn't use a 3c503 in PIO mode. If you do, the linux driver will print a message like "REJUMPER FOR SHARED MEMORY" at boot, and then still try and use it in the crippled PIO mode.

This patch for the 1.2.x series kernels just #ifdef's out all the PIO code based on whether you have defined CONFIG_EL2_PIO, for a 20% reduction in the driver size, as seen below.

With PIO support:
text data bss dec hex
3576 44 0 3620 e24
-rw------- 1 root root 4964 Apr 13 19:50 3c503.o

Without PIO support:
text data bss dec hex
2700 44 0 2744 ab8
-rw------- 1 root root 4005 Apr 15 15:33 3c503.o

The SCSI blacklist

Some old (and even some new!) SCSI devices are poorly designed so that if they are "asked" by the SCSI host adapter as to whether they contain multiple devices such as a multiple disk CD-ROM, they will lock-up. The kernel keeps a huge list of (at present 34) devices that have this problem in drivers/scsi/scsi.c. You can cut this device_list down to just the NULL entry at the end if you don't have any of these devices, or if you configured your kernel to only ask about LUN #1.

The printk() Ring Buffer

The printk() routine uses a 4kB static ring buffer to store kernel messages in while waiting for klogd() to read them. The only time this many unread messages pile up is at boot before klogd() is started. But you can read those by using the Shift+Page_Up key sequence. You can go into kernel/printk.c and change the #define LOG_BUF_LEN 4096 to a smaller value like 512, for a saving of 3.5kB. This will still leave room for over six full (80 character) lines of kernel messages to be buffered.

There is also a 1kB buffer ("buf") allocated to deal with the incoming data passed in with a printk() call. No single printk() calls in the kernel are so huge (or broken) as to dump a whole kB in a single call, and so you can cut this back to 256 bytes, which is still the equivalent of more than three full lines of text. (You could allocate this buffer dynamically with kmalloc(), but things will get ugly if you run out of memory, and then try to do allocate a buffer so you can do a printk("Out of memory\n");!!!)

The Kswap Patches

These are patches by Stephen C. Tweedie who has also done a lot of work on the ext2 filesystem. These patches don't actually save you any memory, but instead they improve the swapping performance on low memory machines. For more details on the gains/implementations and such, here are some of Stephen's mails that I saved. (The dates are encoded in the URLs)

Stephen's latest version of his kswap patches can be found here.

Removing IBM ThinkPad Support

Once again IBM has made an incompatibility. They seem to have done something funny with the last 4kB of RAM at the end of the 640kB region. The Linux kernel won't touch this 4kB by default for fear of upsetting the IBM ThinkPad. If you don't have an IBM ThinkPad, you can re-claim this 4kB by simply changing the value 0x9f000 to an 0xA0000 in linux/arch/i386/mm/init.c. If you are real lazy, here is a patch for the 1.2.x kernels to do that for you. (Thanks to Thomas Graichen for pointing this one out.)

The `-m386' GCC option

When you compile a kernel with the `-m486' option, GCC then alignes internal data structures on data boundaries that will be favourable for the cache structure on an i486 CPU. This can leave small `holes' between the end of one data structure, and the start of another, which accounts for the slightly larger output. So if you compile linux with `-m386' instead, then you will end up with a slightly smaller (actually more tightly packed) kernel. You won't be able to notice any significant performace decrease in everyday usage either.

If you have any other memory saver tips/patches,
e-mail me, and I will add them to the list.

Back to the top...