Here's a hypothetical situation which I consider might be plausible:
- The targeted machine is EFI.
grub
is either never installed on the target or has been utterly wiped from the system.
- it can only ever interfere and offers nothing of value otherwise.
So what we might do in the above case is configure a boot option for a small installation/rescue image we keep on our /esp
or EFI system partition.
If anything were ever to go wrong with our current installation, then, for so long as we can at least access the EFI system partition by some means, then we can interface our firmware and set the machine to boot to our recovery image on next reboot. In that case all we would have to do is change a text file or two, cross our fingers and run reboot now
.
Here is a basic set of commands for a minimally configured Arch Linux (because it's what I use) system which could still do as I describe.
First, we'll make a work directory and download some files.
- I use
aria2c
here. I recommend it, but use whatever works.
- I unzip
rEFInd
with 7za
but the same
tool preference is yours in all cases here.
If you're not reading this within a few hours/days of my posting it, then there is a very good chance that the links used below are not current.
mkdir /tmp/work && cd /tmp/work || exit
aria2c 'magnet:?xt=urn:btih:331c7fac2e13c251d77521d2dc61976b6fc4a033&dn=archlinux-2015.06.01-dual.iso&tr=udp://tracker.archlinux.org:6969&tr=http://tracker.archlinux.org:6969/announce' \
'http://iweb.dl.sourceforge.net/project/refind/0.8.7/refind-cd-0.8.7.zip'
7za x ref*.zip; rm ref*zip
Next I'll make an image disk.
Now I'll partition that disk with the gdisk
utility and assign it to a loop device.
- This is a scripted shortcut for the options you'd want to feed the program interactively. It will create a GUID partition table and a partition of type EFI-system that spans the first available 750Mib of the target disk and another linux default partition spanning the rest of the disk.
- These partitions will be
/dev/sda1
and /dev/sda2
respectively if you're using a real disk, which will be /dev/sda
rather than ./img
. It is usually desirable to add more than one partition for a linux root, which is assumed to be the purpose of /dev/sda2
.
printf
script or no, the gdisk
program is easy to use - and so you might do better to go at it interactively instead. The target disk should not be mounted when it is run, and you'll probably need root rights to w
rite the changes.
- As a general rule you can do pretty much whatever you want in that program without any effect until you
w
rite - so be sure when you do.
I'll be putting my $TGT
in a shell variable. Except for its definition here, which you may want to tailor as necessary, where I use it so can you.
printf %s\\n o y n 1 '' +750M ef00 \
n 2 '' '' '' '' w y |
gdisk ./img >/dev/null
TGT=$(sudo losetup --show -Pf img)p
We'll need a filesystem on the esp, too. It must be FAT.
And we'll make some mount
directories and start extracting the relevant files.
set ref ref*iso \
arch arch*iso \
efi arch/EFI/archiso/efiboot.img
while [ "$#" -gt 0 ]
do mkdir "$1" || exit
sudo mount "$2" "$1"
shift 2
done; mkdir esp
Install rEFInd
...
Now we'll mount
our esp and get the needed files off of the Arch install disk to get our own live bootable rescue disk.
- Most live disks implement a sort of ugly hack to make the flat, unpartitioned iso filesystem look like an acceptable boot device to a UEFI system while still maintaining backwards compatibility w/ BIOS systems.
- Arch Linux is no exception.
This ugly hack is that efiboot.img
currently mounted on ./efi
. It's where we'll find our kernel and initramfs image file. The other ones on the disk (in ./arch/arch/boot
) will not work for EFI systems.
sudo sh -ec <<CONF '
mount "$1" esp
cp -ar efi/EFI/archiso esp/EFI
cp -ar arch/arch/*x86* esp/EFI/archiso
mkdir esp/EFI/archiso/cow
xargs > esp/EFI/archiso/refind_linux.conf
umount efi arch
rm -rf efi arch*' -- "$TGT"1
\"arch_iso\" \"archisobasedir=EFI/archiso \
archisolabel=VESP \
copytoram \
cow_label=VESP \
cow_directory=/EFI/archiso/cow\
cow_persistence=P \
cow_spacesize=384M \
initrd=EFI/archiso/archiso.img\"
CONF
You have essentially just installed - from the ground up - a pre-boot rescue environment with a persistent copy-on-write save file (so you might, for example systemctl enable sshd_socket
now and the setting would persist in the live system's next boot). The Arch Linux live install media now resides on your system's boot partition and can be called from the boot menu at any time. Of course, you also installed the boot menu manager.
- A couple of things about the above should stand out to you:
- I use
*x86*
because I have a 64-bit machine and that glob gets what I need. For a 32-bit installation (but why?) use *686*
instead.
- What I need, by the way, is a total of only 7 files and approximately 300M.
- The live-system's rootfs is the squashed image in
esp/EFI/archiso/x86_64/airootfs.sfs
.
- I specify the disk by label. There are no hints or other such nonsense - the disk is named and so it is easily found. You'll need to substitute in whatever you chose for an esp label instead of
VESP
.
- The
copytoram
kernel parameter instructs the Arch Linux live init
system to copy its rootfs image into a tmpfs before loopmounting it - which frees you actually to access the esp when working in that environment. Most live install systems offer similarly arranged constructs.
Where EFI shines is in its ability to handle a filesystem. On modern computers there is absolutely no need to pack some raw binary and wedge it in between your disk partitions. It astounds me that people still do, when, instead, they could manage and configure their boot environment with simple text files arranged in a regular, everyday directory tree. Above I put the kernel and initramfs in their own named folder in a central tree structure. The EFI - which will take its cues from rEFInd
in this case for convenience - will invoke that at boot by pathname because it mounts the esp.
Now all that is left to do is to ensure you understand how to select the system which will actually boot when you need to. Understand - you can boot this right now. You can do it in a virtual machine w/ qemu
(you'll need OVMF -pflash
firmware) or you can reboot your computer and rEFInd
will detect the kernel and pass its pathname to the firmware which will load and execute the Arch Linux live system. When you install a more permanent system on the disk - or several (which you can do right now if you so choose by rebooting to the live disk and performing the installation) - you'll want to keep its kernel and initramfs in the same structure. This is very easily arranged.
If, for example, you were to install a system on a root partition named, for lack of an imagination, root
, you'd want to set it up something like this:
mount --bind
its particular boot folder over the root /boot
path in /etc/fstab
.
You'll need two lines in /etc/fstab
and to create a mount point in /esp
to handle this.
sudo sh -c <<\FSTAB '
[ -d /esp ] || mkdir /esp
findmnt /esp || mount -L ESP /esp
mkdir -p /esp/EFI/root
cp /boot/kernel binary \
/boot/initramfs.img \
/esp/EFI/root
mount -B /esp/EFI/root /boot
cat >> /etc/fstab
echo "$1">/boot/refind_linux.conf
' -- '"new_menu_item" "root=LABEL=root"'
LABEL=ESP /esp vfat defaults 0 2
/esp/EFI/root /boot none bind,defaults 0 0
FSTAB
You only ever have to do anything like that once per installation - and that is assuming you didn't set it up that way in the first place - which is easier because the kernel and initramfs will already be where they belong. Once you've got those lines in /etc/fstab
and a minimal config file in /boot/refind_linux.conf
you're set for good. You can support as many installations as you like on the same system with the same /esp
device and centralize all bootable binaries in the same tree just like that. Different
systems will do things a little differently - Windows takes a little more cajoling to get it to conform, for example - but they will all work.
Ok, the last thing you need to know, as I said before, is how choose the next booting installation from the filesystem. This is configured in the file /esp/EFI/BOOT/refind.conf
.
- You should read this file - it's probably 99% comment and will tell you all about what you might do with it.
- Of course, you don't really have to do anything - by default
rEFInd
will boot the most recently updated kernel in its scan tree.
But I usually wind up setting the following options:
<<\DEF sudo tee \
/esp/EFI/BOOT/refind.conf.def
### refind.conf.def
### when renamed to refind.conf this file
### will cause refind to select by default
### the menu item called "new_menu_item"
### in its /boot/refind_linux.conf
default_selection new_menu_item
### this file will also set the menu timeout
### to only 5 seconds at every boot
timeout 5
### END
DEF
And the rescue file...
<<\RES sudo tee \
/esp/EFI/BOOT/refind.conf.res
### refind.conf.res
### this one will default to selecting
### the entry named "arch_iso" with a
### 10 second timeout
default_selection arch_iso
timeout 10
### END
RES
- And so now you can just move them around.
- For example, to make the rescue environment definitely boot after you do
reboot now
...
sudo cp /esp/EFI/BOOT/refind.conf.res \
/esp/EFI/BOOT/refind.conf
- And substitute
.def
for the .res
used above, of course, to go back to default root.
mount ./btrfsimage; btrfs dev replace "$(losetup -j ./btrfsimage)" /dev/install-disk start
if you can accept abtrfs
source/target fs. It will just start doing the job immediately in the background and you can do whatever you want in the meanwhile. It would also work with a booted live-disc as the source (which is above got w/losetup
). – mikeserv Jun 29 '15 at 00:32man btrfs-replace
to get a better idea. – mikeserv Jun 29 '15 at 05:45kexec
doesn't persist a reboot - the only thing that does is firmware. All of the offered ideas - DRBL, DRAC - are based around server solutions - you run a server that some preconfigured pre-boot environment knows how to talk to, and have a chat. iPXE would be my recommendation along the same lines. Otherwise you'll need to interface the firmware directly (and iPXE kind of does) which isn't so hard in some cases but is entirely off topic here. Read about the DHCP bootp and tftp protocols. Check out PLoP linux. The virtual drive you desctibe is why i suggested btrfs-replace, though. – mikeserv Jun 29 '15 at 05:51btrfs-replace
.btrfs
can add devices to a storage array on the fly. It doesn't care if the array is made up of loopmounts either. So if you add two devices to am array - a loop moounted file with your image and a real disk which you want to target, you canbtrfs-replace
the loop device in that array w/ the target disk and it's all done by the filesystem automatically. So provision an image, mount it, then replace it is all you have to do. you can do it every boot. – mikeserv Jun 29 '15 at 07:44