HOWTO Gentoo на USB
Материал из Gentoo Linux Wiki
- Вернуться в раздел руководства
Содержание |
[править] Обзор
Однажды у меня появилась идея создания платформы для обработки изображений и, для большей оригинальности, назвал её: ipp (Image Processing Platform). От ipp требовалась поддержка USB и gphoto для подключения цифровых камер, поддержка сети для связи с внешним миром, но не более того. Мне показалось удобным создать эту систему на базе USB-flash. Для достижения поставленной цели нужно было создать полноценную файловую систему на обычном диске, а затем переместить её на flash (делается это потому, что объёмов flash-накопителя может не хватить при компиляции нужного нам софта). Помочь нам в решении этой задачи предстоит такому инструменту, как Catalyst.
Catalyst позволяет gentoo создавать загрузочные CD. С помощью него можно также создать вообще любую загрузочную файловую систему (FS). Для нашей затеи это как раз и нужно: загрузочная FS. Поскольку объём нашей USB-flash не безграничен, то ограничим размер нашей FS 512 Мб (в моём случае ёмкость usb-flash и есть 512Мб).
[править] Что я делал
Давайте начнём с создания структуры каталогов, в которой будут храниться файлы нашей системы. Я выделил три главных компонента ipp:
~/ipp_files +-/rootfs +-/kernel +-/configs
[править] Создание загрузочного USB-носителя
Это было проделано мной в самом начале, поскольку требовалось эксперементировать с различными версиями ядра, чтобы быть увереным, что уже есть работоспособное ядро перед созданием корневой файловой системы с помощью catalyst. Можете пропустить этот шаг, если у вас уже есть работоспособное ядро.
Когда вы подключаете USB-носитель, Linux распознает его как SCSI hdd. Новые ядра распознают его, как блочное устройство usb /dev/uba. Однако, в этом руководстве мы будем оперировать с usb-flash через /dev/sda. Давайте поступим с USB-flash, как с обычным жестким диском, и создадим на нём два раздела: загрузочный и корневой. Для начала очистим таблицу разделов:
| Предупреждение: Если у вас в системе есть другие устройства SCSI (например, SATA-винчестер), убедитесь, что /dev/sda соответствует именно USB-flash (в этом случае сделайте соответствующие изменения!). Если вы этого не сделаете, то потеряете содержимое всего вашего винчестера! Самое время сказать: ***делайте бэкапы*** |
dd if=/dev/zero of=/dev/sda bs=512 count=1
Теперь создадим разделы при помощи #fdisk /dev/sda:
| Code: fdisk commands |
:n # создаём новый раздел (для /boot) :p # primary :1 # первый : # нажмите enter для подтверждения начала раздела по умолчанию :+25M # 25 Мб - размер раздела :n # еще раздел (для /) :p # primary :2 # второй : # нажмите enter для подтверждения начала раздела по умолчанию : # нажмите enter для подтверждения конца раздела по умолчанию (= весь оставшийся объем) :w # запись новой таблицы разделов на USB и выход |
Вот таким вот таинственным образом мы создали /dev/sda1 как раздел на 25MB и /dev/sda2 на всё оставшееся место.
Теперь, когда наши разделы созданы, перезагрузим таблицу и создадим файловые системы:
rmmod usb-storage modprobe usb-storage mke2fs /dev/sda1 mkreiserfs /dev/sda2
Мы так и не создали до сих пор корневую FS, так что для начала возьмём её из архива stage3. Т.е. используем stage3 в качестве заготвки для создания собственной корневой FS с помощью catalyst:
mount /dev/sda2 /mnt/ipp mkdir /mnt/ipp/boot mount /dev/sda1 /mnt/ipp/boot cd /mnt/ipp tar xvjpf stage3-xxx.tar.bz2
Но архив stage3 не содержит то, что нужно grub; к счастью в этом создаваемая нами платформа и основная система совпадают. Так что просто скопируем каталог boot вашей системы с помощью cp -pr /boot/* /mnt/ipp/boot
Теперь, с помощью GRUB, создадим MBR на usb-flash:
| Code: GRUB Commands |
>root (hd2,0) >setup (hd2) |
В моей системе (не в той, которую мы создаем, а в той, которую используем для создания - очень запутано, но смысл, думаю, понятен) usb-носитель представлен как hd2 в GRUB. Убедитесь, что вы указали правильный hd#, и не повредили ваш текущий MBR.
Теперь настроим GRUB menu.lst:
| Файл: /mnt/ipp/boot/grub/menu.lst |
# Boot automatically after 5 secs. timeout 5 # By default, boot the first entry. default 0 # Fallback to the second entry. fallback 1 splashimage=(hd0,0)/grub/splash.xpm.gz title=Test: IPP: 2.4.26 root (hd0,0) kernel /test.ipp.kernel-2.4.26 root=/dev/sda2 vga=791 |
Я указал в GRUB несуществующее ядро - поскольку у нас всё равно его пока нет. Так что не спешите с загрузкой.
[править] Создание работоспособного ядра
Надеюсь, что вы понимаете как работает ядро или у вас уже есть рабочее ядро. Сделайте копию дерева исходных кодов на вашей машине:
mkdir ~/ipp_files/kernel/linux-2.4.26 cd ~/ipp_files/kernel/linux-2.4.26 rsync -aH /usr/src/linux/ .
Затем измените по своему усмотрению файл .config или используйте make menuconfig. Пара советов по настройке. Убедитесь, что у вас SCSI disk support,USB Host Controllers и USB Storage скомпилированы внутри ядра, а не в качестве модулей, иначе, вам придёться повозиться с initrd. Если скомпилируете в качестве модулей и будете загружать их с помощью initrd, вы получите следующее сообщение об ошибке VFS: cannot open root device "801" or unknown-block(8,1). Когда всё настроите, перед перекомпиляцией не забудьте:
cp .config ../ make mrproper cp ../.config . make oldconfig make dep && make bzImage modules
Обратите внимание на отсутствие modules_install, поскольку мы хотим только собрать дерево, а не установить его.
Теперь всё готово для переброса на наш USB-flash. Не факт, что ядро заработает сразу, так что, возможно, вам придётся несколько раз повторять указанные далее действия.
cd ~/ipp_files/kernel/linux-2.4.26 cp .config /mnt/ipp/boot/test.ipp.config-2.4.26 cp System.map /mnt/ipp/boot/test.ipp.System.map-2.4.26 cp arch/i386/boot/bzImage /mnt/ipp/boot/test.ipp.kernel-2.4.26 umount /mnt/ipp/boot umount /mnt/ipp sync
Отсоедините usb, подключите его к испытательному компьютеру и включите его. Если всё получилось, то переходите к следующему разделу; иначе - вернитесь к началу.
[править] О ядрах ветки 2.6
Если вы используете ядро ветки 2.6, то нужно настроить initrd так, чтобы ядро видело ваш usb-flash во время того, как монитируется корневая FS. Но заставить его ожидать перед монтированием отчетов всех модулей USB+usb-storage+sd_mod не является решением. Так, я сделал оба SCSI диска(sd_mod.o) и USB-Storage(usb-storage.o) в качестве модулей ('<M>'), не встраивая их в ядро ('<*>'). Обратите внимание: вы не обязаны делать их модулями, т.к. если вы встроите всё в ядро, то система будет запускаться с вообще чистым intird. Просто я хочу показать как осуществить загрузку, если поддержка этих устройств содержится в модуле:
Я пересобрал ядро и его модули, а затем создал свой initrd:
mkinitrd --omit-raid-modules --omit-lvm-modules -f --fstab=/etc/fstab --nopivot \ --preload=usb-storage --preload=sd_mod /boot/<whatever-initrd-filename> <full-kernel-version>
убедитесь, что вы включили полную версию ядра последним аргументом, т.к. именно благодаря этому mkinitrd узнает, откуда брать модули.
Затем я добавил в настройках GRUB строчку, выбирающую ядро 2.6, сразу после строки "kernel..." :
| Файл: /boot/grub/menu.lst |
... initrd /<whatever-initrd-filename> ... |
Вот и всё.
Однако, если у вас появится следующая ошибка:
VFS: Cannot open root device "sda3" or unknown-block(0,0)
Попробуйте использовать вместо /dev нотации, числовую нотацию устройств. Это помогает в большинстве случаев. Так что замените:
kernel /test.ipp.kernel-2.4.26 root=/dev/sda2 vga=791
на:
kernel /test.ipp.kernel-2.4.26 root=0x802 vga=791
[править] Заметка об ядрах 2.6.15+
Тут всё еще проще: существует загрузочная опция ядра rootdelay=n (замените n требуемым числовым значением), которая решает проблему загрузки модулей. Значения больше 10 вполне хватит для того, чтобы у ядра хватило времени на распознавание любых USB дисков. Может быть это работает и в предыдущих версиях ядра, не пробовал.
[править] Создание корневой FS
Мы создадим stage4 (stage3+пакеты) корневую файловую систему для использования на USB-носителе. В этом нам поможет catalyst. Стоит обратить внимание на факт, упоминавшийся в этом руководстве Catalyst HOWTO.
Примечание: Использование CFLAGS="-Os" позволит уменьшить размер двоичных файлов, по сравнению с CFLAGS="-O2". Запомним это.
Для начала env USE=doc emerge catalyst, важно добавить USE=doc, поскольку документация содержит весьма полезные примеры. Затем обратим внимание на /etc/catalyst/catalyst.conf и /root/catalyst-env.sh. В конце концов, у меня получилось следующее:
| Файл: /etc/catalyst/catalyst.conf |
distdir="/usr/portage/distfiles" options="ccache pkgcache distcc" sharedir="/usr/lib/catalyst" envscript="/root/catalyst-env.sh" |
| Файл: /root/catalyst-env.sh |
export MAKEOPTS="-j6" |
Я установил такое значение MAKEOPTS, поскольку у меня есть 4 дополнительных машины с distcc для компиляции. Если взять n за количество машин с запущенным distcc, то следуйте формуле -j`(n+1)*2`.
Не будем усложнять себе жизнь: возьмём stage3 и сделаем снимок (snapshot); затем используем оба для создания livecd.
Для начала сделаем снимок текущего дерева:
| Файл: /root/catalyst/ipp/snapshot.spec |
target: snapshot version_stamp: 20040714 |
затем catalyst -f snapshot.spec создадим: /var/tmp/catalyst/snapshots/portage-20040714.tar.bz2
Заметка: метка версии (в нашем случае 20040714) ни на что не влияет, так что можете использовать произвольное имя.
Теперь, когда мы создали portage-20040714.tar.bz2 и получили stage3-athlon-xp-2004.1.tar.bz2...
cp stage3-athlon-xp-2004.1.tar.bz2 /var/tmp/catalyst/builds/
Теперь мы должны создать specfile:
| Файл: /root/specfiles/ipp/liveusb-stage1.spec |
subarch: athlon-xp
version_stamp: 20040714
target: livecd-stage1
rel_type: default
profile: default-x86-2004.0
snapshot: 20040714
source_subpath: stage3-athlon-xp-2004.1
distcc_hosts: 1 2 3 4
livecd/use:
-X
-gtk
-gtk2
-kde
-arts
-alsa
-avi
-cdr
-cups
-esd
gphoto2
acpi
-dvd
-dvdr
-emacs
-ethereal
f77
-fbcon
-ginac
-odbc
-plotutils
-ppds
-samba
-sse
usb
-wmf
-xml
-xosd
-gnome
-opengl
-oss
-sdl
-spell
-truetype
livecd/packages:
baselayout
module-init-tools
hotplug
syslog-ng
pciutils
strace
nfs-utils
usbutils
e2fsprogs
reiserfsprogs
nano
less
openssh
dhcpcd
mingetty
screen
iputils
tcptraceroute
ethtool
distcc
libusb
grub
gentoolkit
|
За более подробной информацией обращайтесь к HOWTO build a LiveCD.
Примечание: значение profile: default-x86-2004.0 должно соответствовать существующему профилю в дереве портежей в /usr/portage/profile - если же вы укажете несуществующий профиль, то получите следующую ошибку: ARCH is not set... Are you missing the /etc/make.profile symlink?
Затем заставим catalyst делать чёрную работу: catalyst -f liveusb-stage1.spec
После чего, если всё прошло успешно, catalyst поместит несжатую корневую файловую систему в /var/tmp/catalyst/tmp/default/livecd-stage1-athlon-xp-20040714/. Мы должны перенести её в свой рабочий каталог перед тем, как выполнить следующую команду:
mkdir ~/ipp_files/rootfs/stage1-livecd cd ~/ipp_files/rootfs/stage1-livecd rsync -aH --progress /var/tmp/catalyst/tmp/default/livecd-stage1-athlon-xp-20040714/ .
[править] Создание файлов настроек
Можно просто скинуть их на usb-flash и затем запустить систему, но я полагаю, что это не лучшее решение, поскольку может понадобиться заново пересоздать корневую FS. Так что следуя правилу - мухи отдельно, котлеты отдельно - поместим наши файлы настроек в отдельную директорию, чтобы впоследствии просто скопировать во вновь созданную корневую FS.
Так что выполним:
cd ~/ipp_files/configs/etc rsync -aH /var/tmp/catalyst/tmp/default/livecd-stage1-athlon-xp-200407/etc/ .
Затем следуя gentoo handbook, chapter 8 убеждаемся в правильности настроек. Не будем заострять внимание на каждом файле настроек, поскольку там и так всё понятно.
| Файл: /etc/fstab |
/dev/sda1 /boot ext2 noauto,noatime 1 1 /dev/sda2 / reiserfs noatime 0 0 none /proc proc defaults 0 0 none /dev/shm tmpfs defaults 0 0 |
Также я скопировал с основной системы следующие файлы: /etc/distcc/hosts, /etc/conf.d/distcc, /etc/hosts, /etc/dnsdomainname, /etc/localtime, /etc/nanorc, и /etc/syslog-ng/syslog-ng.conf.
[править] А теперь всё вместе
Если вы стремитесь сократить число циклов записи на usb-носитель, то команда rsync и несжатая файловая система, предоставленная catalyst, помогут нам в этом.
Теперь соберём всё вместе, включая livecd-stage1 FS, потом ядро, затем все файлы настроек в /mnt/ipp.
cd /mnt/ipp rsync -aH --progress --exclude 'boot/*' --exclude 'usr/portage/*' --exclude 'usr/share/doc/*' \ --exclude 'usr/share/man/*' --exclude 'usr/share/info/*' ~/ipp_files/rootfs/stage1-livecd/ .
mount /dev/sda1 boot/ cd boot/ rsync -aH --progress --exclude 'menu.lst' ~/ipp_files/rootfs/stage1-livecd/boot/ .
cd ~/ipp_files/kernel/linux-2.4.26/ env INSTALL_MOD_PATH="/mnt/ipp/" make modules_install cp .config /mnt/ipp/boot/test.ipp.config-2.4.26 cp System.map /mnt/ipp/boot/test.ipp.System.map-2.4.26 cp arch/i386/boot/bzImage /mnt/ipp/boot/test.ipp.kernel-2.4.26
cd /mnt/ipp/etc/ rsync -aH --progress ~/ipp_files/configs/etc/ .
cd umount /mnt/ipp/boot && umount /mnt/ipp sync
Вот и вся любовь! Отключаем usb-flash. Подключаем к испытательному компьютеру. Включаем его. Конфигурацию такие вещей как ssh, nfs и т.д. оставляю на вашу совесть.
Если вы столкнулись с таким сообщением при загрузке с usb-flash: "Could not find CD to boot, something else needed!", то надо выставить задержку в сценарии /init внутри syslinux/gentoo.igz; т.е.:
-> Монтируем usb-flash:
mount /dev/sda1 /mnt2
-> Распаковываем initrd:
cd /tmp; mkdir gentoo.initrd; cd gentoo.initrd
gunzip </mnt2/isolinux/gentoo.igz >../gentoo.i
bvi ../gentoo.i
-> Заменяем все вхождения 'TRAILER!!!' на 'notTRAILER',
*EXCEPT* the LAST one. Use common sense to verify if there isn't any ocurrences
that aren't cpio headers (DON'T change these if there are any).
-> This is needed because the .cpio file that was compressed to produce
the original isolinux/gentoo.igz file is actually a concatenation of
*many* (I counted 10) different CPIO files; the kernel (and presumably
some other version of cpio) can handle this correctly, but mine (debian
v. 2.6-5) can't, and silently stops expanding the file on the first
'TRAILER!!!' header.
cpio -idv < ../gentoo.i
-> разворачиваем целое дерево initrd
-> Изменяем сценарий init:
-> Перед этими строками:
# Mount sysfs
mount_sysfs
# Start udev/devfs
start_dev_mgr
-> Добавляем эти:
#2005/09/25 Durval Menezes
#good delay after loading modules, so the system can stabilize
#(if we don't delay, the start_dev_mgr a few lines below won't
#find our pendrive's device and the boot will fail
echo -n "Waiting for loaded drivers to stabilize"
COUNTER=0
while [ $COUNTER -lt 5 ]; do
sleep 1
echo -n '.'
let COUNTER=$COUNTER+1
done
echo
-> Пересоздаём файл initrd с внесёнными изменениями:
find . | cpio --quiet --dereference -o -H newc | gzip -9 >/mnt2/isolinux/gentoo.igz
-> Отключаем usb:
umount /mnt2
Это изменение должно исключить появление ошибки "could not find CD to boot" и обеспечить нормальную загрузку.
[править] Смотри также
- http://forums.gentoo.org/viewtopic.php?t=57754 - создание live-USB fs.
- http://forums.gentoo.org/viewtopic.php?p=970867 - более подробно об использовании Catalyst для создания live fs.
- http://forums.gentoo.org/viewtopic.php?t=83983 - создание gentoo дистрибутива на CF диске.
- http://www.simonf.com/usb/ - способ подключения USB диска в качестве основного HDD для linux.
- http://forums.gentoo.org/viewtopic.php?t=193273 - неплохой пост об initrd
- http://forums.gentoo.org/viewtopic.php?t=119669 - более подробно об Catalyst
- HOWTO build a LiveCD - Руководство по Catalyst'
- HOWTO Gentoo LiveCD and LiveUSB - посвящено той же тематике, что и это руководство, но вместо catalyst используется livecd-ng.
- HOWTO Small Footprint Gentoo on USB without catalyst - следуя этим инструкциям получите схожую систему, но без использования catalyst и с возможностью сборки на лету.
