Однажды на работе передо мной поставили задачу: заставить работать RAID-контроллер Intel RS2WC040 во FreeBSD 8.2 архитектуры amd64 и сделать установочную флешку со встроенной поддержкой этого контроллера. Сейчас я подумал, что не стоит пропадать добру, и решил выложить рецепт, который у меня получился.
Подробнее о контроллере: Intel RAID Controller RS2WC040 (RTL) PCI-E x8, SAS / SATA-IIRAID0 / 1 / 5 / 10 / 50, 4-Channel
На самом деле контроллер этой модели может быть выполнен с использованием разных микросхем. Нас интересует контроллер с Vendor ID 0x1000 и Device ID 0x0073, который не поддерживается FreeBSD 8.2 и 9.0 из коробки. Точно установить, какой именно набор микросхем используется, можно с помощью команды pciconf. К сожалению, сейчас я не помню, какие дополнительные параметры нужно ей указать, а FreeBSD нет под рукой.
Для сборки ядра и подготовки установочной флешки нам понадобится уже установленная FreeBSD. Скачем с официального сайта образ загрузочной флешки FreeBSD-8.2-RELEASE-amd64-memstick.img, запишем образ на флешку. Скачаем из темы Installing FreeBSD 9 on the IBM System x3550 M3 исходники драйвера. Если заглянуть вовнутрь исходников драйвера, то там можно найти таблицу идентификаторов поддерживаемого оборудования, среди которых есть и интересующее нас.
Загружаемся в установленную FreeBSD, записываем скачанный образ установочной флешки и монтируем её:
# dd if=FreeBSD-8.2-RELEASE-amd64-memstick.img of=/dev/da0 # mount /dev/da0 /mnt/install-flash
Если нет свободной флешки, можно смонтировать файл образа с помощью mdconfig:
# mdconfig -a -t vnode -f FreeBSD-8.2-RELEASE-amd64-memstick.img # mount /dev/md0a /mnt/install-flash
Распаковываем исходники системы:
# cd /mnt/install-flash/8.2-RELEASE/src # ./install.sh all
Переходим в каталог с драйверами устройств и заменяем исходники имеющегося драйвера mfi на исходники скачанного драйвера mfi:
# cd /usr/src/sys/dev/mfi # rm * # cp /root/mfi/* .
Редактируем файл /usr/src/sys/conf/files, после строчки
dev/mfi/mfi_cam.c optional mfi
добавляем строчку
dev/mfi/mfi_syspd.c optional mfi
Создаём свой файл конфигурации ядра. Переходим в каталог /usr/src/sys/amd64/conf и копируем файл GENERIC под именем RAID:
# cd /usr/src/sys/amd64/conf # cp GENERIC RAID
Открываем файл RAID и комментируем в нём две строчки, добавив перед ними знак решётки:
device cbb #cardbus (yenta) bridge
и
makeoptions DEBUG=-g
Вторая опция отменяет создание отладочной информации, которая занимает много места и нас не интересует.
Теперь переходим в каталог /usr/src, собираем и инсталлируем ядро:
# cd /usr/src # make buildkernel KERNCONF=RAID # make installkernel KERNCONF=RAID
Ядро собрано и установлено. Вернём старое ядро, а новое переместим на установочную флешку:
# cd /boot/ # mv kernel /mnt/install-flash/boot/ # mv kernel.old kernel
Новое ядро скопируем временно в каталог /root, где будем готовить его для внедрения в инсталлятор:
# cp -R /mnt/install-flash/boot/kernel /root/kernel # cd /root # mv kernel GENERIC
С этого момента инсталлятор на флешке уже может загружаться и видеть диски в RAID-контроллере. Можно даже поставить на диски RAID-контроллера систему, но она не сможет загрузиться, поскольку установленное ядро не содержит необходимый драйвер.
Запакуем подготовленное ядро, разрежем на части и удалим исходный тарболл:
# tar -czvf generic.tgz GENERIC # split -b 1425408 generic.tgz generic. # rm generic.tgz
Создадим файл generic.mtree:
# mtree -c -p GENERIC -k gname,mode,nlink,size,link,uname,md5digest > generic.mtree
Теперь можно удалить ядро из каталога /root:
# rm -R /root/GENERIC
Создадим файл generic.inf:
# /usr/src/release/scripts/info.sh generic > generic.inf
Подсчитаем контрольные суммы файлов:
# md5 generic.* > CHECKSUM.MD5 # sha256 generic.* > CHECKSUM.SHA256
У нас получились файлы generic с двухбуквенными расширениями (кусочки архива с ядром), файл generic.mtree, файл generic.inf и файлы контрольных сумм CHECKSUM.MD5 и CHECKSUM.SHA256.
Все эти файлы нам нужно поместить на установочную флеку в каталог 8.2-RELEASE/kernels взамен имеющихся.
Удалим ненужное:
# rm /mnt/install-flash/8.2-RELEASE/kernels/*
Переместим туда нужное:
# mv generic.* CHECKSUM.* /mnt/install-flash/8.2-RELEASE/kernels/*
Всё, теперь можно отмонтировать флешку и пользоваться инсталлятором:
# umount /mnt/install-flash
Если вы выполняли все манипуляции над образом, то можно отмонтировать его и записать на реальную флешку объёмом не менее 2 Гигабайт (всё её содержимое будет затёрто):
# umount /mnt/install-flash # dd if=FreeBSD-8.2-RELEASE-amd64-memstick.img of=/dev/da0
Подобную методику можно использовать для внедрения любых сторонних драйверов в инсталлятор. Проще, конечно, сначала поставить систему, а потом пересобрать её с необходимым сторонним драйвером.
Единственная трудность в описанном случае заключается в том, что систему нужно собрать до её установки - нельзя поставить систему на RAID-контроллер, который ею не поддерживается, потом загрузить её и пересобрать уже с поддержкой RAID-контроллера. Чтобы разрубить этот гордиев узел, нужна промежуточная система, которую можно загрузить и собрать в ней этот драйвер. Инсталлятор, правда, было делать не обязательно, но я его и делал не для себя.