[РЕШЕНО] INITRD-строение - нужна помощь с udev в busybox

Добрый день!
У меня есть рабочая система, соптимизированая и с нужным софтом. Хочу избавиться от лишнего на винте, может даже разместить систему на флешке (cf). Читал, что портежам можно задать собрать пакет(ы) в определенный каталог. Разумно ли это использовать? Если я, например, сделаю emerge -e system && emerge -e world в определенный каталог, скопировать туда /boot, чего там еще понадобится? или я не правильным путем направляюсь, и просто нужно удалить distfiles?

Я при переносе системы обычно поступаю так...

1. Создаю на новом винчестере нужные разделы и монтирую их куда-нибудь во временный каталог.
2. Копирую всё содержимое исходной системы в этот каталог, исключая (просто создаю эти каталоги пустыми):
- /dev
- /proc
- /sys
- /mnt
- /media
- /usr/portage/distfiles
- /usr/portage/packages (если есть)
- /var/tmp/ccache (и, возможно, прочие каталоги в /var/tmp
- возможно, что-то ненужное в /var/log
Распаковываю в /dev содержимое аналогичного каталога в stage3.
Устанавливаю загрузчик в новый /boot, редактирую /etc/fstab.
Вроде бы всё.

Цитата: Распаковываю в /dev

Цитата:
Распаковываю в /dev содержимое аналогичного каталога в stage3.

достаточно только console, null, zero. их можно тупа из /dev/ скопировать. остальное udev создаст :)

P.S.: Linux - это красная таблетка :-) Windows - синяя...

Вполне адекватный вариант.

Вполне адекватный вариант. Еще можно использовать chroot на флэшку - в некоторых ситуациях так будет даже удобнее. Но вообще если указать ROOT=/mnt/flash emerge blabla - то это аналогично чруту будет даже, с тем исключением, что не нужно разворачивать портаж внутри флэхи (что позволит вырезать большое количество ненужных системных пакетов). Одна проблема - /var/db/ тоже будет взят оттуда, поэтому, чтобы сделать emerge -e @system, вам сначала придется скопировать содержимое (и, возможно, почистить) /var/lib/portage на флэшку.

Всем спасибо.

Всем спасибо. Экспериментирую. Еще вопрос:
Раз уж решил ставить ось на флешку, то хочу защитить флеху от лишних перезаписей. Привычка делать се радикально, и поэтому хочу не просто вытолкать /var в рамдиск, а вообще заставить машину работать из рамдиска. Одна проблема - как это сделать. Читал про GNAP и LiveCD - по-моему немного не то. По сути, вижу задачу примерно так: при загрузке, ось с флехи катается на рамдиск, и после этого машина грузится уже с рамдиска. Интересно, средствами GRUB можно такое сделать?

Мне кажется, это бессмыслено,

Мне кажется, это бессмыслено, т.к. обычно при работе идет запись только в /var(немного) и /home все остальное только чтение. Или попробуйте unionfs, я не юзал, но слышал, что с помощью нее можно сделать так: файлы остаются на флэшке, а при попытке записи изменения пишутся на диск в оперативке, а в конце работы можно все сбросить на флэшку.

Спасибо, почитаю про

Спасибо, почитаю про unionfs.
А что касается записи - тут есть еще преимущества - рамдиск, в отличие от флешки, доступен на высокой скорости.
Может есть еще варианты?

Гугл говорит, что нужно

Гугл говорит, что нужно смотреть в сторону initrd.

Насколько я знаю, не совсем

Насколько я знаю, не совсем так. Портежи и прочие зависимости сборки вытяутся по зависимостям. Нужно еще указать SYSROOT=/ чтобы build dependences ставились в основной корень, а то, что нужно в ROOT.

Вобщем, почитал еще, понял,

Вобщем, почитал еще, понял, что нужно все-таки использовать метод LiveCD. То есть squashfs образ системы ro и работа в рамдиске. Нашел кучу статей и блогов по построению своего livecd/usb но нигде нет подробного описания какие конфиги можно покрутить чтобы определить что держать в squashfs, а что в ram. Из этого материала вообще не понятно как система в итоге оказывается в ramdisk.
Подскажите кто знает :)

посмотри в сторону catalyst.

посмотри в сторону catalyst. он собирает LiveCD и где-то было как сделать загрузочную флэшку из LiveCD и syslinux

посмотрите в сторону

посмотрите в сторону sysresccd.org - там довольно-таки подробная инструкция как настроить образ под себя с добавлением необходимых программ.

хоть изначально у них используется xfce, но, думаю, не проблема заменить на то, что нравится

что-то добрый я сегодня ....

