24

I found out that if I choose jffs or sd as filesystem (and not initramfs), the kernel size will be very small (1.4 MB as compared to with initramfs which is 3.4MB). It means that initramfs takes considerably large space. So if I can, I'd completely remove it, and thus will have very small kernel, which is what I want.

The basic question popping in my mind is: Why do I need initramfs? Can't a Linux kernel boot without having any initial filesystem?

My end application will only do calculation & communication - no storage at all. So an OS without a filesystem makes sense - at the least for my application.

7
  • 2
    You cannot do without initramfs. Its possible to do without the additional initramfs file, but regardless of what you do, the kernel includes its very own empty or not. So I don't understand your question - what distribution are you talking about? How are you building your kernel? Can you provide the kernel .config file? These are very important. I suspect your distro is compiling its initramfs directly into the kernel - and therefore filling the otherwise empty initramfs it contains - but I can't know based on the information you've provided.
    – mikeserv
    Commented Mar 29, 2014 at 12:07
  • 2
    @mikeserv, obviously a built in but empty/unused initramfs does not count.
    – psusi
    Commented Mar 30, 2014 at 1:29
  • Well, @psusi the kernel docs disagree. And I'm only so adamant about it because there doesn't need to be any mystery - its just /root - that's it. The only thing it does differently is switch_root but even that, provided proper precautions are taken with certain loaded kernel modules, can be done at any time. Initramfs is nothing more than a disk image - brimming or no, it's there. And you're never without it - it's your root after all. It just shouldn't be a mystery, is what I think, and I dislike all of the unnecessary confusion surrounding it.
    – mikeserv
    Commented Mar 30, 2014 at 2:41
  • 2
    @mikeserv, no, /root is the home directory for the root user. The rootfs is /, which then has the real root mounted over top of it. You are just arguing semantics. For the purposes of this discussion, not having an initramfs means not having a file on the disk your boot loader has to load and pass to the kernel.
    – psusi
    Commented Mar 30, 2014 at 2:52
  • That is true, i only used /root for clarity's sake, but I'll give you that one. But no, theyre not semantics, theyre the fundamental mechanics of your linux kernel. These are basic things. Lets just try to get them right.
    – mikeserv
    Commented Mar 30, 2014 at 2:55

7 Answers 7

15

The size increase of having an initramfs is not due to the ramfs driver (it's only a few kB, and needed for other things anyway) but to the initramfs itself. The initramfs contains programs that are necessary to assemble and mount the real root filesystem.

Initramfs makes it a lot easier, and in some cases possible (e.g. encrypted /), to boot the system. It is strongly recommended to keep it on PC-style hardware with lots of hotpluggable peripherals. On the other hand, it makes a lot of sense to boot an embedded device without any initramfs, with a kernel that just supports the particular hardware configuration it's built for.

The kernel of course needs to boot to a filesystem: there has to be some way for it to load whatever application you want to run. If you aren't going to run anything, then you might as well keep the machine powered off.

If you don't want to use an initramfs, just tell your bootloader not to pass one. Also don't include one in the output of kernel build, of course — how this happens if at all is architecture- and bootloader-dependent: for example, vmlinux and bzImage don't include the initramfs (they're the raw and compressed kernel respectively), but uImage (for U-Boot) packs both the kernel and the initramfs if there is one.

(Technically, as mikeserv notes, there's always an initramfs — but by default, it's an empty, 134-byte archive. What you're seeing, and wanting to get rid of, is a “true”, non-empty initramfs created by your build process and containing tools which are then used to mount the root filesystem.)

Mind you, an initramfs can be a reasonable way of making a single-application system with no persistent data: put all of your application into the initramfs, boot that and keep it. This makes it easier to organize your persistent storage or boot image (all you need is the kernel and initramfs, which can be bundled). There are downsides to this approach however: all data in the initramfs will be stored in RAM permanently, and you can't easily modify the files in the boot image, you have to rebuild the archive.

4
  • If youre using a 2.6 or newer linux kernel you have initramfs. Whether or not you use a secondary initramfs image, as is customary, is another matter, but initramfs is not optional.
    – mikeserv
    Commented Mar 30, 2014 at 2:13
  • 2
    @mikeserv You have one, yes. But an empty initramfs is peanuts. It doesn't have to be used (which requires that it contains enough programs to mount the real root, which increases the size in a non-negligible way in a typical embedded system). Commented Mar 30, 2014 at 2:14
  • Compulsory peanuts anyway. And i dont know when i said otherwise! The asker was requesting information on how to remove it as a filesystem - which is not possible.
    – mikeserv
    Commented Mar 30, 2014 at 2:17
  • And yes it does have to be used - without initramfs there is no root. Ever.
    – mikeserv
    Commented Mar 30, 2014 at 2:18
10

From LFS:

The only purpose of an initramfs is to mount the root filesystem. The initramfs is a complete set of directories that you would find on a normal root filesystem. It is bundled into a single cpio archive and compressed with one of several compression algorithms.

...

There are only four primary reasons to have an initramfs in the LFS environment: loading the rootfs from a network, loading it from an LVM logical volume, having an encrypted rootfs where a password is required, or for the convenience of specifying the rootfs as a LABEL or UUID. Anything else usually means that the kernel was not configured properly.

...

For most distributions, kernel modules are the biggest reason to have an initramfs. In a general distribution, there are many unknowns such as file system types and disk layouts. In a way, this is the opposite of LFS where the system capabilities and layout are known and a custom kernel is normally built. In this situation, an initramfs is rarely needed.

Another source www.kernel.org

Beside of this there are a lot of Linux systems which like routers who do not use initramfs.

0
2

You need an initramfs for more complex setups, such as network boot, or lvm or raid, since they require some user mode utilities to configure access to the root fs. For a simple, conventional partition on a disk, then as long as you have the disk drivers built into the kernel, and specify the root argument by device path rather than UUID, then you can do without an initramfs. Of course, the device path is subject to change, depending on what plug and play ( i.e. usb ) devices you have connected, or even simply random timing variances, which is why pretty much everyone uses uuids and an initramfs for reliability.

4
  • This is also incorrect.
    – mikeserv
    Commented Mar 30, 2014 at 2:36
  • 12
    @mikeserv, your comment is useless. If you are going to claim that, you need to explain why.
    – psusi
    Commented Mar 30, 2014 at 2:37
  • I have done, or rather, the kernel documentation composing some 99% of my answer does.
    – mikeserv
    Commented Mar 30, 2014 at 2:54
  • @mikeserv, it is correct. I am running Gentoo linux for years now without initramfs.
    – Tim
    Commented Aug 14, 2018 at 13:30
1

This is an old question but still does not appear to have an accepted answer so I'll throw this out there (I am no expert here, I am trying to figure this out for myself.)

From https://www.kernel.org/doc/Documentation/early-userspace/README (all the way at the bottom which says it has not been updated since 2004.)

The kernel has currently 3 ways to mount the root filesystem:

a) all required device and filesystem drivers compiled into the kernel, no initrd. init/main.c:init() will call prepare_namespace() to mount the final root filesystem, based on the root= option and optional init= to run some other init binary than listed at the end of init/main.c:init().

b) some device and filesystem drivers built as modules and stored in an initrd. The initrd must contain a binary '/linuxrc' which is supposed to load these driver modules. It is also possible to mount the final root filesystem via linuxrc and use the pivot_root syscall. The initrd is mounted and executed via prepare_namespace().

c) using initramfs. The call to prepare_namespace() must be skipped. This means that a binary must do all the work. Said binary can be stored into initramfs either via modifying usr/gen_init_cpio.c or via the new initrd format, an cpio archive. It must be called "/init". This binary is responsible to do all the things prepare_namespace() would do.

