3

I'm trying various ways of Linux installation (from iso, flash, iso on flash, kernel on flash, root FS in iso-file on flash...) and want to understand what's going on.

My question is: is it possible, given the built kernel and ramfs files from a distribution (vmlinuz and initrd), to find out, where they are going to look for the "/" file system? Is it possible to configure this without re-compiling the kernel?

And one more: when kernel loads the root filesystem from loopback device, created from .iso-filesystem, how can I configure this process? Thanks!

EDIT: In fact, GRUB configuration contains GRUB root, which is not the real kernel root filesystem location, but just a folder that contains GRUB's belongings,.

The real root is configured in init script in initrd as described here.

That's how Debian kernel finds an ISO file on hard drive, when booting from it - initramfs finds it: http://www.debian.org/releases/stable/i386/apas02.html.en#howto-getting-images-hard-disk; note that GRUB configuration doesn't contain any reference to ISO location.

4 Answers 4

6

It is given at boot time by your bootloader, for example Grub.

To see with which arguments your kernel was started, do this:

$ cat /proc/cmdline

For me, this ouputs:

BOOT_IMAGE=/vmlinuz-3.5.0-13-generic root=/dev/mapper/crypt-precise--root ro

So the initrd/initramfs will try to mount my /dev/mapper/crypt-precise--root (encrypted LVM) logical volume as /.

You can re-configure Grub to load other operating systems from your harddrive using the same kernel (multi-boot) or edit this line runtime by pressing e while selecting (not yet booting) the Grub entry.

For recent Debian-based distributions, changing it permanently works like this:
(be careful, you may not be able to boot into your original operating system again!)

In the file /etc/default/grub set some GRUB_CMDLINE_LINUX="root=/dev/mydevice" yourself and update Grub by doing update-grub.

However, I recommend you to configure multiboot, otherwise it's not possible to change or update your Grub configuration again easily.

4
  • Thanks, gertvdijk! (I should've found that myself, just overlooked lines in config, sorry.) Sep 18, 2012 at 18:40
  • Hey, gertvdijk, seems, that you deceived me with your answer :) See my update to the question. Oct 1, 2013 at 15:53
  • @Bob No, I think you're overlooking the fact that the initrd you're referring to is not the same as the one you install - note the hd-media prefix in the docs. Also, "The real root is configured in init script [...]" <-- is taken from the kernel parameter, unless the initrd is customized to load it from somewhere else (like the Debian hd-media version of the initrd.)
    – gertvdijk
    Oct 1, 2013 at 16:54
  • Ok, that's fair, there might be no initramfs at all. :) hd-media is a temporary kernel and initramfs for CD image installer, but its initramfs, who makes the kernel search for root in .ISO, not GRUB. Thanks and cheers! Oct 1, 2013 at 18:02
3

Given the boot image, you could find internal kernel version string with file command:

%> file /boot/vmlinuz-linux
/boot/vmlinuz-linux: Linux kernel x86 boot executable bzImage, version 3.5.3-1-NAME (X@Y) #1 SMP PREEMPT WEEK MON DAY, RO-rootFS, swap_dev 0x5, Normal VGA
1

On most installations, you specify the root device to the bootloader. The root device is passed to the kernel as a parameter called root. Depending on the bootloader, this may be part of the kernel command line arguments (which may look like ro quiet root=/dev/sda1) or a separate setting. For some common bootloaders:

  • Lilo: in the configuration file (/etc/lilo.conf), there is a root directive to indicate the Linux root device.
  • Grub legacy (versions 0.9x): in the configuration file (typically /boot/grub/menu.lst), the root device is passed as part of the kernel command line (kernel directive). Note that there is a different root directive for Grub itself; that tells Grub where to look for files such as the kernel. On many systems, the Grub configuration file is generated by the update-grub script which fills in the root device from the installed system (using /boot/grub/device.map).
  • Grub 2 (versions 1.9x): in the configuration file (typically /boot/grub/grub.cfg), the root device is passed as part of the kernel command line (linux directive). Note that there is a different root variable (set root=(hd0,1)) that tells Grub where to look for files such as the kernel. On many systems, the Grub configuration file is generated by the update-grub script which fills in the root device from the installed system (using /boot/grub/device.map).
  • U-Boot: the root device is passed as part of the command line arguments in the bootargs environment variable. The U-Boot binary contains a default value baked in at compile time, which can be overridden by a setting in flash memory (if the device permits).