Для этого служит initrd. В

Для этого служит initrd. В нем находится ядро, минимальный набор программ - mount, cat, chroot etc., и скрипт, которому передает управление ядро после загрузки. Этот скрипт и делает всю работу - монтирует разделы, копирует все что нужно и передает управление дальше.
В инете есть масса информации по этому вопросу.
У меня была такая задача - грузить с flash диска систему удаленного терминала. В терминале стоит VIA Epia mini-ITX c 128mb RAM, ЖК монитор 17" с тачскрином, usb wifi и компортовый сканнер штрихкода. В качестве flash диска использовал Compact Flash 256Mb через переходник на IDE.

Я использовал такой метод - разбил CF на три раздела:
sda1 - с grub, ядром, initrd и var.tar.gz, home.tar.gz на ext2 (/boot) - 10Mb
sda2 - все содержимое /etc на ext2 - 20Mb
sda3 - раздел, где лежит root squashfs - остальное
На sda3 образ squashfs заливаю при помощи dd.

Принцип работы.
Грузится ядро, передает управление в initrd. Там производится несколько действий:
Монтируется sda3 с root squashfs во временный каталог /mnt.
Создаются tmpfs, в них распаковываются var.tar.gz, home.tar.gz и эти tmpfs монтируются /mnt/var и /mnt/home.
Создается tmpfs, туда копируется содержимое sda2 (/etc) и эта tmpfs монтируется в /mnt/etc.
Создается tmpfs и монтируется в /mnt/tmp.
Дальше перемешаем root (chroot в /mnt && pivot_root) и стартуем реальный init из root squashfs.

Таким образом в RAM находятся только /etc, /home, /tmp и /var, а root squashfs работает прямо с CF в режиме только для чтения.
Почему я не использовал unionfs - захотел использовать только штатные средства, без модификации ядра.
Размер root squashfs с установленными xorg, firefox и rdesktop не превышает 130Mb.
Весь процесс создания initrd можно автоматизировать при помощи скрипта.

Для livecd делается все очень похоже. Необходимы только initrd и root squashfs.

MVG написал(а): Для этого

MVG написал(а):
Для этого служит initrd. В нем находится ядро, минимальный набор программ - mount, cat, chroot etc., и скрипт, которому передает управление ядро после загрузки. Этот скрипт и делает всю работу - монтирует разделы, копирует все что нужно и передает управление дальше.

В инете есть масса информации по этому вопросу.
У меня была такая задача - грузить с flash диска систему удаленного терминала. В терминале стоит VIA Epia mini-ITX c 128mb RAM, ЖК монитор 17" с тачскрином, usb wifi и компортовый сканнер штрихкода. В качестве flash диска использовал Compact Flash 256Mb через переходник на IDE.

Хендбук я уже изучил.

MVG написал(а):
Я использовал такой метод - разбил CF на три раздела:
sda1 - с grub, ядром, initrd и var.tar.gz, home.tar.gz на ext2 (/boot) - 10Mb
sda2 - все содержимое /etc на ext2 - 20Mb
sda3 - раздел, где лежит root squashfs - остальное
На sda3 образ squashfs заливаю при помощи dd.

Принцип работы.
Грузится ядро, передает управление в initrd. Там производится несколько действий:
Монтируется sda3 с root squashfs во временный каталог /mnt.
Создаются tmpfs, в них распаковываются var.tar.gz, home.tar.gz и эти tmpfs монтируются /mnt/var и /mnt/home.
Создается tmpfs, туда копируется содержимое sda2 (/etc) и эта tmpfs монтируется в /mnt/etc.
Создается tmpfs и монтируется в /mnt/tmp.
Дальше перемешаем root (chroot в /mnt && pivot_root) и стартуем реальный init из root squashfs.

Таким образом в RAM находятся только /etc, /home, /tmp и /var, а root squashfs работает прямо с CF в режиме только для чтения.
Почему я не использовал unionfs - захотел использовать только штатные средства, без модификации ядра.

Дада - это мне и надо. Правда, нужна еще возможность командой сохранить изменения, но это легче.

MVG написал(а):
Весь процесс создания initrd можно автоматизировать при помощи скрипта.

А может след где остался от Ваших действий?
Я вот нагуглил: http://www.iakovlev.org/index.html?p=4697&m=1&l1=3 Упомянаются конструкторы initrd, но нету их в портежах.
man mkinitrd не просветил как наваять баш скрипт, кидающий и монтирующий что нужно, и как заставить его исполняться при загрузке initrd.

Я еще не сильно наследил в

Я еще не сильно наследил в сети :)

