Установка Calculate Linux с usb flash используя grub2

Дано: обычная флешка на 2Гб, компьютер с линуксом, iso-образ CL.
Цель: сделать live-flash CL.

Чуть-чуть теории или как livecd gentoo определеяет с какого диска продолжать загрузку.
Делают это скрипты initrd. Они по очереди монтируют /dev/sd[a-b][1-9] и /dev/sr[0-9] (возможно с диапазонами я ошибся, но сути это не меняет) и проверяют наличее в корне примонтированного диска файла livecd.
Как только файл обнаружен - монтируется файл заданный в переменной окружения LOOP и chroot’ится в новый корень, передавая управление новому init’у. Переменная окружения LOOP не задается где-то внутри скриптов, как может показаться на первый взгляд, а передается как опция ядра. И ядро уже в свою очередь передает эту опцию init’у, который и выставляет переменную окружения.

Практика
У меня флешка в системе определилась как /dev/sdb. На первой партиции vfat раздел. ФС не принципиальна, главное чтобы grub ее знал.
Монтируем флешку:

# mount -t vfat /dev/sdb1 /mnt/flash

Устаналиваем загрузчик:

# grub2-install --no-floppy --root-directory=/mnt/flash

По идее данная операция не должна уничтожить существующую информацию на флеш-диске. Но бекап лучше все-таки сделать.

Граб установлен, надо где-то взять ядро и initrd
Монтируем iso-образ CL:

# mount -o loop -t iso9660 cld-20101230.iso /mnt/cdrom
 # cp /mnt/cdrom/boot/vmlinuz /mnt/flash/boot/vmlinuz
 # cp /mnt/cdrom/boot/initrd /mnt/flash/boot/initrd

Заодно скопируем файл livecd и тот самый образ livecd.squashfs

# cp /mnt/cdrom/livecd* /mnt/flash/

И последнее - настройка grub2. Необходимо создать /mnt/flash/boot/grub/grub.cfg со следующим содержимым (никаких \ быть не должно, как и переносов строк после них. Здесь они ради удобства чтения):

menuentry "Calculate linux desktop 11.0 beta 2" {
    linux /boot/vmlinuz init=/linuxrc looptype=squashfs unionfs cdroot_type=vfat doload=vfat,nls_cp866,nls_utf8,squashfs,isofs,unionfs loop=livecd.squashfs 
        nodevfs cdroot video=uvesafb:ywrap,1280x1024-32@60,mtrr:3,splash=silent,theme:tty1 CONSOLE=/dev/tty1 udev quiet noresume doscsi 
        calculate=ru_RU,ru_RU,Asia/Novosibirsk,auto
    initrd /boot/initrd
}

Опции ядра можно подглядеть в /mnt/cdrom/isolinux/

В принципе все.
Перезагрузка, проверка загрузки с флешки.

_Если ОС загрузилась с флешки, то именно флешка будет /dev/sda!
Все остальные диски будут начинаться с /dev/sdb.
Чуть-чуть внимания при установке._

Все выше описанное должно быть справедливо и для lilo и для grub (не 2)

Немного эзотерики или зачем все это затеяно
Дело в команде граба loopback
Если в конфиге граба указать примерно следующее (я намеренно опускаю опции ядра, для более легко чтения)

menuentry "Calculate linux desktop 11.0 beta 2" {
    loopback loop /boot/cld-20101230.iso
    linux (loop)/boot/vmlinuz
    initrd (loop)/boot/initrd
}

то ядро и initrd будет браться из образа диска. Это достаточно простой способ создания мультизагрузочной флешки.
Накидываем .iso образов, прописываем их в grub.cfg (а можно еще и при загрузке редактировать записи).
Но тут мы и столкнемся с особенностями загрузки livecd gentoo описанными выше. В некоторых других дистрибутивах (к примеру убунту) есть возможность указать опцию ядру, которая скажет initrd монтировать определенный iso-образ, а не искать его по всем возможным устройствам.
Решение, кстати, уже существует и даже принято в upstream http://bugs.gentoo.org/show_bug.cgi?id=294268
Для интереса я решил применить его не к скриптам genkernel, а к скриптам внутри initrd.

# cd /root
 # mkdir initrd
 # cd initrd
 # zcat /mnt/cdrom/boot/initrd | cpio -id

Далее патчим linuxrc и etc/initrd.scripts (патч по ссылке на баг-трекере) и собираем обратно:

# find . | cpio -H newc -o | gzip > /mnt/flash/boot/inird.new

Теперь появилась возможность сделать следующий конфиг grub’а:

menuentry "Calculate linux desktop 11.0 beta 2" {
    loopback loop /boot/cld-20101230.iso
    linux (loop)/boot/vmlinuz isoboot=/boot/cld-20101230.iso init=/linuxrc looptype=squashfs unionfs cdroot_type=vfat doload=vfat,nls_cp866,nls_utf8,squashfs,isofs,unionfs 
       loop=livecd.squashfs nodevfs cdroot video=uvesafb:ywrap,1280x1024-32@60,mtrr:3,splash=silent,theme:tty1 CONSOLE=/dev/tty1 udev quiet noresume doscsi 
       calculate=ru_RU,ru_RU,Asia/Novosibirsk,auto
    initrd /boot/initrd.new
}

Проверено, работает.

В багтрекере генту указано, что патч принят в апстрим, ждем в скором времени его в CL.

ob server wrote:

можно один вопрос? не пойму, как используется патч в этой команде
# find . | cpio -H newc | gzip > /mnt/flash/boot/inird.new

никак, это как собирать initrd обратно после накладывания патча

у меня выдает ошибку
cpio: You must specify one of -oipt options.
Try `cpio --help’ or `cpio --usage’ for more information.

упс, ошибочка вкралась, спасибо, правильная команда

find . | cpio -H newc -o | gzip > /mnt/flash/boot/inird.new

поправил в тексте

доброе время суток! спасибо за статью, но попробовал пропатчить свой инитрд, получаю ошибку

artems@artems-desktop:~/initrd$ patch -p2 --dry-run <~/grub2-genkernel.patch
patching file initrd.scripts
Hunk #1 FAILED at 72.
Hunk #2 FAILED at 104.
Hunk #3 FAILED at 115.
3 out of 3 hunks FAILED -- saving rejects to file initrd.scripts.rej
patching file linuxrc
Hunk #1 succeeded at 84 (offset 4 lines).

artems@artems-desktop:~/initrd$ patch -p1 --dry-run <~/grub2-genkernel.patch
patching file defaults/initrd.scripts
Hunk #1 FAILED at 72.
Hunk #2 FAILED at 104.
Hunk #3 FAILED at 115.
3 out of 3 hunks FAILED -- saving rejects to file defaults/initrd.scripts.rej
patching file defaults/linuxrc
Hunk #1 FAILED at 80.
1 out of 1 hunk FAILED -- saving rejects to file defaults/linuxrc.rej

не подскажете в чем дело?
initrd с лив-двд gentoo 11.0

даже не знаю, я мало работал с патчами.

я думаю что можно и руками прописать, там различай на 10 строк.