Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org

Linux initial RAM disk (initrd) overview

31 Jul 2006

Linux® initial RAM disk (initrd)- временная рутовая файловая система,которая монтируется во время загрузки. initrd включает в себя различные утилиты и драйвера, которые уже в свою очередь монтируют реальную рутовую систему, после чего initrd RAM отмонтируется и освободит память. Во многих embedded Linux системах initrd является собственно рутовой файловой системой. Эта статья делает обзор RAM disk для Linux 2.6, включая его создание и использование в ядре.

Что такое initial RAM disk?

RAM disk (initrd)- стартовая рутовая файловая система,которая монтируется в первую очередь. initrd входит в состав ядра и грузится как его часть во время загрузки. Ядро монтирует initrd в первой части загрузочного процесса для последующей загрузки модулей и реальной рутовой файловой системы.

initrd включает минимальный набор каталогов и утилит, таких как insmod для инсталляции kernel modules.

В зависимости от того, что мы имеем- desktop или server- initrd является переходной файловой системой. Его время жизни минимально. В embedded systems initrd является постоянной рутовой файловой системой.

initrd image включает необходимые утилиты и системные файлы для второй фазы загрузочного процесса Linux.

В зависимости от версии Linux метод создания initial RAM disk может различаться. Например в Fedora Core initrd создается с помощью loop device. loop device- драйвер,который позволяет монтировать файл как блочное устройство. loop device может не быть в вашем ядре, для этого его можно сконфигурировать. с помощью (make menuconfig) с помощью установки Device Drivers > Block Devices > Loopback Device Support. Можно проверить наличие loop device следующим образом (имя initrd file name может варьироваться):


Listing 1. Inspecting the initrd (prior to FC3)
 # mkdir temp ; cd temp
 # cp /boot/initrd.img.gz .
 # gunzip initrd.img.gz
 # mount -t ext -o loop initrd.img /mnt/initrd
 # ls -la /mnt/initrd
 #
 

Можно посмотреть содержимое /mnt/initrd. initrd image file может и не иметь на конце расширение .gz, но тем не менее он все равно является архивным файлом.

Начиная с Fedora Core 3, initrd image-архив cpio. Для этого типа архива можно выполнить:


Listing 2. Inspecting the initrd (FC3 and later)
 # mkdir temp ; cd temp
 # cp /boot/initrd-2.6.14.2.img initrd-2.6.14.2.img.gz
 # gunzip initrd-2.6.14.2.img.gz
 # cpio -i --make-directories < initrd-2.6.14.2.img
 #
 

Результатом является небольшая файловая система как показано в Listing 3. В каталоге ./bin directory имеются nash (script interpreter), insmod для загрузки kernel modules, lvm (logical volume manager tools).


Listing 3. Default Linux initrd directory structure
 # ls -la
 #
 drwxr-xr-x  10 root root    4096 May 7 02:48 .
 drwxr-x---  15 root root    4096 May 7 00:54 ..
 drwxr-xr-x  2  root root    4096 May 7 02:48 bin
 drwxr-xr-x  2  root root    4096 May 7 02:48 dev
 drwxr-xr-x  4  root root    4096 May 7 02:48 etc
 -rwxr-xr-x  1  root root     812 May 7 02:48 init
 -rw-r--r--  1  root root 1723392 May 7 02:45 initrd-2.6.14.2.img
 drwxr-xr-x  2  root root    4096 May 7 02:48 lib
 drwxr-xr-x  2  root root    4096 May 7 02:48 loopfs
 drwxr-xr-x  2  root root    4096 May 7 02:48 proc
 lrwxrwxrwx  1  root root       3 May 7 02:48 sbin -> bin
 drwxr-xr-x  2  root root    4096 May 7 02:48 sys
 drwxr-xr-x  2  root root    4096 May 7 02:48 sysroot
 #
 

Обратите внимание на init file в корне. Этот файл вызывается в момент,когда initrd image разархивируется в RAM disk.

Инструменты для создания initrd

cpio command

Используя команду cpio, можно манипулировать cpio файлами. Cpio-это файловыйй формат,который включает в себя хидеры. Он включает в себя как ASCII,так и бинарный форматы. Для портабельности,используйте ASCII. Для уменьшения размера файла,используйте бинарный формат.

