Персональный
сайт
Игоря
Сысоева


 
english
обо мне
 
sysoev.ru
 
nginx
 
mod_accel
mod_realip
mod_deflate
программирование
всякая всячина
windows
freebsd
apache
pppd
unix
web
 
 

VMware2 и образы компактных дисков

 

18.03.2002

Летом 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.

(C) Игорь Сысоев
http://sysoev.ru