Skip to content

Instantly share code, notes, and snippets.

@avinash-oza
Last active April 24, 2024 10:09
Show Gist options
  • Save avinash-oza/9791c4edd78a03540dc69d6fbf21bd9c to your computer and use it in GitHub Desktop.
Save avinash-oza/9791c4edd78a03540dc69d6fbf21bd9c to your computer and use it in GitHub Desktop.
How to boot from RAM on debian

Booting Debian from a RAM disk

This guide is adapted from http://reboot.pro/topic/14547-linux-load-your-root-partition-to-ram-and-boot-it/

What you need:

  • lots of RAM
  • Debian based distribution or any that supports booting from initramfs
  • mkinitramfs or a tool to build a new initramfs
  • some linux knowledge
  • no need to create an image
  • no need for Grub4Dos
  • no need for a "special driver"

Step 1: Choose a distribution thats supports booting from initramfs. (like ubuntu)

Step 2: Install to harddisk. Make sure you split it into multiple partitions (/, /boot, /home, swap, ...).

Step 3: Boot your new system, install updates, drivers if neccessary (this will improve performance), strip it down to the minimum. Every file will be loaded to RAM ! A fresh install uses about 2 GB auf harddisk-space.

Step 4: modify /etc/fstab :

cp /etc/fstab /etc/fstab.bak find the line specifing the root partition and change it in: none / tmpfs defaults 0 0* save