To maintain backwards compatibility, the /init binary will only run if it comes via an initramfs cpio archive. If this is not the case, init/main.c:init() will run prepare_namespace() to mount the final root and exec one of the predefined init binaries.

For what it's worth, I believe devices/ distros such as Raspberry Pi, etc. do not use initramfs; in some cases the kernel is on the root partition (mounted by the bootloader which has requisite fs modules.) In other cases where the kernel is e.g. on a /boot partition, the initramfs on the same partition can be accessed directly before mounting the rootfs as others have stated.

In some cases the initramfs can be built into the same file as the kernel but this is not always the case. (a) seems to state pretty clearly that in some cases initramfs is not necessary.

1

If your root partition is on a disk that uses an MBR partition table and you want a persistent block device name as the root= parameter for the kernel, you need to use an initramfs. /dev/sdX isn't persistent, PARTUUID= is a GPT-only feature and LABEL= and UUID= aren't visible to the kernel in the early stages of boot. An initramfs can load the storage and filesystem drivers so LABEL= and UUID= are visible to the kernel.

0

No matter what you do, you have initramfs. There is no doing without it - it is the only filesystem imposed upon you. From kernel.org:

What is rootfs?

Rootfs is a special instance of ramfs (or tmpfs, if that's enabled), which is always present in 2.6 systems. You can't unmount rootfs for approximately the same reason you can't kill the init process; rather than having special code to check for and handle an empty list, it's smaller and simpler for the kernel to just make sure certain lists can't become empty.

Most systems just mount another filesystem over rootfs and ignore it. The amount of space an empty instance of ramfs takes up is tiny.

If *CONFIG_TMPFS* is enabled, rootfs will use tmpfs instead of ramfs by default. To force ramfs, add "rootfstype=ramfs" to the kernel command line.

What is initramfs?

All 2.6 Linux kernels contain a gzipped "cpio" format archive, which is extracted into rootfs when the kernel boots up. After extracting, the kernel checks to see if rootfs contains a file "init", and if so it executes it as PID 1. If found, this init process is responsible for bringing the system the rest of the way up, including locating and mounting the real root device (if any). If rootfs does not contain an init program after the embedded cpio archive is extracted into it, the kernel will fall through to the older code to locate and mount a root partition, then exec some variant of /sbin/init out of that.

All this differs from the old initrd in several ways:

  • The old initrd was always a separate file, while the initramfs archive is linked into the linux kernel image. (The directory linux-*/usr is devoted to generating this archive during the build.)

  • The old initrd file was a gzipped filesystem image (in some file format, such as ext2, that needed a driver built into the kernel), while the new initramfs archive is a gzipped cpio archive (like tar only simpler, see cpio(1) and Documentation/early-userspace/buffer-format.txt). The kernel's cpio extraction code is not only extremely small, it's also __init text and data that can be discarded during the boot process.

  • The program run by the old initrd (which was called /initrd, not /init) did some setup and then returned to the kernel, while the init program from initramfs is not expected to return to the kernel. (If /init needs to hand off control it can overmount / with a new root device and exec another init program. See the switch_root utility, below.)

  • When switching another root device, initrd would pivot_root and then umount the ramdisk. But initramfs is rootfs: you can neither pivot_root rootfs, nor unmount 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.

Since this is a remarkably persnickety process (and involves deleting commands before you can run them), the klibc package introduced a helper program (utils/run_init.c) to do all this for you. Most other packages (such as busybox) have named this command "switch_root".

Populating initramfs:

The 2.6 kernel build process always creates a gzipped cpio format initramfs archive and links it into the resulting kernel binary. By default, this archive is empty (consuming 134 bytes on x86).

The config option CONFIG_INITRAMFS_SOURCE (in General Setup in menuconfig, and living in usr/Kconfig) can be used to specify a source for the initramfs archive, which will automatically be incorporated into the resulting binary. This option can point to an existing gzipped cpio archive, a directory containing files to be archived, or a text file specification such as the following example:

  dir /dev 755 0 0
  nod /dev/console 644 0 0 c 5 1
  nod /dev/loop0 644 0 0 b 7 0
  dir /bin 755 1000 1000
  slink /bin/sh busybox 777 0 0
  file /bin/busybox initramfs/busybox 755 0 0
  dir /proc 755 0 0
  dir /sys 755 0 0
  dir /mnt 755 0 0
  file /init initramfs/init.sh 755 0 0

Run "usr/gen_init_cpio" (after the kernel build) to get a usage message documenting the above file format.

One advantage of the configuration file is that root access is not required to set permissions or create device nodes in the new archive. (Note that those two example "file" entries expect to find files named "init.sh" and "busybox" in a directory called "initramfs", under the linux-2.6.* directory. See Documentation/early-userspace/README for more details.)

The kernel does not depend on external cpio tools. If you specify a directory instead of a configuration file, the kernel's build infrastructure creates a configuration file from that directory (usr/Makefile calls scripts/gen_initramfs_list.sh), and proceeds to package up that directory using the config file (by feeding it to usr/gen_init_cpio, which is created from usr/gen_init_cpio.c). The kernel's build-time cpio creation code is entirely self-contained, and the kernel's boot-time extractor is also (obviously) self-contained.

16
  • 1
    You can boot without an initramfs. Your answer expounds on the merits of initramfs, but that doesn't apply to typical embedded systems, and even on desktops or servers where an initramfs is recommended, it is not compulsory. Commented Mar 30, 2014 at 1:38
  • @Gilles - no you cant. Regardless of what you do, you have initramfs. It's compiled into the kernel - right now, your kernel, my kernel, all of our kernel's. Read the kernel docs - my entire post was a copy-paste. You are incorrect. How can you dispute the official documentation?
    – mikeserv
    Commented Mar 30, 2014 at 2:06
  • 1
    I don't dispute the official documentation, I dispute the conclusions that you're drawing from it. You're reading documentation that explains how to use an initramfs. Nowhere does it state that the initramfs has to be used. Commented Mar 30, 2014 at 2:12
  • @Gilles If this is not good enough: " The 2.6 kernel build process always creates a gzipped cpio format initramfs archive and links it into the resulting kernel binary. By default, this archive is empty (consuming 134 bytes on x86)...." I can do better. The above was a 2 or 3 minute web search.
    – mikeserv
    Commented Mar 30, 2014 at 2:15
  • 3
    I have read the documentation. I do this for a living. It's not a matter of opinion. There is always an initramfs, but it isn't necessarily used for booting. I can't find a decent explanation of the kernel structure for that case, presumably because it's the classic case that's thought not to warrant explanation. The main logic is in do_mounts.c — specifically prepare_namespace, in which saved_root_name comes populated with the root= command line argument. Commented Mar 30, 2014 at 2:46
0

I find the following explanation more clear,

initramfs is a root filesystem that is embedded into the kernel and loaded at an early stage of the boot process. It is the successor of initrd. It provides early userspace which can do things the kernel can't easily do by itself during the boot process.

Using initramfs is optional. By default, the kernel initializes hardware using built-in drivers, mounts the specified root partition, loads the init system of the installed Linux distribution. The init system then loads additional modules and starts services until it eventually allows you to log in. This is a good default behavior and sufficient for many users. initramfs is for users with advanced requirements; for users who need to do things as early as possible, even before the root partition is mounted.

Here are some examples of what you can do with initramfs:

  • Mount the root partition (for encrypted, logical, and otherwise special partitions);
  • Provide a minimalistic rescue shell (if something goes wrong);
  • Customize the boot process (e.g. print a welcome message, boot splash, etc.);
  • Load modules (e.g. third party drivers);
  • Anything the kernel can't do (as long as you can do it in user space, e.g. by executing commands). If you don't have advanced requirements, you don't need initramfs.

You must log in to answer this question.

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