На самом деле я использую целый набор небольших скриптов. Они помогают мне развернуть базовую систему из stage3, собрать все необходимое, создать initrd, создать root squashfs, и сделать резервную копию системы.

Cкрипт, который создает initrd, называется очень оригинально - build_initrd.sh ;)
В качестве источника, он использует каталог, где развернута собранная система.
Обратите внимание на переменную LIVEDIR. Если LIVEDIR="/mnt/test", то ваша система, для которой вы хотите получить initrd, должна лежать в /mnt/test/source. Это связано с тем, что я выношу некоторые каталоги - /usr/portage, /usr/src ... вне source, чтобы они не попали затем в root squashfs. Так же, у вас должен быть создан каталог /mnt/test/boot. В нем будет лежать результат работы скрипта - готовый initrd.

Собственно сам скрипт:

#!/bin/sh

# Каталог для сборки системы
LIVEDIR="/mnt/test"

# Временный каталог для сборки initrd
INITRD_DIR="/tmp/initrd_temp"

# Размер initrd в Mb
INITRD_SIZE="4"

cd ${LIVEDIR}/boot
dd if=/dev/zero of=initrd bs=1M count=${INITRD_SIZE}
mke2fs -q -F -m0 initrd
mkdir ${INITRD_DIR}
mount -o loop initrd ${INITRD_DIR}
chroot ${LIVEDIR}/source <<- EOF
mkdir /mnt/initrd/
cd /mnt/initrd/
mkdir bin etc dev lib proc temp mnt
touch linuxrc
chmod +x linuxrc
touch etc/mtab
touch etc/fstab
mknod dev/console c 5 1
mknod dev/null c 1 3
mknod dev/sda b 8 0
mknod dev/sda1 b 8 1
mknod dev/sda2 b 8 2
mknod dev/sda3 b 8 3
mknod dev/tty c 5 0
mknod dev/tty0 c 4 0
mknod dev/loop0 b 7 0
cp /bin/cat bin
cp /bin/cp bin
cp /bin/chroot bin
cp /bin/gzip bin
cp /bin/mount bin
cp /bin/mkdir bin
cp /bin/ps bin
cp /bin/sh bin
cp /bin/tar bin
cp /bin/umount bin
cp /sbin/pivot_root bin
cp /lib/ld-linux.* lib
find bin -type f | xargs ldd | grep '/lib/' | awk '{print \$3}' | sort -n | uniq | xargs -i, cp , lib/.
EOF
cp -a ${LIVEDIR}/source/mnt/initrd/* ${INITRD_DIR}
rm -Rf ${LIVEDIR}/source/mnt/initrd
rmdir ${INITRD_DIR}/lost+found

# Создаем linuxrc прямо из скрипта
cat >> ${INITRD_DIR}/linuxrc << EOF
#!/bin/sh

BOOT=/dev/sda1
ETC=/dev/sda2
ROOT=/dev/sda3

# Нам нужен доступ к исполняемым файлам в initrd
export PATH=/bin:/sbin

# Получить командную строку ядра из загрузчика
mount -t proc none /proc
CMDLINE=\`cat /proc/cmdline\`
umount /proc

# монтировать squashed / файловую систему
mount -t squashfs \$ROOT /mnt
echo "[ ok ]   / successfully mounted !"

# распаковать в tmpfs и примонтировать /mnt/var
mount -r \$BOOT /temp
mount -t tmpfs -o size=4M none /mnt/var
cd /mnt/var
tar xzpf /temp/var.tar.gz
umount /temp
echo "[ ok ]   /var successfully extracted !"

# распаковать в tmpfs и примонтировать /mnt/home
mount -r \$BOOT /temp
mount -t tmpfs -o size=10M none /mnt/home
cd /mnt/home
tar xzpf /temp/home.tar.gz
umount /temp
echo "[ ok ]   /home  successfully extracted !"

# скопировать в tmpfs и примонтировать /mnt/etc
mount \$ETC /temp
mount -t tmpfs -o size=4M none /mnt/etc
cp -a /temp/* /mnt/etc
umount /temp
echo "[ ok ]   /etc successfully copied !"

# монтировать tmpfs в /mnt/temp
mount -t tmpfs -o size=4M none  /mnt/tmp
echo "[ ok ]   /tmp successfully mounted !"

# Переместить root и стартовать реальный init
cd /mnt
pivot_root . mnt/temp
exec chroot . sh -c 'umount /mnt/temp; blockdev --flushbufs /dev/ram0; \
  exec /sbin/init \${CMDLINE}' <dev/console >dev/console 2>&1
EOF

umount ${INITRD_DIR}
rm -R ${INITRD_DIR}
cd ${LIVEDIR}/boot/
gzip initrd

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

Спасибо, вопросы будут :)

Спасибо, вопросы будут :)

Еще раз большое спасибо MVG,

Еще раз большое спасибо MVG, который терпеливо отвечал на шквал вопросов в IM.
Итак, возник еще один вопрос - задача, к кторой пока не найду как подступиться.
Есть в initrd программа mount , которая вполне себе работает вот так:
mount /dev/sda1 /mnt
А когда я хочу, чтобы в initrd монтировался роаздел по label:
mount -L label /mnt
то пишет partition not found и kernel panic как следствие.
в нормально занруженной системе команда исполняется и монтирует собственно нужный раздел куда нужно.
Кто разбирается, подскажите пожалуйста куда копать:
1. либо надо найти и добавить в initrd еще либу, чтобы использовать опцию -L, то подскажите как найти эту либу,
2. Может быть на этой стадии загрузки ядра, ядро не видит меток (label)?

1) есть подозрения, что моунт

1) есть подозрения, что моунт из бузибикса не умеет лабелы - заскриптуйся с blkid (e2fsprogs)
2) посмотри, что там насоздавал mdev ( в стандартном инирд - параметр debug) - может есть смысл перейти на удев ( он давно должен собиратся с uClibc)

Compute:
Bosch M2.8.1 -> custom Bosch M2.8.3 clone from Russia.
Speed about 260 km,Ram 2 pers.,HDD - 70 kg,210 FLOPS ;)

бизибокс я не использовал,

бизибокс я не использовал, руками создавал initrd, скопировал нужные проги из /bin, libы из /lib, init скрипт тоже написан вручную Только что попробовал монтирование по uuid - тоже не хочет

trscod написал(а): бизибокс я

trscod написал(а):
бизибокс я не использовал, руками создавал initrd, скопировал нужные проги из /bin, libы из /lib, init скрипт тоже написан вручную Только что попробовал монтирование по uuid - тоже не хочет

т.е вручную ?? ты хоть lddtree.sh чекал ?
blkid в инитрд что кажет ?

Compute:
Bosch M2.8.1 -> custom Bosch M2.8.3 clone from Russia.
Speed about 260 km,Ram 2 pers.,HDD - 70 kg,210 FLOPS ;)

slepnoga написал(а): может

slepnoga написал(а):
может есть смысл перейти на удев ( он давно должен собиратся с uClibc)

Udev - он запускается гораздо позже и не решает мои задачи, к сожалению

trscod написал(а): slepnoga

trscod написал(а):
slepnoga написал(а):
может есть смысл перейти на удев ( он давно должен собиратся с uClibc)

Udev - он запускается гораздо позже и не решает мои задачи, к сожалению

удев/мдеев, балин, тот который в инитрд, а не тот, который в системе
покажи листинг файлов и директорий в твоем инирд

Compute:
Bosch M2.8.1 -> custom Bosch M2.8.3 clone from Russia.
Speed about 260 km,Ram 2 pers.,HDD - 70 kg,210 FLOPS ;)

ls bin dev etc lib

ls
bin dev etc lib linuxrc loopfs mnt proc sda1 squash sysroot temp
А как туда udev засунуть?

А вообще, есть хорошая дока

А вообще, есть хорошая дока по initramfs:
http://en.gentoo-wiki.com/wiki/Initramfs
Как-то я ее сразу не нашел.
В принципе, все получилось, но наполовину.
Использую busybox и mdev для определения разделов (флешки). Определяются разделы и метки и монтируются.
Если воткнуть вторую флешку, то первая, бывшая в одиночетсве /dev/sda, становится /dev/sdb и в упор не видится ядром. Вернее ядром то видится до запуска init скрипта initramfs. Создаю ноды для разделов в /dev , но все равно команда mount говорит что такого раздела не существует.
А задача то в этом и заключается, чтобы сколько флешек там небыло воткнуто - грузилось всегда с нужной.
Короче, нагуглил пока что есть в busybox udev. А как его использовать?

trscod написал(а): Создаю

trscod написал(а):
Создаю ноды для разделов в /dev , но все равно команда mount говорит что такого раздела не существует.

Udev не понадобился. man mknod !

Мы сами создаем себе

Мы сами создаем себе трудности, и мы сами их героически преодолеваем - мы Армянские Комсомольцы.

монтируй по UUID - темя избита и перетерта сто тыщь раз

Compute:
Bosch M2.8.1 -> custom Bosch M2.8.3 clone from Russia.
Speed about 260 km,Ram 2 pers.,HDD - 70 kg,210 FLOPS ;)

Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Сохранить установки".