Для обычных Linux system, initrd image создается во время компиляции ядра. Утилита mkinitrd может быть использована для создания initrd с необходимыми библиотеками и модулями. Утилита mkinitrd является shell script. Также есть утилита YAIRD (Yet Another Mkinitrd), с помощью которой можно конструировать initrd.

Конструирование custom initial RAM disk

Поскольку во многих embedded systems нет дисков, там initrd используется перманентно. Listing 4 показывает,как создать initrd image. Здесь используется стандартный десктоп.


Listing 4. Утилита (mkird) для создания custom initrd
 #!/bin/bash
 
 # Housekeeping...
 rm -f /tmp/ramdisk.img
 rm -f /tmp/ramdisk.img.gz
 
 # Ramdisk Constants
 RDSIZE=4000
 BLKSIZE=1024
 
 # Create an empty ramdisk image
 dd if=/dev/zero of=/tmp/ramdisk.img bs=$BLKSIZE count=$RDSIZE
 
 # Make it an ext2 mountable file system
 /sbin/mke2fs -F -m 0 -b $BLKSIZE /tmp/ramdisk.img $RDSIZE
 
 # Mount it so that we can populate
 mount /tmp/ramdisk.img /mnt/initrd -t ext2 -o loop=/dev/loop0
 
 # Populate the filesystem (subdirectories)
 mkdir /mnt/initrd/bin
 mkdir /mnt/initrd/sys
 mkdir /mnt/initrd/dev
 mkdir /mnt/initrd/proc
 
 # Grab busybox and create the symbolic links
 pushd /mnt/initrd/bin
 cp /usr/local/src/busybox-1.1.1/busybox .
 ln -s busybox ash
 ln -s busybox mount
 ln -s busybox echo
 ln -s busybox ls
 ln -s busybox cat
 ln -s busybox ps
 ln -s busybox dmesg
 ln -s busybox sysctl
 popd
 
 # Grab the necessary dev files
 cp -a /dev/console /mnt/initrd/dev
 cp -a /dev/ramdisk /mnt/initrd/dev
 cp -a /dev/ram0 /mnt/initrd/dev
 cp -a /dev/null /mnt/initrd/dev
 cp -a /dev/tty1 /mnt/initrd/dev
 cp -a /dev/tty2 /mnt/initrd/dev
 
 # Equate sbin with bin
 pushd /mnt/initrd
 ln -s bin sbin
 popd
 
 # Create the init file
 cat >> /mnt/initrd/linuxrc << EOF
 #!/bin/ash
 echo
 echo "Simple initrd is active"
 echo
 mount -t proc /proc /proc
 mount -t sysfs none /sys
 /bin/ash --login
 EOF
 
 chmod +x /mnt/initrd/linuxrc
 
 # Finish up...
 umount /mnt/initrd
 gzip -9 /tmp/ramdisk.img
 cp /tmp/ramdisk.img.gz /boot/ramdisk.img.gz
 

initrd Linux distribution

Примером такого проекта является Minimax. Он умещается в 32MB и использует BusyBox и uClibc. Несмотря на размер, он использует 2.6 Linux kernel с большим набором всяких утилит.

Для создания initrd, создадим пустой файл, используя /dev/zero (набор нулей) и запишем его в ramdisk.img file. Результирующий файл получится размером 4MB (4000 1K blocks). Затем с помощью mke2fs создадим ext2 (second extended) файловую систему с помощью созданной пустышки. Монтируем этот файл в /mnt/initrd с помощью loop device. Теперь мы имеем корневую ext2 file system.

Следующий шаг-создание подкаталогов для создания рутовой файловой системы: /bin, /sys, /dev, /proc.

Альтернатива для ext2 file system

Для ext2 есть альтернативные файловые системы, с помощью которых можно уменьшить размер initrd image. Это romfs (ROM file system), cramfs (compressed ROM file system), squashfs (highly compressed read-only file system). Если вам нужно писать данные,ext2 работает прекрасно. И также e2compr является расширением ext2 file system,которая поддерживает компрессию.

Утилита BusyBox представляет из себя image, который включает в себя такие утилиты,как ash, awk, sed, insmod. Преимущество BusyBox в том,что он пакует много утилит в маленький образ. Это идеально для embedded systems. Копируем BusyBox image в каталог /bin. Симлинки указывают на утилиты BusyBox.