In the absence of a root command line argument, the initrd or initramfs, if used, may try to find a root partition to mount. Even in the presence of a root argument, the initrd or initramfs may decide to use a different device. The code calls switch_root to switch from the initrd to the actual root.

The default root device when there is no root command line argument is determined at compile time. You can change that value in a binary image with the rdev utility.

On a booted kernel, you can see the root parameter (if any) that was passed to the kernel in /proc/cmdline. You can see the actual device mounted on / in /proc/mounts.

0
1

Not sure if this is still something of interest but for the sake of future googlers like myself:

There are two separate root directories in play when booting/installing from grub. There is the grub root and the linux root (I'm not sure if this is the technical term).


The grub root can be set within the grub.cfg, and determines which files are readily visible within grub. The default grub root should be the root directory of the drive booting grub, so if the contents of your bootable drive are:

/boot/
/boot/grub2/
/boot/grub2/grub.cfg
...

Then the location of the grub.cfg from the grub root is /boot/grub2/grub.cfg

The grub root can be changed in the grub.cfg using set root=.

You can use this to set the root to a directory within the current root (set root=/boot/ would cause the grub.cfg to be located at /grub2/grub.cfg) which behaves similar to a chroot in Linux.

You can also change the current root to another drive (set root=(hd0,1) would set your root to hd0, partition 1. For a full listing of what devices you can use, see the grub page about it http://www.gnu.org/software/grub/manual/grub.html#Device-syntax).

While changing the grub root can be useful, you can also prefix any path with whatever you were going to use (e.x. linux (hd0,1):/boot/OS/RHEL/isolinux/vmlinuz instead of set root=(hd0,1) first). Also, once the kernel starts the grub root is irrelevant


As for the Linux root, that is a parameter you can pass the kernel (vmlinuz) when you load it. For this you can pass the kernel a parameter root= (this value will appear in /proc/cmdline)

However it's important to note that this new root is expected to contain a Linux root filesystem (looking for /etc/ /var/ and so on). When installing you provide the initrd (INITial Ram Disk) which contains these elements, so you probably don't want/need to change the Linux root during installation.

If you do change the Linux root be wary that Linux installation media is not a Linux root filesystem, though the initrd.img contained within is.


If what you're trying to do is use files within your iso as arguments to your kernel then there is a solution. If you create a loopback device in grub the device will persist when the kernel starts (so you should see a device called /dev/loop0 in the Linux root during installation)

I'll give a little snippet of a grub.cfg that relates to ISOs and RHEL specifically:

menuentry "RHEL" {
    set isofile='/boot/iso/RHEL.iso' #this is just a grub variable

    loopback loop $isofile           #mount the $isofile with label=loop as a loopback device

    set root=(loop)                  #set the grub root to the mounted iso (so / is the top level directory in the iso)

    #this starts the kernel and passes the paramter inst.stage2 using the ISO and kickstart as a location on the loopback device created by grub (the syntax for this line is liable to change between distros)
    linux /isolinux/vmlinuz noeject inst.ks=hd:/dev/loop0:/ks/ks.cfg inst.stage2=hd:LABEL=USBDRIVELABEL:/$isofile  

    initrd /isolinux/initrd.img      #provide an initial ramdisk (which will become the **Linux root**
}

Be aware that the syntax for the kernel line in grub.cfg is:

linux [path to kernel] [kernel argument 1] [kernel argument 2] ...

The kernel arguments will all appear in /proc/cmdline. It's important to note that because they are processed by the kernel grub syntax is not valid.

You can find more about this in the grub documentation (http://www.gnu.org/software/grub/manual/grub.html#Introduction)

and kernel parameters archwiki page (https://wiki.archlinux.org/index.php/kernel_parameters#GRUB)

as well as boot options for your relevant distro (RHEL https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Installation_Guide/chap-anaconda-boot-options.html#list-boot-options-sources)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .