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 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
|