Затем создаем набор device files. Для этого создадим каталог /dev, используя -a опцию.

Финальным шагом является создание файла linuxrc. После того как ядро смонтирует RAM disk, оно ищет файл init для выполнения. Если файла init нет, ядро грузит linuxrc в качестве startup script. В этом файле делаются базовые настройки, такие как монтирование файловой системы /proc. Я также монтирую каталог /sys file и вывожу сообщения на консоль. Я вызываю ash (Bourne Shell clone), поэтому я общаюсь с рутовой файловой системой. linuxrc можно сделать исполняемым с помощью chmod.

В конце ваша root file system сделана. Она отмонтируется и сжимается с помощью gzip. Результирующий файл (ramdisk.img.gz) копируется в /boot,и его можно загрузить с помощтю GNU GRUB.

Для создания initial RAM disk, вызовите mkird, при этом образ автоматически создастся и ляжет в /boot.

Тестирование custom initial RAM disk

Поддержка Initrd в Linux kernel

Для поддержки initial RAM disk, ядро должно быть собрано с опциями CONFIG_BLK_DEV_RAM и CONFIG_BLK_DEV_INITRD.

Ваш созданный initrd image лежит в /boot, протестируем его. Можно загрузиться с него При загрузке GRUB нажмите на клавишу C для появления командной строки. Команда kernel позволит вам задать ядро, команда initrd определяет initrd image file. После этого наберите команду boot как показано в Listing 5.


Listing 5. Manually booting the kernel and initrd using GRUB
     GNU GRUB  version 0.95  (638K lower / 97216K upper memory)
 
 [ Minimal BASH-like line editing is supported. For the first word, TAB
   lists possible command completions. Anywhere else TAB lists the possible
   completions of a device/filename. ESC at any time exits.]
 
 grub> kernel /bzImage-2.6.1
    [Linux-bzImage, setup=0x1400, size=0x29672e]
 
 grub> initrd /ramdisk.img.gz
    [Linux-initrd @ 0x5f2a000, 0xb5108 bytes]
 
 grub> boot
 
 Uncompressing Linux... OK, booting the kernel.
 

После старта ядро проверяет наличие initrd image, и затем загружает его и монтирует. Окончание Linux startup можно посмотреть в Listing 6. При старте ash shell можно использовать для ввода команд. В примере я проверяю root file system. Я также создаю новый файл. Первый созданный процесс есть linuxrc (или init).


Listing 6. Booting a Linux kernel with your simple initrd
 ...
 md: Autodetecting RAID arrays
 md: autorun
 md: ... autorun DONE.
 RAMDISK: Compressed image found at block 0
 VFS: Mounted root (ext2 file system).
 Freeing unused kernel memory: 208k freed
 / $ ls
 bin         etc       linuxrc       proc        sys
 dev         lib       lost+found    sbin
 / $ cat /proc/1/cmdline
 /bin/ash/linuxrc
 / $ cd bin
 /bin $ ls
 ash      cat      echo     mount    sysctl
 busybox  dmesg    ls       ps
 /bin $ touch zfile
 /bin $ ls
 ash      cat      echo     mount    sysctl
 busybox  dmesg    ls       ps       zfile
 

Загрузка initial RAM disk

Загрузчик типа GRUB определяет ядро и копирует его и связанный с ним initrd в память. Подробности можно посмотреть в исходниках в подкаталоге ./init.

После декомпрессии и загрузки в память, запускается ядро. Выполняется инициализация-смотрите init/main.c:init(). Вызывается init/do_mounts.c:prepare_namespace(), которая подготавливает namespace (dev file system, RAID, md, devices, initrd). Загрузка initrd происходит с помощью init/do_mounts_initrd.c:initrd_load().

Функция initrd_load() вызывает функцию init/do_mounts_rd.c:rd_load_image(), которая определяет RAM disk image и грузит его с помощью функции init/do_mounts_rd.c:identify_ramdisk_image(). Она проверяет формат файловой системы с помощью т.н. magic number. Вернувшись в initrd_load_image, вызываем init/do_mounts_rd:crd_load(). Эта функция выделяет память для RAM disk, вычисляет cyclic redundancy check (CRC), и грузит RAM disk image в память.initrd image становится block device.

