Как создать зацикленное корневое устройство

Теперь, когда все основные принципы объяснены, можно перейти к созданию зацикленного корневого устройства.

Требования

Создание зацикленного корневого устройства потребует от вас нескольких вещей.

Наиболее важно иметь доступ к работающему Linux-у. Это необходимо по причине того, что зацикленное устройство может быть создано только в Linux-е. Это означает, что нельзя создать работающую машину с зацикленной корневой файловой системой из ничего. От этой Linux-системы потребуется возможность собрать на ней ядро.

После создания зацикленное устройство будет представлять из себя большой файл. Я использовал примерно 80 Мб файлов, но этого достаточно только, чтобы сделать Х-терминал, а возможно, если вы захотите чего-то большего, вам потребуется больше места. Этот файл должен быть скопирован на DOS-раздел, то есть придется использовать или сеть, или кучу флоппи-дисков.

Вам также понадобится следующее программное обеспечение:

Это все должно входить в последние инсталляции дистрибутивов Linux.

Создаем ядро Linux

Я создал зацикленное устройство с использованием ядра версии 2.0.31, другие версии тоже должны работать, но они должны поддерживать все опции, перечисленные ниже.

Опции ядра, которые вам надо будет включить:

Первые две опции - это сам электронный диск и загрузочный электронный диск. Следующая - это зацикленная файловая система. Последние две - это поддержка файловой системы msdos, которая необходима для подключения DOS-раздела.

Сборка ядра без модулей - это наиболее простой способ, но если вы все-таки решили использовать модули, это возможно, хотя я этого и не пробовал. Если вы используете модули, вы должны убедиться в том, что опции, используемые выше, встроены в ядро, а не собраны в виде модулей.

В зависимости от версии вашего ядра, вам, возможно, придется установить патч к ядру. Это очень простой патч, который разрешает использование зацикленной файловой системы в виде корневой.

Для ядер версий 2.0.x в файл /init/main.c надо добавить одну строку, в соответствии с уже измененной версией, приведенной ниже. В строке, которую надо добавить написано "loop", 0x0700.

static void parse_root_dev(char * line)
{
	int base = 0;
	static struct dev_name_struct {
		const char *name;
		const int num;
	} devices[] = {
		{ "nfs",     0x00ff },
		{ "loop",    0x0700 },
		{ "hda",     0x0300 },

...

		{ "sonycd",  0x1800 },
		{ NULL, 0 }
	};

...

}

Для ядер версий 2.2.x в файл /init/main.c надо добавить три строки, в соответствии с уже измененной версией, приведенной ниже. Надо добавить строку, в которой написано "loop", 0x0700, а также предшествующую и следующую за ней:

static struct dev_name_struct {
	const char *name;
	const int num;
} root_dev_names[] __initdata = {
#ifdef CONFIG_ROOT_NFS
	{ "nfs",     0x00ff },
#endif
#ifdef CONFIG_BLK_DEV_LOOP
        { "loop",    0x0700 },
#endif
#ifdef CONFIG_BLK_DEV_IDE
	{ "hda",     0x0300 },

...

	{ "ddv", DDV_MAJOR << 8},
#endif
	{ NULL, 0 }
};

После того, как ядро настроено, его необходимо собрать в файл zImage (команда make zImage). Этот файл будет находиться в каталоге arch/i386/boot/zImage.

Создаем загрузочный электронный диск

Загрузочный электронный диск проще всего создавать, как зацикленное устройство с самого начала. Вы должны делать это в качестве root-а. Список команд, которые вы должны запустить, приведен ниже. Они предполагают запуск из личного каталога root-а (/root).

mkdir /root/initrd
dd if=/dev/zero of=initrd.img bs=1k count=1024
mke2fs -i 1024 -b 1024 -m 5 -F -v initrd.img
mount initrd.img /root/initrd -t ext2 -o loop
cd initrd
[create the files]
cd ..
umount /root/initrd
gzip -c -9 initrd.img > initrdgz.img

Здесь производится несколько действий, которые можно вкратце описать так:

  1. Создаем точку подключения загрузочного электронного диска (пустой каталог).

  2. Создаем пустой файл необходимого размера. Я здесь использовал 1024 Кб, вам может понадобиться меньше или больше, в зависимости от содержимого (размер задается в последней опции).

  3. Создаем файловую систему ext2 в пустом файле.

  4. Подключаем этот файл к точке подключения, с использованием зацикленного устройства.

  5. Переходим ко вновь подключенному зацикленному устройству.

  6. Создадим там все необходимые файлы (см. ниже).

  7. Выходим из подключенного зацикленного устройства.

  8. Отключаем устройство.

  9. Создаем компрессированную версию для дальнейшего использования.

Содержимое загрузочного электронного диска

На загрузочном диске нужно иметь все файлы, необходимые для запуска любых команд:

Содержимое загрузочного электронного диска, которое я использовал, приведено ниже. Оно заняло примерно 800 Кб, если принимать в расчет излишки файловой системы.

total 18
drwxr-xr-x   2 root     root         1024 Jun  2 13:57 bin
drwxr-xr-x   2 root     root         1024 Jun  2 13:47 dev
drwxr-xr-x   2 root     root         1024 May 20 07:43 etc
drwxr-xr-x   2 root     root         1024 May 27 07:57 lib
-rwxr-xr-x   1 root     root          964 Jun  3 08:47 linuxrc
drwxr-xr-x   2 root     root        12288 May 27 08:08 lost+found
drwxr-xr-x   2 root     root         1024 Jun  2 14:16 mnt

./bin:
total 168
-rwxr-xr-x   1 root     root        60880 May 27 07:56 ash
-rwxr-xr-x   1 root     root         5484 May 27 07:56 losetup
-rwsr-xr-x   1 root     root        28216 May 27 07:56 mount
lrwxrwxrwx   1 root     root            3 May 27 08:08 sh -> ash

./dev:
total 0
brw-r--r--   1 root     root       3,   0 May 20 07:43 hda
brw-r--r--   1 root     root       3,   1 May 20 07:43 hda1
brw-r--r--   1 root     root       3,   2 Jun  2 13:46 hda2
brw-r--r--   1 root     root       3,   3 Jun  2 13:46 hda3
brw-r--r--   1 root     root       7,   0 May 20 07:43 loop0
brw-r--r--   1 root     root       7,   1 Jun  2 13:47 loop1
crw-r--r--   1 root     root       1,   3 May 20 07:42 null
crw-r--r--   1 root     root       5,   0 May 20 07:43 tty
crw-r--r--   1 root     root       4,   1 May 20 07:43 tty1
crw-r--r--   1 root     root       1,   5 May 20 07:42 zero

./etc:
total 3
-rw-r--r--   1 root     root         2539 May 20 07:43 ld.so.cache

./lib:
total 649
lrwxrwxrwx   1 root     root           18 May 27 08:08 ld-linux.so.1 -> ld-linux.so.1.7.14
-rwxr-xr-x   1 root     root        21367 May 20 07:44 ld-linux.so.1.7.14
lrwxrwxrwx   1 root     root           14 May 27 08:08 libc.so.5 -> libc.so.5.3.12
-rwxr-xr-x   1 root     root       583795 May 20 07:44 libc.so.5.3.12

./lost+found:
total 0

./mnt:
total 0

Единственным сложным пунктом здесь являются устройства в каталоге dev. Используйте команду mknod, чтобы создать эти устройства, или используйте устройства в каталоге /dev, как шаблон для необходимых устройств.

Файл /linuxrc

Файл/linuxrc на загрузочном электронном диске нужен для того, чтобы произвести все приготовления, необходимые для подключения зацикленного устройства как корневого.

Скрипт, приведенный ниже пытается подключить /dev/hda1 как раздел msdos, и если это происходит удачно, то он настраивает файлы /linux/linuxdsk.img как /dev/loop0 и /linux/linuxswp.img как /dev/loop1.

#!/bin/sh

echo INITRD: Trying to mount /dev/hda1 as msdos
# echo INITRD: Попытка подключить /dev/hda1 как msdos

