Embedded System GNU/Linux 1, qkim@pecetrirekr PC GNU/Linux, ZDISK LRP, LFS Embedded Linux 1 1 2 GNU/LINUX 2 21 3 22 4 23 5 24 6 25 6 3 ZDISK 7 31 GNU/Linux 7 32 ZDISK 8 33 ZDISK GNU/Linux 9 4 LRP (LINUX ROUTER PROJECT) 11 41 LRP 11 42 LRP GNU/Linux 12 5 EMBEDDED LINUX 12 51 13 52 14 53 SWAP 20 54 20 6 20 1 (Embedded System) PC, PC PC ROM, RAM, CPU,,, 1 : V 12, 2001 3 14
PC, ROM, ROM RAM,,, LCD PC PC,,, TV, PDA,,,, VCR, PC,,, PDA, PC,, CPU, RAM ROM, 2 LCD, PC, GNU/Linux, GNU/Linux, 10, GNU GNU/Linux GNU/Linux x86 PC MIPS, Alpha, PowerPC, SPARC, ARM, 2 GNU/Linux 3 4 ZDISK LRP ( Linux Router Project), 5 LFS (Linux From Scratch), 6 2 GNU/Linux GNU/Linux, ROM RAM Real-time OS 3 2 RAM 4MB ~ 16MB Flash ROM Disk 2MB ~ 16MB 16MB 3 GNU/Linux Real-time OS RT-Linux http://wwwrtlinuxorg/ 2
4 21 211 10% 90% GNU/Linux 150, df, mkdir 212 BusyBox BusyBox Debian Rescue/Install, (multi-call) [1] BusyBox BusyBox BusyBox, ls, $ ln s /busybox ls, /ls busybox ls, $ /busybox ls BusyBox 045, 5 ar, basename, cat, chgrp, chmod, chown, chroot, chvt, clear, cp, cut, date, dc, dd, deallocvt, df, dirname, dmesg, du, dutmp, echo, false, fbset, fdflush, find, free, freeramdisk, fsckminix, grep, gunzip, gzip, halt, head, hostid, hostname, id, init, insmod, kill, killall, length, ln, loadacm, loadfont, loadkmap, logger, logname, ls, lsmod, makedevs, mkdir, mkfifo, mkfsminix, mknod, mkswap, mktemp, more, mount, mt, mv, nc, nslookup, ping, poweroff, printf, ps, pwd, reboot, rm, rmdir, rmmod, sed, setkeycodes, sfdisk, sh, sleep, sort, swapoff, swapon, sync, syslogd, tail, tar, tee, telnet, test, touch, tr, true, tty, umount, uname, uniq, update, uptime, usleep, uudecode, uuencode, wc, which, whoami, yes, zcat, [, busybox busyboxdefh, "//" 4 Size Optimization 5 2000 6 21 BusyBox 045 3
213 TinyLogin TinyLogin BusyBox [2] TinyLogin, TinyLogin shadow password, BusyBox BusyBox 6 GNU/Linux TinyLogin $ du -ch `which adduser deluser delgroup login sulogin passwd getty` 60k /usr/sbin/useradd 20k /bin/login 16k /sbin/sulogin 24k /usr/bin/passwd 32k /sbin/getty 152k total $ ls -sh /tinylogin 36k /tinylogin TinyLogin BusyBox, tinylogindefh "//" 214 Ash Unix (shell) bash ash POSIX, /bin/sh shell ash [3] $ ls -sh /bin/bash 376k /bin/bash $ ls -sh /bin/ash 68k /bin/ash 22 GNU/Linux init, init '1', init,, /etc/inittab init,, getty login init, GNU/Linux init, 6 2000 6 21 TinyLogin 078 4
$ pstree init-+-apmd -crond -hanterm---bash---vi -inetd---intelnetd---login---bash---bash---hanterm---bash---pstree -login---bash---startx---xinit-+-x `-gnome-session -sh---hanterm-org---bash---su---bash -syslogd `-xscreensaver---attraction, inittab GNU/Linux init sysvinit,[4], Debian start-stop-daemon 7 8 sysvinit start-stop-daemon BusyBox init, run level, inittab ::sysinit:/etc/initd/rcs ::askfirst:/bin/sh 23 static,, glibc-212 libc-212so $ ls -sh /lib/libc-212so 39M /lib/libc-212so $ ls -sh libcso6 340k libcso6 GNU/Linux PC libcso6 libcxxxso $ ls -al /lib/libcso6 lrwxrwxrwx 1 root root 13 Apr 19 12:53 libcso6 -> libc-212so BusyBox busybox /lib/libcso6 7 start-stop-daemon 8 GNU/Linux 5
/lib/libc-212so /lib/libcso6 24 Linux, TCP/IP, SCSI HDD, Linux GNU/Linux ext2 minix, Linux 25 CPU, 2 (GCC g O2),,, [5] 251, C GCC GCC 252 strip (*) $ strip strip-debug filename $ strip strip-debug /usr/bin/* GCC g bash, /lib /usr/lib glibc gcc 87MB 16MB 6
253 BASH with debugging symbols without debugging symbols static 23MB 645KB dynamic 12MB 478KB O, O0, O1, O2, O3 O0, GCC, Makefile CFLAGS (GCC ) CXXFLAGS (G++ ) CFLAGS CXXFLAGS Makefile make e BASH CFLAGS CXXFLAGS $ export CFLAGS= -O3 mcpu=xxx march=yyy $ export CXXFLAGS= -O3 mcpu=xxx march=yyy xxx yyy CPU,, 80686 CPU i686, $ export CFLAGS= -O3 mcpu=i686 march=i686 CFLAGS CXXFLAGS, make make e 3 ZDISK ZDISK 35" 1722MB MS-DOS GNU/Linux,,, [6] ZDISK, MS-DOS 1722MB GNU/Linux, 1722MB MS-DOS GNU/Linux 31 GNU/Linux PC ROM BIOS, 0, 0, 1 RAM (loading) [7] 0, 0, 1 7
, LILO, Linux 9 Linux BIOS (boot loader) GNU/Linux LILO, LILO liloconf liloconf lilo LILO BIOS LILO LILO, 10, Linux 11, init, init inittab sysinit, fsck,,, fstab, sysinit init, init inittab initdefault default runlevel runlevel tty getty, getty "login: ", login 32 ZDISK ZDISK MS-DOS, MS- DOS/Windows FAT GNU/Linux SYSLINUX [8] LILO Linux, MS-DOS, SYSLINUX, FAT 9 512,, Linux 1 Linux 512 1, Linux 10, LILO liloconf http://wwwlinuxdocorg/howto/bootprompt-howtohtml 11 RAM RAM RAM, RAM, RAM 8
GNU/Linux Ext2 LILO, MS-DOS LOADLIN MS-DOS SYSLINUX ldlinuxsys, Linux liloconf syslinuxcfg LILO, SYSLINUX DEFAULT rescue LABEL rescue KERNEL kernel APPEND vga=normal load_ramdisk=1 prompt_ramdisk=0 \ ramdisk_size=2800 initrd=rescuegz root=/dev/ram0 rw DISPLAY messagetxt PROMPT 1 syslinuxcfg BIOS ldlinuxsys, SYSLINUX syslinuxcfg [9][10][11] rescue (DEFAULT rescue) rescue kernel (KERNEL kernel) VGA normal 80x25 (vga=normal) messagetxt (DISPLAY messagetxt) RAM 2800KB (load_ramdisk=1 ramdisk_size=2800) RAM (prompt_ramdisk=0) RAM rescuegz, RAM (initrd=rootlrp root=/dev/ram0) "boot: " LABEL (PROMPT 1) ZDISK MS-DOS $ mount t msdos o rw /dev/fd0h1722 /mnt/fdd $ cd /mnt/fdd $ ls -al total 1622 drwxrwxr-x 2 root root 7168 Jan 1 1970 / drwxr-xr-x 27 root root 4096 Jun 23 16:42 / -rwxrwxr-x 1 root root 658523 Jun 24 14:57 kernel -r-xr-xr-x 1 root root 5860 Jun 24 14:43 ldlinuxsys -rwxrwxr-x 1 root root 858 Jun 24 14:58 messagetxt -rwxrwxr-x 1 root root 982177 Jun 24 14:56 rescuegz -rwxrwxr-x 1 root root 527 Jun 24 15:15 syslinuxcfg 33 ZDISK GNU/Linux ZDISK GNU/Linux 2 Linux 2214, GNU/Linux,, RAM RAM (initrd) Loopback RAM 9
ZDISK 32 rescuegz RAM, 2 ZDISK BusyBox, init /etc/inittab BusyBox init BusyBox init runlevel, TinyLogin rescuegz $ cd rescuetmp $ dir -l total 52 drwxr-xr-x 2 root root 4096 Jun 18 10:30 bin drwxr-xr-x 2 root root 4096 Jun 11 08:06 boot drwxr-xr-x 2 root root 8192 Apr 15 05:35 dev drwxr-xr-x 2 root root 4096 Jun 10 07:09 etc drwxr-xr-x 3 root root 4096 Jun 19 23:46 lib drwxr-xr-x 9 root root 4096 Dec 7 1999 mnt drwxr-xr-x 2 root root 4096 Aug 15 1998 proc drwxr-xr-x 3 root root 4096 Dec 15 1999 root drwxr-xr-x 2 root root 4096 Jun 18 09:01 sbin drwxr-xr-x 2 root root 4096 Jan 9 1999 tmp drwxr-xr-x 7 root root 4096 Jun 18 23:35 usr drwxr-xr-x 5 root root 4096 Feb 8 18:41 var ZDISK rescuegz genext2fs (initrd) genext2fs ext2 rescuegz rescuetmp genext2fs ext2 $ genext2fs r 0 i 600 b 2800 d rescuetmp rescue $ gzip 9 rescue $ ls al rescuegz -rw-rw-r-- 1 root root 982177 Jun 24 14:54 rescuegz genext2fs r, -i inode, -b, -d, rescuegz RAM ext2 ZDISK /etc/mtab /dev/ram0 / ext2 rw 0 0 /etc/fstab proc /proc proc defaults 0 0 10
4 LRP (Linux Router Project) LRP 144MB GNU/Linux,,, 80386, 80486 [12] LRP ZDISK, MS-DOS GNU/Linux, 144MB 1722MB MS-DOS GNU/Linux 41 LRP LRP ZDISK MS-DOS, MS-DOS GNU/Linux SYSLINUX LRP, lrp tar gzip, *lrp *targz $ mount t msdos o rw /dev/fd0 /mnt/fdd $ cd /mnt/fdd $ ls -al total 1222 drwxrwxr-x 2 root root 7168 Jan 1 1970 / drwxr-xr-x 27 root root 4096 Jun 23 16:42 / -rwxrwxr-x 1 root root 32889 May 29 1999 etclrp -r-xr-xr-x 1 root root 5476 May 29 1999 ldlinuxsys -rwxrwxr-x 1 root root 362995 May 29 1999 linux -rwxrwxr-x 1 root root 488 May 29 1999 locallrp -rwxrwxr-x 1 root root 628 May 29 1999 loglrp -rwxrwxr-x 1 root root 52302 Jun 23 16:46 moduleslrp -rwxrwxr-x 1 root root 782604 May 29 1999 rootlrp -rwxrwxr-x 1 root root 179 Jun 23 16:52 syslinuxcfg -rwxrwxr-x 1 root root 515 Jun 23 16:51 syslinuxdpy LRP syslinuxcfg DISPLAY syslinuxdpy TIMEOUT 0 DEFAULT linux APPEND=load_ramdisk=1 initrd=rootlrp initrd_archive=minix \ ramdisk_size=4096 root=/dev/ram0 boot=/dev/fd0,msdos \ LRP=etc,log,local,modules syslinuxcfg BIOS ldlinuxsys SYSLINUX, syslinuxcfg [9][10][11] syslinuxdpy (DISPLAY syslinuxdpy) "boot: ", (TIMEOUT 0) linux 32 ZDISK rescue, rescue KERNEL LRP DEFALUT DEFAULT LABEL (DEFAULT linux) 11
RAM 4096KB (load_ramdisk=1 ramdisk_size=4096) RAM, RAM rootlrp, RAM minix (root=/dev/ram0 initrd=rootlrp initrd_archive=minix) LRP etclrp, loglrp, locallrp, moduleslrp, MS-DOS, SYSLINUX boot, (boot=/dev/fd0,msdos) syslinuxcfg GNU/Linux minix /etc/fstab /etc/fstab: static file system information <file system> <mount point> <type> <options> <dump> <pass> /dev/ram0 / minix rw proc /proc proc noauto 0 0 42 LRP GNU/Linux LRP GNU/Linux PC ZDISK LRP GNU/Linux /bin /sbin, BusyBox TinyLogin $ ls -al /bin/login /usr/bin/passwd /sbin/getty -rwxr-xr-x 1 root root 22968 Nov 3 1998 /bin/login -rwxr-xr-x 1 root root 12156 Mar 10 1999 /sbin/getty lrwxrwxrwx 1 root root 15 Jun 26 13:19 /usr/bin/passwd -> //bin/login LRP ZDISK LRP Linux 2036pre15 $ ls -sh linux 360k linux GNU/Linux ZDISK LRP 5 Embedded Linux GNU/Linux LFS (Linux From Scratch) [13], 'Embedded Linux Howto' [14], 'The Linux Bootdisk HOWTO' [7] 12
GNU/Linux 5 GNU/Linux, GNU/Linux GNU/Linux 51 GNU/Linux, GNU/Linux ext2, 12 511 GNU/Linux, fdisk,,, /dev/hda5 512 ext2 ext2 mke2fs $ mke2fs /dev/hda5 513, /lfs $ mkdir /lfs $ mount /dev/hda5 /lfs 514 GNU/Linux FHS [15] $ cd /lfs $ mkdir bin dev home proc sbin usr boot etc lib mnt root tmp var 12 Tom Fawcett The Linux Bootdisk HOWTO [7] 13
$ mkdir -p usr/bin usr/sbin usr/share usr/lib $ mkdir -p etc/config etc/default etc/initd etc/rcboot $ mkdir -p etc/rc0d etc/rc1d etc/rc2d etc/rc3d \ etc/rc4d etc/rc5d etc/rc6d etc/rcsd /proc: /etc: /sbin: /bin: /lib: /mnt: /usr: /dev: /boot: /dev mknod, GNU/Linux,, /dev/fd0 /dev/fd1 $ cp -av /dev/* /lfs/dev/ GNU/Linux 52 GNU/Linux Linux, init GNU/Linux sysvinit init 33 ZDISK sysvinit init busybox LFS 521 Sysvinit start-stop-daemon sysvinit start-stop-daemon, init /lfs/sbin, start-stop-daemon /lfs/usr/sbin 522 Sysvinit Sysvinit inittab, LFS /lfs/etc Begin /etc/inittab default run level id:2:initdefault: 14
CTRL+ALT+DEL pressed ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now /sbin/mingetty invocations for run levels 1:2345:respawn:/sbin/sulogin End /etc/inittab 32 init sysinit inittab Begin /etc/inittab default run level id:2:initdefault: Boot-time system configuration/initialization script This is run first except when booting in emergency (-b) mode si::sysinit:/etc/initd/rcsysinit What to do in single-user mode ~~:S:wait:/sbin/sulogin /etc/initd executes the S and K scripts upon change of runlevel 0:halt 1:single-user 2-5:multi-user (5 may be X with xdm or other) 6:reboot l0:0:wait:/etc/initd/rc 0 l1:1:wait:/etc/initd/rc 1 l2:2:wait:/etc/initd/rc 2 l3:3:wait:/etc/initd/rc 3 l4:4:wait:/etc/initd/rc 4 l5:5:wait:/etc/initd/rc 5 l6:6:wait:/etc/initd/rc 6 What to do when CTRL-ALT-DEL is pressed ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now Keyboard Request Action on special keypress (ALT-UpArrow) kb::kbrequest:/bin/echo "Edit /etc/inittab to let this work" /sbin/getty invocations for the runlevels The "id" field MUST be the same as the last characters of the device (after "tty") Format: <id>:<runlevels>:<action>:<process> 1:2345:respawn:/sbin/getty 9600 tty1 2:23:respawn:/sbin/getty 9600 tty2 3:2345:respawn:/sbin/mingetty tty3 4:2345:respawn:/sbin/mingetty tty4 5:2345:respawn:/sbin/mingetty tty5 6:2345:respawn:/sbin/mingetty tty6 3:23:respawn:/sbin/getty 38400 tty3 4:23:respawn:/sbin/getty 38400 tty4 5:23:respawn:/sbin/getty 38400 tty5 6:23:respawn:/sbin/getty 38400 tty6 Example how to put a getty on a serial line (for a terminal) T1:23:respawn:/sbin/getty -L ttys1 19200 vt100 15
Example how to put a getty on a modem line T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttys3 Example how to run portslave T0:23:respawn:+/usr/sbin/portslave 0 T1:23:respawn:+/usr/sbin/portslave 1 T2:23:respawn:+/usr/sbin/portslave 2 T3:23:respawn:+/usr/sbin/portslave 3 End /etc/inittab 523 522 inittab, sysinit, inittab rcsysinit /etc/initd $ cd /lfs/etc $ mkdir rc0d rc1d rc2d rc3d rc4d rc5d rc6d initd rcsd rcboot /lfs/etc/initd/rcsysinit!/bin/sh /etc/initd/rcsysinit: run once at boot time, and call all S??* scripts in /etc/rcsd in numerical/alphabetical order Set the path PATH=/bin:/sbin:/usr/bin:/usr/sbin runlevel=s prevlevel=n umask 022 export PATH runlevel prevlevel Source defaults /etc/default/rcs export VERBOSE Trap CTRL-C &c only in this shell so we can interrupt subprocesses trap ":" 2 3 20 Call all parts in order for i in /etc/rcsd/s??* do Ignore dangling symlinks for now [! -f "$i" ] && continue case "$i" in *sh) Source shell script for speed 16
done esac *) ( ) ;; trap - 2 3 20 $i start No sh extension, so fork subprocess $i start ;; For compatibility, run the files in /etc/rcboot too [ -d /etc/rcboot ] && run-parts /etc/rcboot /etc/default/rcs (default), VERBOSE export VERBOSE /lfs/etc/default/rcs Defaults for the boot scripts in /etc/default Time files in /tmp are kept TMPTIME=0 Set to yes if you want sulogin to be spawned on bootup SULOGIN=no Set to no if you want to be able to login over telnet/rlogin before system startup is complete (as soon as inetd is started) DELAYLOGIN=yes Set GMT="-u" if your system clock is set to GMT, and GMT="" if not GMT="-u" Set VERBOSE to "no" if you would like a more quiet bootup VERBOSE=yes Set EDITMOTD to "no" if you don't want /etc/motd to be editted automatically EDITMOTD=yes Set FSCKFIX to "yes" if you want to add "-y" to the fsck at startup FSCKFIX=no Update links in all rc?d dirs from initd/script headers at boot? DYNARCD=yes /lfs/etc/rcboot [rcboot] $ ls -al total 12 drwxr-xr-x 2 root root 4096 Mar 20 1998 / drwxr-xr-x 18 root root 4096 Jun 28 17:19 / -rwxr-xr-x 1 root root 412 Jun 10 1998 0setserial [rcboot]$ cat 0setserial!/bin/sh Initializes the serial ports on your system Distributed with setserial version 212 17
STD_FLAGS="autoconfig session_lockout ^fourport spd_vhi" SETSERIAL=/bin/setserial echo -n "Configuring serial ports " ${SETSERIAL} -b ${SETSERIAL} -b /dev/ttys0 uart 16550A port 0x3F8 irq 4 ${STD_FLAGS} /dev/ttys1 uart 16550A port 0x2F8 irq 3 ${STD_FLAGS} echo "done" ${SETSERIAL} -bg /dev/ttys* 524 reboot, halt, mountfs, umountfs /lfs/etc/initd/reboot!/bin/sh Begin /etc/initd/reboot echo -n "System reboot in progress" /sbin/reboot -d -f -i End /etc/initd/reboot /lfs/etc/initd/halt!/bin/sh Begin /etc/initd/halt /sbin/halt -d -f -i -p End /etc/initd/halt /lfs/etc/initd/mountfs!/bin/sh Begin /etc/initd/mountfs check_status() { if [ $? = 0 ] then echo "OK" else echo "FAILED" fi } echo -n "Remounting root file system in read-write mode" /bin/mount -n -o remount,rw / check_status > /etc/mtab /bin/mount -f -o remount,rw / echo -n "Mounting proc file system" 18
/bin/mount proc check_status End /etc/initd/mountfs /lfs/etc/initd/umountfs!/bin/sh Begin /etc/initd/umountfs check_status() { if [ $? = 0 ] then echo "OK" else echo "FAILED" fi } echo "Deactivating swap" /bin/swapoff -av check_status echo -n "Unmounting file systems" /bin/umount -a -r check_status End /etc/initd/umountfs $ cd /lfs/etc/initd $ chmod 755 rcs reboot halt mountfs umountfs $ cd /rc0d $ ln -s /initd/umountfs S90umountfs $ ln -s /initd/halt S99halt $ cd /rc6d $ ln -s /initd/umountfs S90umountfs $ ln -s /initd/reboot S99reboot $ cd /rcsd $ ln -s /initd/mountfs S10mountfs 525 LFS /lfs/etc fstab, /dev/hda5 / ext2 defaults 0 1 /dev/hda6 none swap sw 0 0 proc /proc proc defaults 0 0 RAM ZDISK LRP 526 passwd group 522 inittab, init sulogin, sulogin root 19
/lfs/etc passwd group passwd root:s394ul1bkvmq2:0:0:root:/root:/bin/bash group root::0: root /etc/passwd lfs123 527 Ash root passwd, GNU/Linux bash, ash Ash /lfs/bin $ ln s /bin/ash bash $ ln s /bin/ash sh $ ln s /bin/ash csh 528 BushBox TinyLogin 212 213 BushBox TinyLogin 529 LILO SYSLINUX /etc/liloconf PC GNU/Linux LFS /etc/liloconf, MS-DOS GNU/Linux SYSLINUX 53 SWAP, [16] /lfs/etc/initd/rcsysinit 54 GNU/Linux root shutdown reboot f LFS 6 GNU/Linux 2,,,,,, GNU/Linux 20
21
[1] BusyBox, http://busyboxlineocom/ [2] TinyLogin, http://tinyloginlineocom/ [3] Ash, http://wwwdebianorg/packages/unstable/shells/ashhtml [4] Sysvinit, ftp://ftpcistronnl/pub/people/miquels/sysvinit/ [5] Gerard Beekmans, "Compiler optimizations", http://wwwlinuxfromscratchorg/view/ [6] ZDISK, http://metalabuncedu/pub/linux/system/recovery/!indexhtml [7] Tom Fawcett, "The Linux Bootdisk HOWTO", http://wwwlinuxdocorg/howto/bootdisk- HOWTO/indexhtml [8] H Peter Anvin, "SYSLINUX A boot loader for Linux using MS-DOS floppies" [9] Werner Almesberger, "LILO User's guide", ftp://metalabuncedu/pub/linux/system/boot/lilo/ [10] Paul Gortmaker, "The Linux BootPrompt-HowTo", http://wwwlinuxdocorg/howto/bootprompt-howtohtml [11] "Using the RAM disk block device with Linux", /usr/src/linux/documentation/ramdisktxt [12] LRP Linux Router Project, http://wwwlinuxrouterorg/ [13] LFS Linux From Scratch, http://wwwlinuxfromscratchorg/ [14] Sebastien Huet, "Embedded Linux Howto", http://wwwlinuxembeddedcom/howto/embedded-linux-howtohtml [15] "Filesystem Hierarchy Standard", http://wwwpathnamecom/fhs/ [16] Paul Moody, "minihowto Embedded Linux 11c", http://wwwlinuxembeddedcom/pmhowtohtml http://wwwlinuxdevicescom/articles/at9888936014html http://wwwfefede/dietlibc/ http://wwwfefede/djb/ http://wwwfefede/libowfat/ http://robursluse/jensl/ugrep/ http://www-ecnjitedu/~asm3072/programminghtml http://wwwfefede/fgetty/ http://wwwfefede/fget/ http://wwwfefede/ncp/ http://wwwfefede/embutils/ http://cvsuclinuxorg/uclibchtml http://opensourcelineocom/projectshtml Particularly impressive is the ability of Mobile Linux's cramfs to squeeze a more or less normal Linux system, complete with glibc, other libraries, the kernel and even the X windowing system into a paltry 8MB This leaves plenty of room on the typical 32MB or 64MB storage devices used in embedded systems for applications such as Web browsers and mp3 music systems 22
Cramfs saves space by optimizing inode table size and eliminating the space wasted between files in traditional filesystems It also uses zlib compression for a better than 2-to-1 compression rate The overhead for decompression is not especially bad because cramfs allows decompression of arbitrary blocks, rather than entire files, a function that the Linux kernel is able to exploit In addition to saving space, cramfs saves the appliance enduser from the prospects of waiting for fsck or worse, having to perform fsck manually after an abnormal termination It does this by being readonly This limitation makes some sense since flash ROM can withstand only a few hundred thousand write cycles It could also be a security advantage in many circumstances Still, an ongoing project is to incorporate compression into a journaling file system such as reiserfs which could be useful in some applications Another key to space savings is the use of BusyBox, a single executable offering lite versions of lots of standard Unix commands Busybox will be familiar to those who have played around with floppy diskbased Linux routers, rescue disks and the like, but most users would find its utilities pretty limited Configuration and other data that must persist across reboots is first saved to a temporary filesystem built in RAM on a "ramfs" filesystem, another bit of Torvalds handywork "Linus was on a filesystem spree there for a while," according to Quinlan When it's time to commit ramfs to persistent storage, a utility called packramfs is called to stuff it into the cramfs filesystem The ramfs is similar to a RAM disk, but supports file "limits" so that it can be prevented from overrunning available RAM space 23