RFC (Request for Comments, Запрос на комментарии) - серия документов, публикуемая сообществом исследователей и разработчиков, руководствующихся практическими интересами, в которой описывается набор протоколов и обобщается опыт функционирования Интернет.
Летом 2001 я захотел поэкспериментировать с загрузочными CD-дисками, в частности, с загрузочным диском NT. Делать это на физических CD-RW дисках не хотелось и я решил воспользоваться VMware. Однако, существовавшая в то время VMware2 не умела работать с образами CD, поэтому я научил устройство vn изображать из себя некое подобие CD-ROM. Способ это применим только для FreeBSD 4.x, так как в FreeBSD 5 уже нет устройства vn. Тем не менее, этот способ пока не потерял актуальности, так как, хотя VMware3 умеет работать с образами CD, но под FreeBSD она на данный момент не работает.
Для того, чтобы VMware воспринимало устройство vn как CD-ROM, нужно добавить несколько ioctl. Прежде всего нужен ioctl CDIOCGETVOL, возвращающий уровень громкости. С его помощью VMware проверяет, является ли устройство CD-ROM'ом. В ответ vn возвращает нулевую громкость. Затем VMware вызывает ioctl CDIOCALLOW, который разрешает использовать кнопку eject. В ответ нужно просто вернуть 0. Надо заметить, что этот ioctl вызывается достаточно часто.
Для того, что бы с диском можно было работать и загружаться, нужно ещё два ioctl. Первый, CDIOREADTOCHEADER, возвращает таблицу трэков (TOC), vn возвращает TOC c одним треком. Второй, CDIOREADTOCENTRY, возвращает начало запрашиваемого трека. С помощью CDIOREADTOCENTRY VMware запрашивает два трека – 0 и 1 в формате LBA. vn в обоих случаях возвращает начало трека, равное нулю. NT так же запрашивает два трека – 1 и последний – 170, но в формате MSF. Для первого трека vn возвращет начало трека – 2 секунды, а для последнего – длину всего диска в формате MSF.
Кроме того, NT периодически вызывает ioctl CDIOCREADSUBCHANNEL, возвращающий информацию о подканале – vn возвращает CD_AS_NO_STATUS, говорящий о том, что трек не содержит аудио. На всякий случай также реализован ioctl CDIOCPREVENT, блокирующий кнопку eject, хотя я не видел, чтобы он использовался.
Для того, что бы vn всё это умел, нужно наложить патч:
# patch -d /usr/src < patch.vn_cd.txt
и пересобрать модуль vn.ko и vnconfig. Для сборки модуля нужно перейти в каталог, где лежат объектные файлы ядра и запустить make: # cd /usr/src/sys/compile/KERNEL # make
Переустанавливать всё не нужно, достаточно только скопировать модуль: # cp modules/usr/src/sys/modules/vn/vn.ko /modules/vn.ko
Для сборки vnconfig нужно перейти в каталог /usr/src/usr.sbin/vnconfig и запустить make: # cd /usr/src/usr.sbin/vnconfig # CFLAGS="${CFLAGS} -I /usr/src/sys/" make obj all
Собранный vnconfig можно установить: # make install
После всех этих действий в vnconfig появится новый флаг cdrom:
# vnconfig -s cdrom -c vn0c image.iso
и с помощью cdcontrol можно попробовать прочитать TOC имиджа: # cdcontrol -f /dev/vn0c info Starting track = 1, ending track = 1, TOC size = 18 bytes
В этой строке отображается информация, которую cdcontrol получает через ioctl CDIOREADTOCHEADER. Однако, в отличие от реального диска, в нашем случае cdcontrol не может показать начало и длину треков, так как вместо реализованного ioctl CDIOREADTOCENTRY, он использует нереализованный ioctl CDIOREADTOCENTRYS, возвращающий начало нескольких треков.
В настройках VMware нужно указать, что CD-ROM находиться в устройстве /dev/vn0c.