Difference between initrd and initramfs?

As far as I know, initrd acts like a block device, so a file system driver (e.g. ext2 ) is required. The kernel must have at least one built-in module for detecting the initrd file system. In this article, Introducing initramfs, a new model for initial RAM disks , it is written that:

But ramdisks actually spends even more memory due to caching. Linux - this is designed to cache all files and entries in directories read or written to lock devices, so Linux copies data to and from ramdisk to the "page cache" (for file data) and the "cache dentin" (for writing to the directory) . The disadvantage of ramdisk claiming to be a block device is treated as a block device.

What is page cache and dentry cache ? In this paragraph, it means that the data has been duplicated because ramdisk treated as a block device, so is all data cached?

In contrast mode ramfs :

A few years ago, Linus Torvalds had a great idea: what if the Linux cache can be mounted as a file system? Just store the files in the cache and never get rid of them until they are deleted or the system reboots? Linus wrote a tiny wrapper around the cache called "ramfs", and another kernel developer created an improved version called "tmpfs" (which can write data to replace the space and limit the size of this mount so that it fills up before consuming all available memory). Initramfs is an instance of tmpfs.

These ram-based file systems automatically grow or shrink to fit the size of the data they contain. Adding files to ramfs (or extending existing files) automatically allocates more memory and deletes or truncated files frees that memory. There is no duplication between the block device and the cache, since there is no block device. Copy to cache is the only copy of data. Best of all, this is not a new but new application for the existing Linux caching code, which means that it adds almost no size, is very simple and based on a very well tested infrastructure.

In sum, ramfs is just a file open and loaded into memory, isn't it?

Both initrd and ramfs clamped during compilation, but the difference is that initrd is a block device that is unpacked for installation by the kernel at boot, while ramfs unpacked via cpio into memory. I'm right? Or is ramfs very minimal file system?

Finally, still the initrd image is still displayed in the last core. However, what initrd is actually ramfs used today, and the name is for historical purposes only?

+52
linux filesystems kernel boot
May 15 '12 at 14:38
source share
4 answers

Dentry cache (and inode)

The Linux file system subsystem has three levels. VFS (virtual file system), which implements the system call interface and processes intersecting mount points and default permissions and restrictions. Below are the drivers for individual file systems, and those which in turn interact with drivers for block devices (disks, memory cards, etc., Network interfaces are an exception).

Several classes are the interface between VFS and the file system (it’s just C, so structures containing pointers to functions, etc., but this is an object-oriented interface is conceptual). The main three classes are the inode , which describes any object (file or directory) in the dentry file system, which describes the entry in the directory and file , which describes the file opened by the process. When installed, the file system driver creates inode and dentry root for it, while others are created on demand when the process wants to access the file and, ultimately, expired. This is cache and inode.

Yes, this means that for every open file and any directory to the root there should be inode and dentry structures allocated in the memory core that represent it.

Page Cache

On Linux, each page of memory containing user area data is represented by a single page structure. This may mean that the page is anonymous (it can be replaced with a swap space, if available) or associate it with an inode on some file system (it can be written and re-read from the file system), and it can be part of any number of memory cards, that is, visible in the address space of some process. The sum of all pages loaded into memory is the page cache.

Pages are used to implement the mmap interface, and although regular system read and write calls can be implemented by the file system in other ways, most interfaces use a common function that also uses pages. There are common functions that, when requested to read a file, select pages and call the file system to fill them one by one. For a file system based on block devices, it simply calculates the corresponding addresses and delegates this filling to the block device driver.

ramdev (ramdisk)

Ramdev is a regular block device. This allows you to place any file system on top of it, but it is limited by the interface of the block device. And it only has methods to fill in the page highlighted by the caller and write it back. This is exactly what is necessary for real block devices, such as disks, memory cards, a USB storage device, etc., But for ramdisk this means that the data exists in memory twice, once in ramdev memory and once in memory allocated to the caller subscriber.

This is an old way to implement initrd . Since the time when initrd was a rare and exotic occurrence.

Tmpfs

Tmpfs is different. This is a dummy file system. The methods that it provides VFS are the absolute minimum minimum to make it work (as such, it perfectly documents what the inode, dentry, and file methods should do). Files exist only if the inode cache has the corresponding inode and dentry created when the file was created and never expired until the file was deleted. Pages are associated with files when data is written and otherwise behave as anonymous (data can be stored in swap, page structures remain in use as long as the file exists).

