LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   LinuxQuestions.org Member Success Stories (https://www.linuxquestions.org/questions/linuxquestions-org-member-success-stories-23/)
-   -   HOW-TO: Boot OS into RAM for speed and silence (https://www.linuxquestions.org/questions/linuxquestions-org-member-success-stories-23/how-to-boot-os-into-ram-for-speed-and-silence-662116/)

IsaacKuo 08-11-2008 09:31 PM

HOW-TO: Boot OS into RAM for speed and silence
 
How to RAMboot

This details a method of loading your entire OS into an uncompressed ramdisk. The result is lightning fast performance, and elimination of hard drive noise and power consumption (if swap is not used and the hard drive is spun down).

The basic steps are:

1. Install Debian 4.0 on the hard drive

2. Create a modified /etc/fstab which has tmpfs for the root partition

3. Optionally create a startup script to park hard drives

4. Create a script which makes a stripped down OS image

5. Create a custom initrd.img which loads the OS image into a tmpfs ramdisk

6. Modify /boot/grub/menu.lst with an entry for the custom initrd.img

After completing these steps, you will have a dual boot system with the following boot options:

A) Boot normally, where you install new software or change settings

B) Boot into the "ramboot" OS image, for high speed silent computing

-------------------------------------------------
Step 1. Installing Debian 4.0

a) Install Debian 4.0 onto a partition of least 500megs. For purposes of the rest of these instructions, I'll assume you're have installing into the hda1 partition.

b) In the software selection step, deselect the so-called Base software suite. You will manually install only what you need later on.

c) After doing the install, log in as root and edit /etc/apt/sources.list to comment out the CD-ROM entry (use the command "nano /etc/apt/sources.list"). Then run the following commands:

Code:

apt-get update
apt-get install hdparm localepurge debconf-english
apt-get remove --purge aptitude tasksel tasksel-data laptop-detect
apt-get clean

Note that installing debconf-english will remove debconf-i18n. This is normal.

-------------------------------------------------
Step 2. Create a modified /etc/fstab

Create and edit a new fstab using these commands:

Code:

cd /etc/
cp fstab fstab.ramboot
nano fstab.ramboot

Comment out the / entry. Create a new / line like this:

Code:

none / tmpfs defaults 0 0
-------------------------------------------------
Step 3. Optionally create a startup script to park hard drives

If you want, create a startup script with these commands:
Code:

nano /etc/init.d/ijkijkijk
chmod 755 /etc/init.d/ijkijkijk
update-rc.d ijkijkijk defaults 20

The contents of ijkijkijk should be something like this:

Code:

#! /bin/sh
# /etc/init.d/ijkijkijk

# Some things that run always
touch /var/lock/ijkijkijk

# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting script ijkijkijk"

        echo "Isaac Kuo script parking drives"
        hdparm -S 6 /dev/hda
        hdparm -y /dev/hda
        #hdparm -S 6 /dev/hdb
        #hdparm -y /dev/hdb
        #hdparm -S 6 /dev/hdc
        #hdparm -y /dev/hdc
        #hdparm -S 6 /dev/hdd
        #hdparm -y /dev/hdd

    ;;
  stop)
    echo "Stopping script ijkijkijk"



    ;;
  *)
    echo "Usage: /etc/init.d/blah {start|stop}"
    exit 1
    ;;
esac

exit 0

-------------------------------------------------
Step 4. Create a script which makes a stripped down OS image

Login as root. Then create a basic script like this:

Code:

#!/bin/sh
#
# Takes an OS snapshot, strips it down, and wraps it up into /snapstrip.tar

# Clean up anything previous
touch /snapstrip.tar
touch /snapstrip
rm -fvr /snapstrip.tar
rm -fvr /snapstrip

# Create temporary ramdisk and copy files over
mkdir /snapstrip
mount -t tmpfs -o size=100% none /snapstrip
cp -vax /. /snapstrip/.
cp -vax /dev/. /snapstrip/dev/.

# Move over the modified fstab
cd /snapstrip/etc/
cp -vax fstab.ramboot fstab

