воскресенье, 19 декабря 2010 г.

Использование BusyBox в LiveCD

Этот пост является логическим продолжением трех предыдущих:
LZMA сжатие в SquashFS-4.0
Создание LiveCD Slackware based: использование Squashfs
AUFS-2.1: установка и работа в связке с SquashFS

и заканчивает описание построения LiveCD по Slax-типу.

В прошлый раз я сетовал на то что оперативной памяти расходуется неоправданно много. Я подсчитал, что расход памяти равен размеру образа initrd умноженному на два плюс размер распакованного ядра плюс запущенные программы. Это непонятное умножение на два убивало все мои усилия сделать компактный LiveCD без перерасхода RAM. При старте машины с недостатком оперативки я заметил, что:
- ядро и образ initrd успешно загружаются, после чего начинается инициализация ядра,
- после инициализации ядро пытается распаковать образ initrd и на этом этапе происходит крах системы.

Ядро абсолютно не волнует что мой squashfs-архив не надо распаковывать и он сразу готов к использованию. Поразмыслив я решил что такое поведение осталось с тех времен, когда initrd был только архивом системного раздела, который требовалось предварительно распаковывать. те же кого не устраивает такое поведение ядра используют busybox и сами реализуют необходимую им функциональность. итак, что мне даст busybox в моём livecd?
- recovery-livecd будет работать на 64Мб ОЗУ,
- монтирование aufs сразу на корень, а не на отдельные папки,
- модульность slax. это значит что можно будет разбить системный раздел на несколько модулей. например: базовая часть, модули ядра, х-сервер, специфичное ПО и загружать ту или иную комбинацию. Это значит что не будет необходимости загружать два набора модулей ядра, загружаться будет только модуль выбранного ядра. также не будет необходимости делать раздельные релизы для консольной и X-версии, весь функционал будет воплощен в одном релизе.

Цена вопроса. У всего этого есть слабое место. После запуска busybox необходимо будет смонтировать носитель что бы скопировать модули в память. Это уязвимое место всех livecd на busybox. Потому что носитель может располагаться где угодно: на cdrom, флешке, жестком диске, сетевом носителе. У флешки и жесткого диска могут быть при этом какие угодно файловые системы. Нужен какой-то надежный способ указать носитель из загрузчика, например параметром типа root=/dev/sda3.
Пора посмотреть как это все работает на практике. Нужен будет LiveCD полученный в прошлом посте:
LZMA сжатие в SquashFS-4.0

заходим в рабочий каталог и распаковываем образ системного раздела:
# ./unsquashfs -d ./1 ./image

сначала нужно удалить нашу самодеятельность в инициализационном файле rc.S
# nano -w ./1/etc/rc.d/rc.S

здесь удаляем нашу вставку
/sbin/mount -t tmpfs -o size=1M tmpfs /opt/etc
/sbin/mount -t tmpfs -o size=1M tmpfs /opt/var
/sbin/mount -t tmpfs -o size=1M tmpfs /opt/tmp
/sbin/mount -t tmpfs -o size=1M tmpfs /opt/root
/sbin/mount -t aufs -o dirs=/opt/etc:/etc=ro none /etc
/sbin/mount -t aufs -o dirs=/opt/var:/var=ro none /var
/sbin/mount -t aufs -o dirs=/opt/tmp:/tmp=ro none /tmp
/sbin/mount -t aufs -o dirs=/opt/root:/root=ro none /root

сжимаем системный раздел без модулей
# ./mksquashfs ./1 ./image1 -comp lzma -b 1M -e ./1/lib/modules

и отдельно модули ядра
# mkdir -p ./2/lib
# cp -a ./1/lib/modules ./2/lib
# ./mksquashfs ./2 ./image2 -comp lzma -b 1M

удаляем каталоги и старый образ
# rm -r ./1 ./2 ./image

теперь нужен initrd с busybox'ом. он формируется утилитой mkinitrd. Так как носителем будет выступать болванка cdrom, чтобы его подмонтировать нам нужен будет модуль файловой системы ISO9660
# mkinitrd -c -k 2.6.34-rc6.aufs -m isofs -f isofs -r /dev/sr0 -o ./initrd.gz
OK: /lib/modules/2.6.34-rc6.aufs/kernel/fs/isofs/isofs.ko added.
5776 blocks
/tmp/livecd/./initrd.gz created.
Be sure to run lilo again if you use it.

осталось поправить конфиг isolinux.cfg. строка параметров должна выглядеть так
APPEND vga=normal initrd=initrd.gz root=/dev/ram0 rw vt.default_utf=1

livecd готов.
# ./mk

и в /tmp/mycd.iso получаем итоговый образ. вставляем его в VirtualBox и запускаем. После загрузки и инициализации ядра нас выкинет в консоль BusyBox с сообщением о невозможности смонтировать раздел. Упрощая, можно сказать, что задача busybox выполнить shell-скрипт init и прежде чем править этот скрипт неплохо бы было разобраться как это все должно работать. создадим служебные директории:
# mkdir -p /opt/1 /opt/2 /opt/3

монтируем cdrom и tmpfs
# mount /dev/sr0 /mnt
# mount -t tmpfs shm /opt/3

Примечание от 22.08.2012г.
В применимости к реальному livecd последняя команда монтирования tmpfs не является такой простой. Загвоздка в том, что по умолчанию для tmpfs монтируется половина оперативки и если у вас на машине 512Мб оперативки, а загрузить вы собираетесь 300Мб содержимого livecd то при копировании получите ошибку:
no left space on device

и kernel panic как следствие. В настоящее время в livecd перед монтированием tmpfs подсчитывается размер загружаемых модулей, немного накидывается "про запас" за счет преобразования байтов в мегабайты и далее монтируется необходимое пространство. как то так:
m=$(du -c перечисление_модулей_через_пробел |tail -n1|awk {'print $1'}|cut -c -3)
mount -t tmpfs -o size=$mM shm /opt/3



копируем модули в оперативку
# cp /mnt/image1 /opt/3
# cp /mnt/image2 /opt/3

cdrom больше не нужен - размонтируем его
# umount /mnt

монтируем модули в отдельные каталоги:
# mount /opt/3/image1 /opt/1
# mount /opt/3/image2 /opt/2

используя aufs создаем "бутерброд/сандвич" файловых систем на /mnt
# mount -t aufs -o br=/opt/3=rw:/opt/1=ro:/opt/2=ro aufs /mnt

осталось позаботиться о виртуальных ФС
# mount -o move /proc /mnt/proc
# mount -o move /sys /mnt/sys

и финальная команда смещающая корень в /mnt и запускающая процесс init livecd
# exec switch_root /mnt /init 3

после чего обычным образом загружается livecd.
Примерно такую последовательнось команд должен содержать скрипт init busybox'а для инициализации LiveCD.

Таким образом, перейдя от архитектуры RIPLinux к Slax LiveCD я сократил объем потребляемой памяти "Recovery LiveCD" в четыре раза, доведя ее с 256Мб до 64Мб. По сути говоря сама оригинальная болванка весит больше, а именно 72Мб. Все это дает мне свободу действий при создании livecd на основе графического-сервера где суммарный вес приложений может быть действительно большой. Это позволит мне не жертвовать функциональностью системы в угоду весу а создать полнофунциональный и сверхбыстрый дистрибутив LiveCD с расположением в ОЗУ.

1 комментарий:

  1. добавил небольшое объяснение того, как удалось уменьшить требование к минимальному размеру оперативной памяти LiveCD в версии 2.2

    ОтветитьУдалить