2001-11-05 11:53:34

by Jan-Benedict Glaw

[permalink] [raw]
Subject: Limited RAM - how to save it?

Hi!

I'm working on a 4MB linux system (for a customer) which has quite
limited resources at all:

- 4MB RAM
- 386 or 486 like processor (9..16 BogoMIPS)
- < 100MB HDD
- Quite a lot user space running:-(

For me, 4MB seems to be a problem. I've stripped diwn the applications
quite a lot, but 4MB behaves very slow and unresponsible. Adding only
one more MB solves any performance problem! I've made a small patch
practically removing printk() from kernel which helps a lot (patch
attached below). Basically, the running kernel is ~160KB smaller!
Are there further methods of saving space? I've already done some
other things, but these don't help that much:

- A maximum of 64 concurrent processes
- Only 32 PTYs

If you've got further ideas on getting the kernel a bit smaller,
would be nice to get a mail dropped...

MfG, JBG


diff -Nur linux-2.2.19/Documentation/Configure.help linux-CUSTOM-2.2.19/Documentation/Configure.help
--- linux-2.2.19/Documentation/Configure.help Sun Mar 25 18:37:29 2001
+++ linux-CUSTOM-2.2.19/Documentation/Configure.help Mon Nov 5 11:30:47 2001
@@ -4942,6 +4942,14 @@
important data. This is primarily of use to people trying to debug
the middle and upper layers of the SCSI subsystem. If unsure, say N.

+Smaller kernel by omitting most messages
+CONFIG_NO_PRINTK
+ Enabling this option will result in a smaller kernel by removing
+ most text strings. This is only useful for emdedded systems where
+ you've got to live with <= 4MB of RAM. I386-only for now...
+
+ If unsure, say no.
+
Fibre Channel support
CONFIG_FC4
This is an experimental support for storage arrays connected to
diff -Nur linux-2.2.19/arch/i386/config.in linux-CUSTOM-2.2.19/arch/i386/config.in
--- linux-2.2.19/arch/i386/config.in Sun Mar 25 18:37:29 2001
+++ linux-CUSTOM-2.2.19/arch/i386/config.in Mon Nov 5 11:01:28 2001
@@ -210,5 +221,6 @@

#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+bool 'Eleminate *most* printk()s' CONFIG_NO_PRINTK
endmenu

diff -Nur linux-2.2.19/arch/i386/kernel/head.S linux-CUSTOM-2.2.19/arch/i386/kernel/head.S
--- linux-2.2.19/arch/i386/kernel/head.S Sun Mar 25 18:31:45 2001
+++ linux-CUSTOM-2.2.19/arch/i386/kernel/head.S Fri Nov 2 11:21:42 2001
@@ -315,7 +315,7 @@
movl %ax,%ds
movl %ax,%es
pushl $int_msg
- call SYMBOL_NAME(printk)
+ call SYMBOL_NAME(real_printk)
popl %eax
popl %ds
popl %es
diff -Nur linux-2.2.19/arch/i386/kernel/traps.c linux-CUSTOM-2.2.19/arch/i386/kernel/traps.c
--- linux-2.2.19/arch/i386/kernel/traps.c Sun Mar 25 18:37:30 2001
+++ linux-CUSTOM-2.2.19/arch/i386/kernel/traps.c Fri Nov 2 11:53:32 2001
@@ -135,16 +135,16 @@
esp = regs->esp;
ss = regs->xss & 0xffff;
}
- printk("CPU: %d\nEIP: %04x:[<%08lx>]\nEFLAGS: %08lx\n",
+ oops_printk("CPU: %d\nEIP: %04x:[<%08lx>]\nEFLAGS: %08lx\n",
smp_processor_id(), 0xffff & regs->xcs, regs->eip, regs->eflags);
- printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
+ oops_printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
regs->eax, regs->ebx, regs->ecx, regs->edx);
- printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
+ oops_printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
regs->esi, regs->edi, regs->ebp, esp);
- printk("ds: %04x es: %04x ss: %04x\n",
+ oops_printk("ds: %04x es: %04x ss: %04x\n",
regs->xds & 0xffff, regs->xes & 0xffff, ss);
store_TR(i);
- printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
+ oops_printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current);