Монтирование block device начинается с вызова init/do_mounts.c:mount_root(). root device создан, вызывается init/do_mounts.c:mount_block_root(). Из нее вызываем init/do_mounts.c:do_mount_root() , которая вызывает fs/namespace.c:sys_mount() для монтирования root file system и затем chdir. Смотрите это место в Listing 6: VFS: Mounted root (ext2 file system).

Возвращаемся в функцию init и вызываем init/main.c:run_init_process. Вызывается execve для старта init process ( /linuxrc). linuxrc может быть скриптом либо исполняемым файлом.

Иерархия вызываемых функций показана в Listing 7. Здесь представлены не все функции.


Listing 7. Hierarchy of major functions in initrd loading and mounting
 init/main.c:init
   init/do_mounts.c:prepare_namespace
     init/do_mounts_initrd.c:initrd_load
       init/do_mounts_rd.c:rd_load_image
         init/do_mounts_rd.c:identify_ramdisk_image
         init/do_mounts_rd.c:crd_load
           lib/inflate.c:gunzip
     init/do_mounts.c:mount_root
       init/do_mounts.c:mount_block_root
          init/do_mounts.c:do_mount_root
            fs/namespace.c:sys_mount
   init/main.c:run_init_process
     execve
 

Diskless Boot

В сценариях embedded booting диск (floppy or CD-ROM) необязателен для загрузки ядра. Dynamic Host Configuration Protocol (DHCP) может быть использован для сетевых настроек. Trivial File Transfer Protocol (TFTP) может быть использован для перевода статуса ядра и initial ramdisk в local device.

Сжатие initrd

Если вам нужен минимальный размер initrd image, есть несколько хинтов. Первый-использование BusyBox. BusyBox занимает несколько метров.

BusyBox image в этой статье статически прилинкован и не требует никаких библиотек. Но если вам нужна стандартная C library (для бинарников), можно взять маленькую библиотеку uClibc, которая минимизирует размер стандартной C library. Другой вариант библиотеки-dietlib. Имейте ввиду,что в обоих случаях вам нужно пересобирать их.

Summary

initial RAM disk создан для перехода ядра от временной промежуточной рутовой файловой системы к основной. initrd также полезен как root file system для embedded Linux systems.

Resources

Learn
  • "Inside the Linux boot process" (developerWorks, May 2006) explores the Linux boot process from the initial bootstrap to the start of the first user-space application.

  • In "Boot Linux from a FireWire device" (developerWorks, July 2004), see how you can start Linux (with its initrd) from a multitude of devices on a variety of platforms.

  • The cpio file format is both simple and compact. It's no wonder the Fedora team chose it as a format option for the initrd.

  • The mkinitrd utility is ideal for creating initrd images. In addition to creating an initrd image, it also identifies the modules to load for your particular system and populates them into the image.

  • The loop device is a great driver for mounting image files as file systems.

  • The Network Boot and Exotic Root HOWTO illustrates not only booting Linux from the network, but also other interesting scenarios such as floppy boot, CD-ROM boot, and embedded scenarios.

  • In the developerWorks Linux zone, find more resources for Linux developers.

  • Stay current with developerWorks technical events and Webcasts.

Get products and technologies
  • The cpio file format (now supported as a Fedora Core initrd image format) has a long history and operates on a wide range of UNIXes.

  • The ash shell is a Bourne Shell clone (mostly compliant) that is small, but does the job. It's great for use as a script interpreter in space-constrained Linux embedded systems.

  • BusyBox is a great way to shrink the memory requirements for your next embedded Linux project.

  • To shrink the size of your initrd even further, consider using a C library alternative to glibc, such as uClibc or dietlib. If you prefer C++, you can try the alpha version of the uClibc++ library.

  • Minimax is a Linux distribution that fits entirely in an initrd image!

  • Order the SEK for Linux, a two-DVD set containing the latest IBM trial software for Linux from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.

  • With IBM trial software, available for download directly from developerWorks, build your next development project on Linux.


Discuss
  • Check out developerWorks blogs and get involved in the developerWorks community.

    Оставьте свой комментарий !

    Ваше имя:
    Комментарий:
    Оба поля являются обязательными

     Автор  Комментарий к данной статье