Ok, so here's the way the boot process works:
- firmware > bootloader maybe > kernel
${parameters}
> initramfs > userspace maybe
On a redhat installation disk their dracut system of scripts is what builds and constitutes initramfs and their anaconda installation system constitutes the final userspace.
It is udev
that handles the device setup - as in, it names the devices in /dev
. But this almost always happens twice - once in initramfs and again when the init
within has found its target root device and is ready to mount a devfs
on it.
So this is how it works:
bootloader (or firmware) invokes the kernel with an optional parameter set and an optional initramfs image. This parameter set is saved in /proc/cmdline
and the kernel ignores all parameters it doesn't understand.
The initramfs is a working linux userspace. Whether its /
contents are unpacked from an image handed it at invocation or they are compiled in doesn't matter - since kernel 2.6 it is always the first working root filesystem the linux kernel mounts. From this point the linux kernel leaves it all to userspace.
Usually (as is true for redhat's dracut) the initramfs contains only what is absolutely necessary to find a root device and mount it over itself. Generally all that is included is busybox
and the kernel modules required to mount your target root device.
It probably needs udev
to do that though, so udev
is most often included - with its own tiny little set of rules.
As mentioned, initramfs is its own little complete linux root filesystem. A complete one might look like: /bin /etc /dev /new_root /proc /sys init
. There's generally nothing very unusual about any of the contents of these directories - there's almost always a /bin/sh
and an /etc/fstab
.
Most init
s will parse /proc/cmdline
for any kernel parameters they might interpret. A very common one is root=/dev/somedisk
or root=UUID=somediskUUID
or root=LABEL=somedisklabel
. It is the initramfs init
that interprets these root=...
parameters - not the kernel or the final init
execed later (though the final one may very well interpret others). It will accept this parameter and mount it on /new_root
(or whatever name it uses for the staging mount before it switchroot
s). If udev
is included in initramfs then it is the initramfs ruleset that decides what that target disk's /dev/...
entry is named for now - but that can change.
When the initramfs init
successfully finds and mounts the /new_root
device it usually looks for something to exec
itself into - usually /new_root/bin/init
- so whatever that program is becomes pid 1. It usually does this with the switch_root
program provided with busybox
- which does an exec
while simultaneously mounting /new_root
over /
. Its process is described in the kernel docs thus:
But initramfs is rootfs: you can neither pivot_root
rootfs, nor umount
it. Instead delete everything out of rootfs to free up the space (find -xdev / -exec rm '{}' ';'
), overmount rootfs with the new root (cd /newmount; mount --move . /; chroot .
), attach stdin/stdout/stderr
to the new /dev/console
, and exec
the new init
.
The root device init
just execed now has to populate its own root filesystem. It calls its udev
and mounts its own devfs
on /dev
based on its own ruleset and does all the rest. When it's through you are ready to use your computer.
Sorry for the level of detail there, but I wanted to make it clear why the following is true:
- any kernel parameter you hand in from the bootloader like
root=/dev/sda
doesn't have to be the same /dev/sda
that you will eventually access on /dev/sda
after the initramfs /init
is through.
So one way to do this, I think, is to set a udev
rule on your anaconda disk - which is actually a squashfs archive, probably - that instructs it to setup all usb disks somewhere else. There's an excellent example here:
KERNEL=="sd*", SUBSYSTEMS=="scsi", ATTRS{model}=="USB 2.0 Storage Device", SYMLINK+="usbhd%n"
And it would be a very good thing if you read the rest of that link as well. You should be able to do that so your usb disk device is /dev/sda
for initramfs - so you don't have to change any bootloader configurations - but then later creates a node for the same disk as /dev/usba
for the anaconda install system.
/dev/sd[anything]/whatever
-- unless I'm about to learn something new, this should not be a real path. Files are in filesystems, not device nodes. – goldilocks Jul 22 '14 at 18:31/dev/sdX
is given manually (or through kickstart file) during installation, the kernel (or some other software) automatically chooses a mount point to load the files on. – skamazin Jul 22 '14 at 18:42/dev
reference. However, you should consider using consistent device names (e.g., labels or UUIDs). – HalosGhost Jul 22 '14 at 19:08/dev/sdb/fs.cfg
" -> Unless you have an explicit source of information to the contrary (I'm not intimate w/ kickstarter stuff), this has to be wrong (I'm saying this to save you some frustration)./dev/sdb
is a device node. You might mount this, e.g.,mount /dev/sdb /mnt/whatever
, and then you could access/mnt/whatever/fs.cfg
, but normally,/dev/sdb
is a dead stop in a path, because, again, it is not a directory, and cannot be used like a directory. – goldilocks Jul 22 '14 at 19:11sed
commands that substitutes 'UUID' for 'LABELS' in/etc/fstab
(thesed
commands are in a newer version of the kickstart) I'll add these commands to my kickstart. @goldilocks Whenever it fails to load the kickstart file the installer gives the user a choice of where is it located. Either insda
orsdb
. While I do agree that/dev/sdb/fs.cgf
would normally be impossible because/dev/sdb
is a dead stop, it appears to work (somehow) during installation. – skamazin Jul 22 '14 at 19:23sda
which is a problem for the kickstart files. – skamazin Jul 23 '14 at 14:44/dev/sda
. Whoops ;) – goldilocks Jul 23 '14 at 16:36