/*
@@ -152,18 +152,18 @@
* time of the fault..
*/
if (in_kernel) {
- printk("\nStack: ");
+ oops_printk("\nStack: ");
stack = (unsigned long *) esp;
for(i=0; i < kstack_depth_to_print; i++) {
if (((long) stack & 8191) == 0)
break;
if (i && ((i % 8) == 0))
- printk("\n ");
- printk("%08lx ", *stack++);
+ oops_printk("\n ");
+ oops_printk("%08lx ", *stack++);
}
- printk("\nCall Trace: ");
+ oops_printk("\nCall Trace: ");
if (!esp || (esp & 3))
- printk("Bad ESP value.");
+ oops_printk("Bad ESP value.");
else {
stack = (unsigned long *) esp;
i = 1;
@@ -184,21 +184,21 @@
(addr <= (unsigned long) &_etext)) ||
((addr >= module_start) && (addr <= module_end))) {
if (i && ((i % 8) == 0))
- printk("\n ");
- printk("[<%08lx>] ", addr);
+ oops_printk("\n ");
+ oops_printk("[<%08lx>] ", addr);
i++;
}
}
}
- printk("\nCode: ");
+ oops_printk("\nCode: ");
if (!regs->eip || regs->eip==-1)
- printk("Bad EIP value.");
+ oops_printk("Bad EIP value.");
else {
for(i=0;i<20;i++)
- printk("%02x ", ((unsigned char *)regs->eip)[i]);
+ oops_printk("%02x ", ((unsigned char *)regs->eip)[i]);
}
}
- printk("\n");
+ oops_printk("\n");
}

spinlock_t die_lock;
@@ -207,7 +207,7 @@
{
console_verbose();
spin_lock_irq(&die_lock);
- printk("%s: %04lx\n", str, err & 0xffff);
+ oops_printk("%s: %04lx\n", str, err & 0xffff);
show_registers(regs);
spin_unlock_irq(&die_lock);
do_exit(SIGSEGV);
diff -Nur linux-2.2.19/include/linux/kernel.h linux-CUSTOM-2.2.19/include/linux/kernel.h
--- linux-2.2.19/include/linux/kernel.h Sun Mar 25 18:31:03 2001
+++ linux-CUSTOM-2.2.19/include/linux/kernel.h Mon Nov 5 12:19:04 2001
@@ -9,6 +9,7 @@

#include <stdarg.h>
#include <linux/linkage.h>
+#include <linux/config.h>

/* Optimization barrier */
/* The "volatile" is due to gcc bugs */
@@ -54,8 +55,16 @@

extern int session_of_pgrp(int pgrp);

-asmlinkage int printk(const char * fmt, ...)
+asmlinkage int real_printk(const char * fmt, ...)
__attribute__ ((format (printf, 1, 2)));
+
+#ifdef CONFIG_NO_PRINTK
+# define printk(format, arg...) do {} while(0)
+#else
+# define printk(format, arg...) real_printk(format, ## arg)
+#endif /* CONFIG_NO_PRINTK */
+
+#define oops_printk(format, arg...) real_printk(format, ## arg)

#if DEBUG
#define pr_debug(fmt,arg...) \
diff -Nur linux-2.2.19/kernel/ksyms.c linux-CUSTOM-2.2.19/kernel/ksyms.c
--- linux-2.2.19/kernel/ksyms.c Sun Mar 25 18:31:02 2001
+++ linux-CUSTOM-2.2.19/kernel/ksyms.c Fri Nov 2 11:07:04 2001
@@ -357,7 +357,7 @@

/* misc */
EXPORT_SYMBOL(panic);
-EXPORT_SYMBOL(printk);
+EXPORT_SYMBOL(real_printk);
EXPORT_SYMBOL(sprintf);
EXPORT_SYMBOL(vsprintf);
EXPORT_SYMBOL(kdevname);
diff -Nur linux-2.2.19/kernel/printk.c linux-CUSTOM-2.2.19/kernel/printk.c
--- linux-2.2.19/kernel/printk.c Sun Mar 25 18:31:02 2001
+++ linux-CUSTOM-2.2.19/kernel/printk.c Fri Nov 2 11:01:21 2001
@@ -249,7 +249,7 @@
return do_syslog(type, buf, len);
}