This means that there are no extra copies of data in memory, and all this is much simpler and because of this a little faster. It simply uses data structures that serve as a cache for any other file system as the main storage.

This is a new way to implement initrd ( initramfs , but the image is still just called initrd ).

It is also a way to implement "posix shared memory" (which simply means that tmpfs is mounted on /dev/shm , and applications can freely create files there and mmap, simple and efficient) and recently even /tmp and /run (or /var/run ) often have tmpfs specifically designed for laptops so that the disks cannot spin or avoid wear in the case of SSDs.

+44
May 15 '12 at 16:05
source share

I think you're right about everything.

The difference is easy to see if you follow the steps necessary at boot:

initrd

  • The block device A ramdev . This is a ram-based block device, which is a simulated hard drive that uses memory instead of physical disks.
  • The initrd file is read and unpacked into the device, as if you were doing zcat initrd | dd of=/dev/ram0 zcat initrd | dd of=/dev/ram0 or something similar.
  • initrd contains an image of the file system, so now you can mount the file system as usual: mount /dev/ram0 /root . Naturally, the file system needs a driver, so if you are using ext2, the ext2 driver must be compiled in the kernel.
  • Done!

initramfs

  • A tmpfs : mount -t tmpfs nodev /root . Tmpfs does not need a driver, it is always on. No devices, no additional drivers required.
  • initramfs compressed directly on this new file system: zcat initramfs | cpio -i zcat initramfs | cpio -i or similar.
  • Done!

And yes, it is still called initrd in many places, although it's initramfs , especially in bootloaders, since for them it's just a BLOB. The difference is that the OS is loading.

+56
May 15 '12 at 15:27
source share

To add another noteworthy difference between initrd and initramfs not mentioned in the excellent answer above.

  • With initrd kernel by default passes pid 1 user space to /sbin/init
  • Newer initramfs, however, make a difference and run pid 1 in /init

how this can become a trap (see https://unix.stackexchange.com/a/147688/24394 )

+1
Jan 31 '19 at 12:10
source share

Minimal executable QEMU examples and beginner explanation

In this answer I will:

  • provide a minimal executable Buildroot + QEMU example for testing
  • explain the most fundamental difference between the two for beginners who are likely to resort to help

We hope that they will serve as the basis for testing and understanding the more specific details of the difference.

The minimum setup is fully automated , and this is the appropriate start .

The installation program prints QEMU commands as they are executed, and as explained in this repository, we can easily create the following three working download types:

  1. the root file system is in ext2 on the "hard drive":

     qemu-system-x86_64 -kernel normal/bzImage -drive file=rootfs.ext2 
  2. The root file system is in initrd:

     qemu-system-x86_64 -kernel normal/bzImage -initrd rootfs.cpio 

    -drive not provided.

    rootfs.cpio contains the same files as rootfs.ext2 , except that they have a CPIO format similar to .tar : it serializes directories without compressing them.

  3. The root file system is in initramfs:

     qemu-system-x86_64 -kernel with_initramfs/bzImage 

    Neither -drive nor -initrd are listed.

    with_initramfs/bzImage is a kernel compiled with parameters identical to normal/bzImage , with one exception: CONFIG_INITRAMFS_SOURCE=rootfs.cpio pointing to the same CPIO as in -initrd .

Comparing the settings, we can conclude the most fundamental properties of each:

  1. in the settings of the hard drive, QEMU loads bzImage into memory.

    This work is usually done by bootloaders / firmware on real hardware such as GRUB .

    The Linux kernel boots, then, using its drivers, reads the root file system from disk.

  2. in the initrd configuration, QEMU performs an additional load, in addition to loading the kernel into memory: also:

    This time, the kernel simply uses rootfs.cpio directly from memory, since there is no hard disk.

    Does not write persistently on reboots, since everything is in memory

  3. in configuring initramfs we build the kernel a little differently: we also give rootfs.cpio the kernel build system.

    The kernel build system then knows how to combine the kernel image and CPIO into one image.

    Therefore, all we need to do is pass bzImage to QEMU. QEMU loads it into the image, as for other settings, but nothing else is required: CPIO is also loaded into memory, since it is glued to the kernel image!

0
Jan 22 '19 at 10:32
source share



All Articles