# Strip down unnecessary stuff
cd /snapstrip/
rm -fvr /snapstrip/boot/*
rm -fvr /snapstrip/var/lib/apt/lists/*
rm -fvr /snapstrip/usr/share/doc-base/*
rm -fvr /snapstrip/usr/share/doc/*
rm -fvr /snapstrip/usr/share/man/*

rm -fvr /snapstrip/lib/modules/*/kernel/drivers/bluetooth
rm -fvr /snapstrip/lib/modules/*/kernel/drivers/ieee1394
rm -fvr /snapstrip/lib/modules/*/kernel/drivers/parport
rm -fvr /snapstrip/lib/modules/*/kernel/drivers/pcmcia
rm -fvr /snapstrip/lib/modules/*/kernel/drivers/telephony
rm -fvr /snapstrip/lib/modules/*/kernel/drivers/isdn
rm -fvr /snapstrip/lib/modules/*/kernel/drivers/md

rm -fvr /snapstrip/lib/modules/*/kernel/fs/ntfs
rm -fvr /snapstrip/lib/modules/*/kernel/fs/reiserfs
rm -fvr /snapstrip/lib/modules/*/kernel/fs/hfs
rm -fvr /snapstrip/lib/modules/*/kernel/fs/hfsplus
rm -fvr /snapstrip/lib/modules/*/kernel/fs/xfs

rm -fvr /snapstrip/lib/modules/*/kernel/net/appletalk
rm -fvr /snapstrip/lib/modules/*/kernel/net/bluetooth
rm -fvr /snapstrip/lib/modules/*/kernel/net/irda

### ADD IN MORE STUFF TO STRIP HERE ###

# Create the tar archive
cd /snapstrip/
tar cf /snapstrip.tar *

Run the script to create the tar archive. You'll run this script after making changes to the main OS to create a new snapshot file.

-------------------------------------------------
Step 5. Create a custom initrd.img which loads the OS image into a tmpfs ramdisk

This is step is a hack. It works with Debian 4.0. There's probably a less "hackish" way of doing this.

Use the following commands:

Code:

cd /usr/share/initramfs-tools/scripts/
cp -vax local local.bak
nano local
cp -vax local local.ramboot

In nano, you'll want to modify the portion where the actual "mount" command is done. Comment it out and insert something like this:

Code:

[...]
########### ramboot
        # FIXME This has no error checking
        # Mount root
###    mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}

########### mount the filesystem
        mkdir /ijkijk
        mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} /ijkijk

########### create root ramdisk
        mount -t tmpfs -o size=100% none ${rootmnt}

########### copy the files over to the ramdisk
        cd ${rootmnt}
        tar xf /ijkijk/snapstrip.tar

########### umount the filesystem and set to spin down
        umount /ijkijk
        hdparm -S 1 /dev/hda
[...]

After making these modifications, create the initrd.img with this command:

Code:

mkinitramfs -o /boot/initrd.img.ramboot
After creating this ramdisk make sure to copy back the backup file with:

Code:

cp -vax local.bak local
This is important! If you forget to do this, then your system will be screwed up if your kernel is upgraded!

-------------------------------------------------
Step 6. Modify /boot/grub/menu.lst with an entry for the custom initrd.img

Modify /boot/grub/menu.lst with a new entry. Copy existing OS's entry. Then modify the initrd to use your new initrd.img. It will look something like this:

Code:

title  RAMdisk Debian GNU/Linux
root    (hd0,0)
kernel  /boot/vmlinuz-2.6.18-6-486 root=/dev/hda1 ro
initrd  /boot/initrd.img.ramboot

-------------------------------------------------

After following these steps, you'll have a very basic working system. Now you can boot into the "main" OS and install things like X (only install the xserver you need) and other programs like icewm and iceweasel. For example:

apt-get install xserver-xorg-video-vesa xserver-xorg-video-ati xfonts-base alsa-base alsa-utils icewm menu iceweasel xfe aterm

The default icewm theme is rather ugly, so you can copy over a nice theme like /usr/share/icewm/themes/IceCrack2 from another install. Obviously, you don't want to install all of the themes in icewm-themes since they'll be consuming RAM just sitting there.