-asmlinkage int printk(const char *fmt, ...)
+asmlinkage int real_printk(const char *fmt, ...)
{
va_list args;
int i;


2001-11-05 13:02:25

by Matt Bernstein

[permalink] [raw]
Subject: Re: Limited RAM - how to save it?

You might like to patch an older Linux than 2.2 :)
dietlibc might help userspace, too.. (though I don't know if you can link
against it)

At 12:52 +0100 Jan-Benedict Glaw wrote:

>I'm working on a 4MB linux system (for a customer) which has quite
>limited resources at all:
>
> - 4MB RAM
> - 386 or 486 like processor (9..16 BogoMIPS)
> - < 100MB HDD
> - Quite a lot user space running:-(

2001-11-05 20:22:40

by H. Peter Anvin

[permalink] [raw]
Subject: Re: Limited RAM - how to save it?

Followup to: <[email protected]>
By author: Jan-Benedict Glaw <[email protected]>
In newsgroup: linux.dev.kernel
>
> I'm working on a 4MB linux system (for a customer) which has quite
> limited resources at all:
>
> - 4MB RAM
> - 386 or 486 like processor (9..16 BogoMIPS)
> - < 100MB HDD
> - Quite a lot user space running:-(
>
> For me, 4MB seems to be a problem. I've stripped diwn the applications
> quite a lot, but 4MB behaves very slow and unresponsible. Adding only
> one more MB solves any performance problem! I've made a small patch
> practically removing printk() from kernel which helps a lot (patch
> attached below). Basically, the running kernel is ~160KB smaller!
> Are there further methods of saving space? I've already done some
> other things, but these don't help that much:
>

4 MB was the practical minimum for even the very early versions of
Linux. I would probably suggest backrevving to 2.0 (which is still
maintained) or even 1.2 (which isn't) for a start...

-hpa
--
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt <[email protected]>

2001-11-05 22:14:17

by Alan

[permalink] [raw]
Subject: Re: Limited RAM - how to save it?

> 4 MB was the practical minimum for even the very early versions of
> Linux. I would probably suggest backrevving to 2.0 (which is still
> maintained) or even 1.2 (which isn't) for a start...

There is no 1.2 kernel tree that is secure from remote attack

2001-11-05 22:16:07

by H. Peter Anvin

[permalink] [raw]
Subject: Re: Limited RAM - how to save it?

Alan Cox wrote:

>>4 MB was the practical minimum for even the very early versions of
>>Linux. I would probably suggest backrevving to 2.0 (which is still
>>maintained) or even 1.2 (which isn't) for a start...
>>
> There is no 1.2 kernel tree that is secure from remote attack
>

Doesn't matter much if your system is a standalone embedded system, does
it? (Not that I know if the original poster's system was such, but such
systems definitely exist in plenty.)

-hpa

2001-11-06 07:03:17

by Lars Brinkhoff

[permalink] [raw]
Subject: Re: Limited RAM - how to save it?

Jan-Benedict Glaw <[email protected]> writes:
> I'm working on a 4MB linux system (for a customer) which has quite
> limited resources [...] If you've got further ideas on getting the
> kernel a bit smaller, would be nice to get a mail dropped...

I started a port of Linux 2.3.99 to a MIPS device which usually has 2M
flash and 4M RAM.

To reduce the size of the text and data sections, I sorted the output
of the "size" command and investigated the files with the largest
sections.

These are the memory-saving changes I arrived at. They are not really
tested, so some of them may break some functionality. Also, I don't
know whether they apply to the current kernels.

fs/dcache.c

Changed HASH_BITS from 14 to 8. This reduces the size of the
cache from 128K to 2K.

fs/inode.c

Changed HASH_BITS from 14 to 8. This reduces the size of the
cache from 128K to 2K.

include/linux/blk.h

Changed NR_REQUEST from 256 to 16. This reduces the number of
requests that can be queued. The size of the queue is reduced
from 16K to 1K.

include/linux/major.h

Changed MAX_BLKDEV and MAX_CHRDEV from 256 to 10 and 20,
respectively. This reduces the number of block and character
devices and saves about 40K.

kernel/printk.c

Changed LOG_BUF_LEN from 16384 bytes to 2048 bytes.

include/linux/tty.h

Changed NR_PTYS and NR_LDISCS from 256 and 16, respectively,
to 16 and 4, respectively. Saved about 12K.

Warning: this change may break the pty driver, in which case
further modifications will have to be done to
drivers/char/pty.c.

kernel/panic.c

Changed a buffer from 1024 bytes to 200 bytes.

include/linux/sched.h

Changed PIDHASH_SZ from 1024 to 16, which saves 1008 bytes.

include/linux/mmzone.h

NR_GPFINDEX from 0x100 to 0x10. Saves 4800 bytes, but I'm not
sure it doesn't break anything.

net/Makefile, net/socket.c, net/nosocket.c

Replacing socket.c with nosocket.c, a file containing dummy
replacement functions for those in socket.c, saves about 24K.

Warning: this disables the socket API entirely, but it is
currently not used in the product.

mm/Makefile, mm/swapfile.c, mm/swap_state.c, mm/noswapfile.c, mm/noswap_state.c

Replacing swapfile.c with noswapfile.c, and swap_state.c with
noswap_state.c saves about 12K. The no*.c files contains
empty replacement functions.

Warning: this disables swapping of anonymous memory, which
isn't used in the product. But note that demand paging of
executables still works.

mm/Makefile, mm/mmap.c

The functions in mmap.c could probably also be replaced by
empty functions. Estimated saving: 9K (not included in the
grand total below).

*, CONFIG_MESSAGES

Applying the CONFIG_MESSAGES patch and disabling all kernel
messages saves about 80K.

The CONFIG_MESSAGES patch was written by Graham Stoney
<[email protected]>.

With all of the above, and only this enabled in .config:
CONFIG_EXPERIMENTAL=y
CONFIG_CPU_R3000=y
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_ELF_KERNEL=y
CONFIG_BINFMT_ELF=y
CONFIG_MODULES=y
CONFIG_MODVERSIONS=y
CONFIG_KMOD=y
CONFIG_CROSSCOMPILE=y
, the kernel is down to about 550K.

Here is the output of "size vmlinux". I think this is without the
CONFIG_MESSAGES patch (it was long since I worked with this).

text data bss dec hex filename
572128 41964 15860 629952 99cc0 vmlinux

--
Lars Brinkhoff http://lars.nocrew.org/ Linux, GCC, PDP-10
Brinkhoff Consulting http://www.brinkhoff.se/ programming

2001-11-06 10:58:50

by szonyi calin

[permalink] [raw]
Subject: Re: Limited RAM - how to save it?


--- Matt Bernstein <[email protected]> wrote:
> You might like to patch an older Linux than 2.2 :)
> dietlibc might help userspace, too.. (though I don't
> know if you can link
> against it)

Kernel 2.4 is better at speed than 2.2. (and at mm)

>
> At 12:52 +0100 Jan-Benedict Glaw wrote:
>
> >I'm working on a 4MB linux system (for a customer)
> which has quite
> >limited resources at all:
> >
> > - 4MB RAM
> > - 386 or 486 like processor (9..16 BogoMIPS)
> > - < 100MB HDD
> > - Quite a lot user space running:-(
>
> -
> To unsubscribe from this list: send the line
> "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at
> http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/


__________________________________________________
Do You Yahoo!?
Find a job, post your resume.
http://careers.yahoo.com

2001-11-06 11:23:34

by Matt Bernstein

[permalink] [raw]
Subject: Re: Limited RAM - how to save it?

Not on a 4MB system it isn't. (I'd love to be proved wrong though :)

At 02:58 -0800 szonyi calin wrote:

>--- Matt Bernstein <[email protected]> wrote:
>> You might like to patch an older Linux than 2.2 :)
>> dietlibc might help userspace, too.. (though I don't
>> know if you can link
>> against it)
>
>Kernel 2.4 is better at speed than 2.2. (and at mm)