Step 5: edit the local script in your initramfs: cd /usr/share/initramfs-tools/scripts/* make a backup of /usr/share/initramfs-tools/scripts/local cp local local.bak* modify local, find this line:

# FIXME This has no error checking

# Mount root

mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}

change it to:

# FIXME This has no error checking

# Mount root

#mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}

mkdir /ramboottmp

mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} /ramboottmp

mount -t tmpfs -o size=100% none ${rootmnt}

cd ${rootmnt}

cp -rfa /ramboottmp/* ${rootmnt}

umount /ramboottmp
  • save
  • execute, or rebuild initramfs mkinitramfs -o /boot/initrd.img-ramboot* replace modified local with original file cp -f local.bak localStep 6:
  • modify this file (needs a better solution) /boot/grub/grub.cfg* copy the first boot entry and replace the /initrd line with this: /initrd /boot/initrd.img-ramboot* label the new entry as RAMBOOT This will boot our generated initramfs instead the original one. Step 7:
  • reboot
  • choose standart boot (no ramdisk)
  • choose RAMBOOT and all your files on the root partition will be loaded to a tmpfs
@bathtime
Copy link

bathtime commented Dec 4, 2021

For me—running Debian 11 (bullseye)—this line:

/initrd /initrd.img-ramboot

should be:

/initrd /boot/initrd.img-ramboot

Otherwise, it works perfectly on my machine.

It's worth a mention that the screen will display only a flashing cursor for about a minute while it loads the system contents into ram. Could easily be mistaken for a frozen computer.

I have my Debian system fully installed on USB and use this method. Running in normal (non-ram) mode takes Firefox 7 seconds to load, and running on Ramboot, <2 seconds, so it definitely does speed things up.

Anyone know of a way to sync the ram back to the disk? Would be awesome to then have the ability to retain persistence if the user chose to at the end of their session.

Thanks so much for this guide and glad you've kept it up all these years!

@avinash-oza
Copy link
Author

avinash-oza commented Dec 6, 2021 via email

@bathtime
Copy link

bathtime commented Dec 6, 2021

Thanks. It would be helpful.

I've started a thread on the Debian forum to gather ideas: https://forums.debian.net/viewtopic.php?f=10&t=150930

Here's what I have so far:

mkdir /mnt

mount /dev/sda1 /mnt

# View in dry run mode which only shows what files would have been changed but makes no actual changes:
# Remove '--dry-run' flag to do sync
# Always do a dry run, and check what files will be changed, before running a true rsync
# --delete flag tells the system to delete a file if it's missing from the source. It might be best not to include this flag unless you're sure you're backing up all necessary files, else important stuff could be deleted
rsync --dry-run -av --delete --exclude proc/ --exclude media/ --exclude tmp/ --exclude mnt/ --exclude dev/ --exclude sys/ --exclude run/ / /mnt/ | less

sync

This code seems to be able to sync, and persist to next boot, at least a simple install of 'nano', but it did not keep the updated apt files. I cannot guarantee that this would work when installing complicated programs such as firefox or kernel updates.

@Sulunia
Copy link

Sulunia commented Dec 7, 2021

It's worth a mention that the screen will display only a flashing cursor for about a minute while it loads the system contents into ram. Could easily be mistaken for a frozen computer.

You can echo a message to the prompt before you begin loading data to RAM. Another option is to use Plymouth bootscreen

@bathtime
Copy link

bathtime commented Dec 11, 2021

Thanks Sulunia. I've tried echoing, but the notice will only remain on the screen for a few seconds.

...

Does anyone know how we can update the ramboot or change it? I tried going back and repeating the instructions at least a dozen times in different orders and with different configs, and I keep ending up with 'init not found' and 'cp: command not found' error at boot. To get it working again I just copy the old /boot/initrd.img-ramboot.bak back to /boot/initrd.img-ramboot, but that's just the old ramboot file.

EDIT

All has been fixed when I did a complete reinstall and got rid of my FrankenDebian OS, which had a mixture of stable + unstable packages—yeah, I know, what was I thinking??? Anyways, I can now update grub and run mkinitramfs without issue.

@avinash-oza
Copy link
Author

@bathtime : Here is the script I was using to sync back when I was running this: https://github.com/avinash-oza/home-projects/blob/master/nas/ram_backup

I kept the physical drive mount under /USB_OS. If I updated the OS files and wanted to persist it for whatever reason, I ran this script and it seemed to work fine.

@bathtime
Copy link

Thank you for this @avinash-oza

I figured out a way to show some information on the screen when copying into ram. First of all, I tried using rsync, but I found that such command was not available at this time in the boot process; only a select few commands are.

My improvised solution was to simply add a '-v' flag to the 'cp' command, to list the files being copied. IMO, it's better having something to look at than a blank screen for 2+ minutes:
cp -rfav /ramboottmp/* ${rootmnt}

It can also be quite informative! ;)

In the event that anyone finds it helpful, here's a script I made to do snapshots when in ramboot mode (you'll need a partition that is not in ram mode to save them!):

snapshot.sh:

#!/bin/sh

###########################################################################
### Script to take snapshots of your current OS when in ramboot mode.   ###
### Please, do not run this on a production machine! For testing only!  ###
###########################################################################

# Exit on error (DO NOT BE TEMPTED TO REMOVE THIS OR JUPITER HELP YOUR OS..!)
set -ep

# This is a persistent device (must not use a device/path stored in ram)
snapshotDir=/home/user/snapshots/
sourceDevice=/dev/sda2
sourceMount=/
targetMount=/mnt-target


sudo mkdir -p /mnt-target
mkdir -p ~/snapshots

[ "$(mount | grep $targetMount)" ] && sudo umount $targetMount
sudo mount $sourceDevice $targetMount 

DATE=`date "+%Y-%b-%d:_%T"`
echo "Backing up $Source to $Target\n\nSource mount: $sourceMount ($Source)\nTarget mount: $targetMount ($Target)\n"
echo "Snapshots will be stored to: $snapshotDir"
echo "\nBrowse files, and make sure the program is working properly.\nPress 'q' to exit browsing and create snapshot.\n"

sleep 6

sudo rsync --dry-run -avu --delete -inplace --backup --exclude $snapshotDir --exclude /lost+found/ --exclude /sys/ --exclude /proc/ --exclude /media/ --exclude /tmp/ --exclude /dev/ --exclude /home/user/share/ --exclude /run/ --exclude .cache/ --exclude /mnt/ --exclude /mnt-source/ --exclude /mnt-target/ --backup-dir=$snapshotDir$DATE "$sourceMount" "$targetMount" | less


# Give user time to reconsider
t=3; while [ $t -gt 0 ]; do echo -ne "\rCreating snapshot in $t seconds... Press ctrl-c to cancel."; t=$(( t - 1 )); sleep 1; done


echo -e "\n\nCreating snapshot...\n"

sudo rsync -avu --delete --inplace --backup --exclude $snapshotDir --exclude /lost+found/ --exclude /sys/ --exclude /proc/ --exclude /media/ --exclude /tmp/ --exclude /dev/ --exclude /home/user/share/ --exclude /run/ --exclude .cache/ --exclude /mnt/ --exclude /mnt-source/ --exclude /mnt-target/ --backup-dir=$snapshotDir$DATE "$sourceMount" "$targetMount"

echo "\nSnapshot created!\n"

# View snapshot file tree (sudo apt install tree)
sudo tree -a /home/user/share/snapshots/ | less

I've yet to write anything that would restore the snapshots, but for now, at least the information would be backed up.

...

Also, just thought I'd cross post on another project (hope that's okay?) which allows running one's system as an overlay, and I can attest it works on my machine: https://gist.github.com/jfernandz/bfb1285114c136ac2b86320cb06c3904

Information like your script and the link above seem like diamonds in the rough, so all the much better if people can find it easier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment