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" и обеспечить нормальную загрузку.

[править] Смотри также

Личные инструменты
На других языках