if /bin/mount -n -t msdos /dev/hda1 /mnt; then

   echo INITRD: Mounted OK
   # echo INITRD: Подключение  успешно
   /bin/losetup /dev/loop0 /mnt/linux/linuxdsk.img
   /bin/losetup /dev/loop1 /mnt/linux/linuxswp.img
   exit 0

else

   echo INITRD: Mount failed
   # echo INITRD: Подключение не удалось
   exit 1

fi

Первое устройство /dev/loop0 станет корневым, а второе - /dev/loop1 - станет swap-пространством.

Если вы хотите иметь возможность писать на DOS-раздел, не будучи root-ом, когда все будет завершено, то вы должны использовать команду mount -n -t msdos /dev/hda1 /mnt -o uid=0,gid=0,umask=000,quiet, вместо приведенной выше. В этом режиме доступ к DOS-разделу буду исполняться так, как будто это делает root.

Создаем корневое устройство

Корневое устройство, которое вы будете использовать - это файл linuxdsk.img. Его вам придется создать самим так же, как вы создавали загрузочный электронный диск, но значительно большего размера. Вы можете установить любой дистрибутив Linux, который вам понравится, на этот диск.

Наиболее простой путь для этого - скопировать существующую инсталляцию Linux в этот файл. Другой путь - установить туда Linux с дистрибутива. Предполагая, что вы это сделали, внесем некоторые незначительные изменения.

Файл /etc/fstab должен ссылаться на корневой раздел и swap-пространство через два зацикленных устройства, настроенных загрузочным электронным диском.

/dev/loop0     /      ext2   defaults 1 1
/dev/loop1     swap   swap   defaults 1 1

Таким образом, вы будете уверены в том, что ядро не ошибется относительно реального местоположения корневой файловой системы. Также swap-пространство будет организовано обычным образом так, как будто используется обычный swap-раздел. Вы должны удалить все строки, ссылающиеся на корневое файловое устройство или swap-раздел.

Если хотите иметь возможность читать DOS-раздел под Linux-ом? вам придется внести еще несколько небольших изменений.

Создайте каталог /initrd, куда будет подключен загрузочный электронный диск после подключения зацикленной корневой файловой системы.

Создайте символьную ссылку /DOS, которая будет указывать на /initrd/mnt, куда, в свою очередь, будет подключен реальный DOS-раздел.

Добавьте строку в rc-файл, которая будет подключать диски. Там должна быть команда mount -f -t msdos /dev/hda1 /initrd/mnt, которая создаст 'поддельное' подключение DOS-раздела, чтобы программы (например, df) знали, что DOS-раздел подключен, и где его найти. Если вы использовали другие опции в файле /linuxrc, то, очевидно, вам придется их использовать и здесь.

Нет необходимости в том, чтобы иметь ядро Linux на этом корневом зацикленном устройстве, так как оно загружено ранее. Если вы используете модули, можете включить их в это устройство обычным образом.

Создаем Swap-устройство

Swap-устройство, которое вы будете использовать - это файл linuxswap.img. Swap-устройство очень просто создать. Создайте пустой файл так же, как делали это для загрузочного электронного диска, и затем запустите mkswap linuxswap.img для его инициализации.

Размер swap-устройства, которое вы будете использовать, зависит от ваших планов по использованию новой системы, но я бы рекомендовал его от 8 Мб до размера вашей оперативной памяти.

Создаем каталог MSDOS

Файлы, которые будут нами использоваться, необходимо переписать на DOS-раздел.

В DOS-каталоге C:\LINUX должны находиться следующие файлы:

Создаем загрузочный флоппи-диск

Загрузочный флоппи-диск, который мы будем использовать, является простым загрузочным диском DOS.

Он создается командой DOS format a: /s.

На этом диске вам надо создать файл AUTOEXEC.BAT (пример приведен ниже) и скопировать туда ядро, компрессированный загрузочный электронный диск и программу LOADLIN.

В файле AUTOEXEC.BAT должна быть только одна строка.

\loadlin \zImage initrd=\initrdgz.img root=/dev/loop0 ro

Здесь указано, какой образ ядра использовать, какой образ загрузочного электронного диска использовать, а также корневая файловая система, которая должна быть подключена "только для чтения".