synss 10-01-2008 03:45 AM

Hi, why not further compress your disk image ? squashfs + aufs would do the job just fine. That would save, not only space, but also time when you copy everything into tmpfs. And overall better performance, if possible.

Also, you should not modify the /usr/share/initramfs-tools/* files but you should make your own things in /etc/initramfs-tools/ to keep things tidy. And instead of moving files back and forth, I would use a kernel option, i.e., you boot with ramboot and it puts everything into tmpfs, you boot without and it does a normal boot.

Lastly, you can have anything in the initramfs. Anything includes your whole hardrive if you want to. That would simplify everything in your case, the computer would do all the work of putting your initamfs into RAM.

IsaacKuo 10-01-2008 07:18 AM

My experience with LiveCD's which do that is that performance is sluggish compared to an uncompressed OS.

I'm not familiar enough with initramfs-tools to know how to properly do this in /etc/initramfs-tools/ rather than /usr/share/initramfs-tools/, or how to script kernel options. I'd appreciate some pointers.

My first idea was to use the initramfs, but it seemed more complicated to figure out. I wanted to do an essentially small modification to the OS's normal operations. I really like the idea of bulking up the initramfs into a truly minimal OS, though.

Thanks for the comments and ideas!

synss 10-01-2008 11:55 PM

Are you comparing a squashfs partition on a CD to an uncompressed partition on a hard-disk drive? If so, the difference in performance is not due to the compression but to the media used. In principle, squashfs reduces head movement at the expense of increased CPU usage, the tradeoff should be worthy. You can find benchmarks here http://forums.gentoo.org/viewtopic-t...-squashfs.html and my own experience fits in: compressing /usr indeed increases performances (you can start here, I mean only squash /usr and see for yourself, it is not a very dangerous operation.)

By a kernel option, I meant an option on the kernel line in grub. You set it in /boot/grub/menu.lst or "on the fly" while booting by entering in the interactive grub menu.

I do not know if you have read man (8) initramfs-tools but you probably should, Debian makes it easy to tinker with the boot process. (http://man.he.net/man8/initramfs-tools). Options on the kernel line are read from /proc/cmdline, you can see how by reading files in /usr/share/initramfs-tools, you should definitely have a look at init.

On my Debian laptop, I have a small script in /etc/initramfs-tools/scripts/local-bottom that moves /root to /ro (it is the squashed fs) then, if a root_rw=<device> option is provided, the scripts mounts the device on /rw and uses aufs to union /ro and /rw on /root; if no root_rw is provided, then tmpfs is mounted on /rw, etc. I do not copy anything to RAM, but it is a good idea and I may actually try that since I do not touch RAM that much on that computer. I do not have the computer here, otherwise I would post my script.

/usr is for programs and you should not make local changes in this place: it is package manager land; configurations are set in /etc. For update-initramfs and initramfs-tools, files in /usr/share/initramfs-tools or /etc/initramfs-tools are treated equally. The difference is for you: next time you update initramfs-tools, you lose all your changes in /usr/* while files in /etc/* are left alone.

Now, an initramfs is just a compressed filesystem containing an executable called init. A long time ago, I started a wiki entry on the Gentoo wiki on how to make an initramfs from scratch (second part in http://gentoo-wiki.com/HOWTO_Initramfs ) and you may have a look over there. Also for reference, the kernel doc: Documentation/early-userspace/README and another how to from scratch http://jootamam.net/howto-initramfs-image.htm.

It requires some work to do it this way, but it is not that difficult. Enjoy!

honeybadger 10-04-2008 01:40 AM

hi there,

IsaacKuo .......... dude ........... you are great.

Masumi 10-29-2008 05:56 PM

Nice tutorial, I've bookmarked it, going to try this sometime.

synss 10-31-2008 03:08 AM

Hi again, I do things a bit different from you: I use LVM; I also prefer a squashed filesystem, but here are the scripts I use (this is not a very original idea, but my scripts are better written than most of what I have seen so far on the subject)

You'll get the idea of what I told you (kernel options; scripts in /etc/initramfs-tools/ ...)


1. Mount the squashfs filesystem, if the option root_rw=<DEVICE> is provided, <DEVICE> is used as a read-write fs; if not, tmpfs is used
Code:

#!/bin/sh -e

PREREQS="lvm"

prereqs() { echo "$PREREQS"; }

case "$1" in
        prereqs)
        prereqs
        exit 0
        ;;
esac

# Program starts here
# (c) 2008 Mathias Laurin, MIT licence
# This script /etc/initramfs-tools/scripts/local-bottom/aufs allows booting
# a computer with a squashed root. By default, the read-write branch is in a
# tmpfs (RAM based) filesystem.
#
# Options on the kernel line:
# root=<LABEL=label|UUID=uuid|device> read-only squashfs filesystem
# root_rw=<LABEL=label|UUID=uuid|device> read-write filesystem, tmpfs if omited
#
# No modules are loaded from this script. On a Debian system, at least
# aufs and squashfs should be added to /etc/initramfs-tools/modules

# Load helper functions
. /scripts/functions

MY_TMPFS="yes"
MY_ROOT_RW=

# Parse command line options
# cf. /usr/share/initramfs-tools/init on a Debian system
for x in $(cat /proc/cmdline); do
        case $x in
        root_rw=*)
                MY_TMPFS=
                MY_ROOT_RW=${x#root_rw=}
                case $MY_ROOT_RW in
                LABEL=*)
                        MY_ROOT_RW="/dev/disk/by-label/${MY_ROOT_RW#LABEL=}"
                        ;;
                UUID=*)
                        MY_ROOT_RW="/dev/disk/by-uuid/${MY_ROOT_RW#UUID=}"
                        ;;
                esac       
                ;;
        esac
done

grep -q $rootmnt /proc/mounts ||
panic "$rootmnt does not seem to be mounted, check /proc/mounts"

# Read-only branch
mkdir /ro

log_begin_msg "Move the real root to /ro"
mount -n -o move,ro $rootmnt /ro
test $? -ne 0 && panic "Failed to move /root to /ro"
log_end_msg

# Read-write branch
mkdir /rw

if [ -n "$MY_ROOT_RW" ]; then
        log_begin_msg "Mount $MY_ROOT_RW on /rw"
        MY_TMPFS=

        # For this to work, the fs module needs to be loaded
        # add it to /etc/initramfs-tools/modules
        mount -n $MY_ROOT_RW /rw
        test $? -ne 0 && MY_TMPFS="yes" &&
                log_warning_msg "Failed! Falling back to tmpfs on /rw"
        log_end_msg
fi

if [ -n "$MY_TMPFS" ]; then
        log_begin_msg "Mount tmpfs on /rw"
        mount -n -t tmpfs aufstmpfs /rw
        test $? -ne 0 && panic "Failed to mount the rw filesystem"
        log_end_msg
fi

log_begin_msg "Unite on /root"
mount -n -t aufs -o br:/rw=rw:/ro=ro aufsroot $rootmnt
test $? -ne 0 && panic "Failed to mount aufs on $rootmnt"
log_end_msg

# Cleanup variables
unset MY_TMPFS
unset MY_ROOT_RW

2. Recreate a squashfs image
Code:

#!/bin/sh -e

PREREQS="aufs"

prereqs() { echo "$PREREQS"; }

case "$1" in
        prereqs)
        prereqs
        exit 0
        ;;
esac

# Load helper functions
. /scripts/functions

# Program starts here
# (c) 2008 Mathias Laurin, X11 license
# When called by the resquash option, this script
# /etc/initramfs-tools/scripts/local-bottom/resquash creates a fresh
# squashfs image and *panics* to let the user update grub
#
# Options on the kernel line:
# resquash=<basename of the sqfs image, a timestamp is added>

# Parse command line options
for x in $(cat /proc/cmdline); do
        case $x in
                resquash)
                SQFS_NAME="root_$(date +%Y%m%d).sqfs"
                ;;
                resquash=*)
                SQFS_NAME="${x#resquashfs=}_$(date +%Y%m%d).sqfs"
                ;;
        esac
done

# Not called, exit gracefully
test -z "$RESQUASH" && exit 0

# Variables
MY_TMPFS_DIR="/my-ramdisk"
test "$quiet" = "n" && MKSQUASHFS_OPTS="-info"

# The Debian people change the name of the lvm binary, look for vgchange
LVM="$(which vgchange &>/dev/null)"
if [ ! -x "$LVM" ]; then
        log_failure_msg "lvm program not found"
        PATH=$PATH:$rootmnt/bin:$rootmnt/sbin:$rootmnt/usr/bin:$rootmnt/usr/sbin
        LVM=$(which vgchange &>/dev/null)
        test -x "$LVM" || panic "Unable to find any lvm binary"
fi
ln -s $LVM /sbin/lvm

MKSQUASHFS="$(which mksquashfs &>/dev/null)"
if [ ! -x "$MKSQUASHFS" ]; then
        log_failure_msg "mksquashfs program not found"
        PATH=$PATH:$rootmnt/bin:$rootmnt/sbin:$rootmnt/usr/bin:$rootmnt/usr/sbin
        MKSQUASHFS=$(which mksquashfs &>/dev/null)
        test -x "$MKSQUASHFS" || panic "Unable to find mksquashfs"
fi

SQFS_FILE="$MY_TMPFS_DIR/$SQFS_NAME"
VG="/dev/$(lvm vgdisplay | awk '/VG Name/{print $3}')"
SQFS_LV="$VG/$SQFS_NAME"

# Start the actal work
log_begin_msg "Create the sqfs image in tmpfs"
test ! -d $MY_TMPFS_DIR && mkdir $MY_TMPFS_DIR
mount -t tmpfs tmpsquash $MY_TMPFS_DIR
$MKSQUASHFS $rootmnt $SQFS_FILE \
        $MKSQUASHFS_OPTS \
        -e var/cache/apt/archives/ etc/fstab etc/mtab
test $? -eq 0 || panic "Failed to create $SQFS_FILE"
log_success_msg "$SQFS_FILE created"

LV_SIZE=$(ls -sh $SQFS_FILE | awk '{print $1}')
lvm lvcreate -n "$SQFS_NAME" -L $LV_SIZE $VG
test $? -eq 0 || panic "Failed to create the logical volume"
log_success_msg "$SQFS_LV created"

cat $SQFS_FILE > $SQFS_LV
test $? -eq 0 || panic "Failed to put the filesystem into the LV"
log_end_msg

log_success_msg "The root filesystem has been squashed into $SQFS_LV. You should"
log_success_msg "probably create a read-write filesystem to mount on top of the"
log_success_msg "squashfs filesystem. You also need to update grub before you "
log_success_msg "reboot into the newly created image."


3. squashfs is read-only, if you use it with tmpfs, you cannot make persistant changes to rootfs. However, you can make persistant changes from the initram! like this
Code:

#!/bin/sh -e

PREREQS="aufs"

prereqs() { echo "$PREREQS"; }

case "$1" in
        prereqs)
        prereqs
        exit 0
        ;;
esac

# Load helper functions
. /scripts/functions

# Program starts here
# (c) Mathias Laurin, X11 license
# When called by the mk_fstab option, this script
# /etc/iniramfs-tools/script/local-bottom/mk_fstab is used to
# edit /etc/fstab on a read-only filesystem
#
# Options on the kernel line:
# mk_fstab

# Parse command line options
for x in $(cat /proc/cmdline); do
        case $x in
                mk_fstab)
                MK_FSTAB=1
                ;;
        esac
done

# Not called, exit gracefully
test -z "$MK_FSTAB" && exit 0

test ! -d $rootmnt/etc && exit 0

test -f $rootmnt/etc/fstab &&
log_warning_msg "/etc/fstab exists on the root filesystem and will be overwritten" &&
log_warning_msg "Changes should be made in /etc/initramfs-tools/script/local-bottom/$0"

log_begin_msg "Create /etc/fstab on the root filesystem"
cat << EOF > $rootmnt/etc/fstab
# /etc/fstab: static file system information.
#
# File created by mk_fstab during the init process
# If you want to modify this file, edit
# /etc/initramfs-tools/scripts/local-bottom/mk_fstab
# and run update-initramfs -u or your changes will be lost at the next reboot

LABEL=BOOT          /boot      ext2    noauto,noatime,noexec,nosuid,nodev 1 2
/dev/vg/home        /home      ext3    relatime,nosuid,nodev  1 1

/usr/opt            /opt        none    bind        0 0

#/dev/vg/swap_1      none        swap    sw          0 0

# vim: set expandtab sw=4 ts=4:
EOF
log_end_msg

The name and place of these scripts is written in the comments.

nsine 01-03-2011 08:58 AM

Hi,

Sorry for bringing up this thread, i've just used it successfully with debian lenny. (Thanks)
However as we know the RAMBOOT is non-persistant.

Is it a good idea to "restore" the ram back to the harddisk by copying the data back?
My main idea is to use this ramboot on my network firewall (router) without keeping the hdd spinning.
I want to keep the changes made to /etc (dhcp editing, adding/removing firewallrules, ...) and especially the logs.

- Boot into ramboot
- Mount the harddisk to a folder (see this as backupfolder)
- Create a snapshot dir from the ramboot to the backupfolder
- Create the tar snapshot and place it in the correct folder on the harddisk for the next boot
-------------------------
- Reboot (the new tar file should be used automatically)
- Remount the harddisk
- Rsync the ramboot with the "backupfolder" (with crontab or on halt/reboot)
- Recreate the tar snapshot from the "backupfolder" for the next reboot


Any other (better) ideas?

IsaacKuo 01-05-2011 10:46 AM

Quote:

Originally Posted by nsine (Post 4211485)
However as we know the RAMBOOT is non-persistant.

Is it a good idea to "restore" the ram back to the harddisk by copying the data back?

If you can figure out a method that does what you want it to do, then great! I didn't bother because I didn't want to do it. I liked the fact that the system was "reset" to the default state when rebooted.
Quote:

My main idea is to use this ramboot on my network firewall (router) without keeping the hdd spinning.
I want to keep the changes made to /etc (dhcp editing, adding/removing firewallrules, ...) and especially the logs.
My first instinct is that this is not a good idea. My RAMBOOT hack is already an ugly experimental hack, so I'd only do it for non-critical workstations. My router/firewall is a component that I just want to work with minimum fuss. If it's down, then internet access is down...which makes it that much harder for me to get things working again...

So, for me personally, I like to keep servers and routers as boring and "stock" as possible. Yeah, I'm a wuss...
Quote:

- Boot into ramboot
- Mount the harddisk to a folder (see this as backupfolder)
- Create a snapshot dir from the ramboot to the backupfolder
- Create the tar snapshot and place it in the correct folder on the harddisk for the next boot
-------------------------
- Reboot (the new tar file should be used automatically)
- Remount the harddisk
- Rsync the ramboot with the "backupfolder" (with crontab or on halt/reboot)
- Recreate the tar snapshot from the "backupfolder" for the next reboot
I don't see any reason why this wouldn't work, but then I always find that some little thing I never expected or even knew about messes things up so I have to tweak around to make everything work properly.

I mean--why in the world do the tar thing at all? Well, it's because the thing I THOUGHT would work (a simple recursive cp) didn't work (the limited cp available at the start just isn't powerful enough for the job). So I just messed around until I figured out a hack that would work.

synss 01-06-2011 03:46 AM

Quote:

Originally Posted by nsine (Post 4211485)
- Boot into ramboot
- Mount the harddisk to a folder (see this as backupfolder)
- Create a snapshot dir from the ramboot to the backupfolder
- Create the tar snapshot and place it in the correct folder on the harddisk for the next boot
-------------------------
- Reboot (the new tar file should be used automatically)
- Remount the harddisk
- Rsync the ramboot with the "backupfolder" (with crontab or on halt/reboot)
- Recreate the tar snapshot from the "backupfolder" for the next reboot

What's wrong with my scripts, then? They do offer the option to recreate the disk image.


All times are GMT -5. The time now is 11:07 PM.