User:Pietinger/Tutorials/Initramfs Overview

From Gentoo Wiki
Jump to:navigation Jump to:search
This article is a stub. Please help out by expanding it - how to get started.

Tutorial: Initramfs Overview

In my point of view we have the best descriptions of an initramfs in our Wiki here ... but it is all a little bit "mixed". This tutorial gathers all links and informations needed to understand initramfs a little bit better (hopefully). Only links to our Wiki will be used.

What is an initramfs ?

In very easy words: It is a small linux system your kernel can start before of your main linux system. If you use an initramfs, it MUST mount your root partition of your main system, because kernel will not do this job anymore. In most cases it will also start your /sbin/init as last step, so your usual system start will run afterwards (or - very seldom - initramfs do all steps by itself to boot up your system).

Why ? / When do I need an initramfs ?

Because you can do things at boot-time a kernel is not able to do. Most famous example is: Decrypting a root partition. But there are also other reasons to use it. I will give you later some links for these "Solutions".

Type of initramfs

You can have two types of an initramfs: Embedded into the kernel image or as an external CPIO archive. This leads to two questions:

1. What are the advantages and disadvantages ?

2. How to build them ?

My answer to the first question:

Advantage of an embedded: Very easy to build IF you have access to kernel configuratiion (= not possible if you use the bin-kernel).

Disadvantage: If you want to change something IN your initramfs you must compile the kernel again.

Advantage of an external CPIO archive: You can change/update to other kernel versions without needing to compile your kernel again (if you can use the initramfs for many different kernel versions). Used in binary distributions OR in Linux-Boot-CD.

Disadvantage: You must configure one additional kernel command line parameter (initrd=) so your kernel can find (and load) this CPIO archive.

What do I need to build an initramfs ?

You can use a tool to build it automatically. For this we have enough articles and it is not part of this description.

For building it manually we need at minimum two files: The "new" init = your personal script, which kernel starts now instead of /sbin/init, and a list of files which shall be included in your initramfs. Instead of this file-list you can also build a directory with all needed files inside. So, here you have also two options. Together with the type of an initramfs you will now have 4 options for building an initramfs ;-)

Initramfs and your main root partition

As said before, your initramfs must mount your root partition and therefore needs the same information as kernel has needed before: Where is my root partition ? Here you have some choices ... depending if you use a bootmanager or if you use a stub kernel which will be started from your UEFI directly. See more here: User:Pietinger/Tutorials/Kernel_Commandline_Parameter

Building an initramfs

I will begin with the easiest type ...

Embedded with a file-list

1. Copy both files into a directory you like. In most articles here in our wiki /usr/src/initramfs is used. Your init-file MUST have the name "init". Your file-list can can have every name you like, but in most articles here in our wiki /usr/src/initramfs/initramfs_list is used.

2. Configure your kernel with:

KERNEL
General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    (/usr/src/initramfs/initramfs_list) Initramfs source file(s)
    [*]   Support initial ramdisk/ramfs compressed using gzip
    Built-in initramfs compression mode (Gzip)  --->

3. Build your kernel with "make" and install it - as you always do.

An example for this you will find here: Early_Userspace_Mounting#Building_as_an_embedded_Initramfs

Embedded with a directory

1. Copy your init AND all files you need into a directory you like. In most articles here in our wiki /usr/src/initramfs is used.

2. Configure your kernel with:

KERNEL
General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    (/usr/src/initramfs/) Initramfs source file(s)
    [*]   Support initial ramdisk/ramfs compressed using gzip
    Built-in initramfs compression mode (Gzip)  --->

( You see the difference in "Initramfs source file(s)", do you ? )

3. Build your kernel with "make" and install it - as you always do.

Now it is time to give you a link to a great Wiki article: Custom_Initramfs#Directory_structure

External CPIO archive with a file-list

1. Copy both files into a directory you like. In most articles here in our wiki /usr/src/initramfs is used. Your init-file MUST have the name "init". Your file-list can can have every name you like, but in most articles here in our wiki /usr/src/initramfs/initramfs_list is used.

2. Do these steps:

root #make -C /usr/src/linux/usr/ gen_init_cpio
root #cd /usr/src/linux
root #chmod +x usr/gen_init_cpio usr/gen_initramfs.sh
root #usr/gen_initramfs.sh -o /root/initram.cpio /usr/src/initramfs/initramfs_list
root #gzip --best /root/initram.cpio

3. Copy this file either into your /boot directory OR into your efi-directory of your ESP (depending if you use a bootmanager or an UEFI boot).

4. You need this in your kernel configuration:

KERNEL
General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    () Initramfs source file(s)
    [*]   Support initial ramdisk/ramfs compressed using gzip
    Built-in initramfs compression mode (Gzip)  --->

5. Configure your bootmanager or your UEFI that kernel will get the needed command line parameter: See next chapter.

An example for this you will find here: Early_Userspace_Mounting#Building_as_an_external_CPIO_archive

External CPIO archive with a directory

1. Copy your init AND all files you need into a directory you like. In most articles here in our wiki /usr/src/initramfs is used.

2. Do these steps:

root #cd /usr/src/initramfs
root #find . -print0 | cpio --null --create --verbose --format=newc | gzip --best > /boot/custom-initramfs.cpio.gz

3. Copy this file either into your /boot directory OR into your efi-directory of your ESP (depending if you use a bootmanager or an UEFI boot).

4. You need this in your kernel configuration:

KERNEL
General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    () Initramfs source file(s)
    [*]   Support initial ramdisk/ramfs compressed using gzip
    Built-in initramfs compression mode (Gzip)  --->

5. Configure your bootmanager or your UEFI that kernel will get the needed command line parameter: See next chapter.

An example for this you will find here: Custom_Initramfs#Packaging

Special Case: Building an embedded initramfs with a CPIO archive

If you have already an external CPIO archive but you want an embedded initramfs then you can build it with a "make" and these kernel settings:

KERNEL
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    (/PATH/TO/MY/myinitram.cpio) Initramfs source file(s)

or:

KERNEL
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    (/PATH/TO/MY/myinitram.cpio.gz) Initramfs source file(s)
    [*]   Support initial ramdisk/ramfs compressed using gzip
    Built-in initramfs compression mode (Gzip)  --->

It is important to use suffix .cpio so "make" understand it is a CPIO file !

It is important to use suffix .cpio.gz so "make" understand it is an already gzipped CPIO file

(Both is explained in /usr/src/linux/usr/Makefile )

Telling the kernel where to find its external CPIO archive

This is done with the kernel commandline parameter "initrd=..." and you have a description already in Early_Userspace_Mounting#Bootloader_configuration

Telling initramfs where to find the "real" root partition

This is a little bit more complicated because it depends how your init evaluates a kernel command line parameter. In most cases a "root=/dev/sdXY" will always work. Because this can sometimes lead to troubles it is recommended to use the ID of your root partition. Here it could be we must change something.

In many cases you cannot use a "root=PARTUUID=..." anymore WHEN init is a busybox-shell-script and needs "root=UUID=..." instead. Just look into the description of your "Solution".

Of course there exists also a rare used option: You can hardcode the UUID of your root partition directly in your init. In this case your init doesnt need the parameter "root=.." anymore (this is only used for security reasons). An example you will find in my (german) forums post: https://forums.gentoo.org/viewtopic-t-1159297.html

Why do I need an additional line when using an embedded initramfs ?

You have read Early_Userspace_Mounting and you want to know why this line is additionally necessary:

FILE /usr/src/initramfs/initramfs_list
nod /dev/console 0600 0 0 c 5 1

The answer is: The kernel needs ALWAYS /dev/console BEFORE starting an initramfs (even if your initramfs uses a "mount -t devtmpfs none /dev").

Next question is: But why I dont need it when building an external CPIO archive ?

Because our "make" will ALWAYS (*) build an embedded initramfs - even if you dont want ;-) For this it takes the file /usr/src/linux/usr/default_cpio_list and builds with this an (additional) embedded initramfs. Now look into this file ...

(* as soon as you have enabled [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support)

So, I have two initramfs ? Yes, your kernel merges this embedded initramfs with your external CPIO archive together (at boot-time).

Solutions

You need only one link: Custom_Initramfs#Examples ... ;-)