Установка Windows 7 на USB storage и/или виртуальный диск VHD

Источник: habrahabr

В данной статье хочу рассмотреть вопросы по установке на внешний USB-накопитель не обычного набора инструментов реанимации, а полноценной рабочей ОС, которую можно носить с собой. И если Linux ставится из коробки на любое устройство и без проблем работает, то Windows и не ставится, и не работает.

Также эта статья  может быть полезена при загрузке Windows на новом оборудовании (при обновлении материнской платы и т.д.).

 Изначально было 2 противоречивых требования души:"всё своё ношу с собой" и "не хочу быть нагруженным", что в итоге вылилось в установку Ubuntu на внешний диск. Всё было замечательно, но чувствовалась какая-то незавершённость. И решил я установить Windows 7 туда же.

 Но появились проблемы:

  • Windows 7 предупреждает о невозможности загрузки с USB (заботливый какой) и не хочет устанавливаться на него;
  • установщик не умеет работать с VHD;
  • при загрузке Windows 7 с USB-storage появляется BSOD.

И они были успешно решены.

Нам потребуются

  • Сам внешний USB-накопитель (в данном случае USB-HDD) с созданными разделами.
  • Виртуальная машина (в данном случае буду опираться на VMWare Player).Стоит отметить, что для распаковки install.wim можно воспользоваться утилитой imagex из WAIK (Windows Automated Installation Kit, доступный для свободного скачивания с сайта разработчика), об этом можно прочитать в других статьях, например тут, но у меня же душа очень сильно противилась скачиванию чего-либо лишнего, по-этому я решил обойтись уже установленным VMWare (VMWare Player доступен для свободного скачивания)
  • Windows 7 Enterprise или Ultimate (только они поддерживают Native VHD boot). Но можно воспользоваться и другой версией и поставить на физический раздел, а не VHD - в таком случае надо просто пропустить манипуляции с консолью при установке.

Поехали

 В настройках виртуальной машины подключаем к CD-ROM Windows 7 и добавляем HDD: "Use physical disk" -> выбрать диск, соответствующий USB (скорее всего, он последний). Стоит отметить, что другие диски на данном этапе лучше удалить из виртуальной машины. Загружаемся с CD и попадаем в установщик.

Установка

 Сейчас самое время указать установщику VHD. Командой Shift+F10 открывается консоль. Допустим, мы хотим установить Windows на C:\win7.vhd:

diskpart

create vdisk file=C:\win7.vhd type=fixed maximum=25000

select vdisk file=C:\win7.vhd

attach vdisk

create partition primary

list volume

Убеждаемся, что имеем 3 volume с Fs: UDF, NTFS, RAW. Ну или больше, если на диске есть другие разделы.

 Теперь можно уходить с консоли и перейти к непосредственной установке. При выборе назначения установки, мы должны увидеть Disk 1 Partition 1, при выборе которого Windows 7 заботливо предупредит о возможных проблемах, но продолжить всё-таки разрешит.
 Теперь можете откинуться на спинку кресла и отдохнуть. По завершению данного этапа установщик должен записать загрузчик на физический раздел, который запустит Windows с виртуального диска. В итоге мы получим рабочую Windows 7 внутри виртуальной машины. Самое время подготовиться к запуску с USB.

Настройка для запуска с USB

 С особенностями загрузки Windows 7 я особо не знаком, но вкратце суть примерно такая: загрузчик читает ядро и самые важные драйвера (к которым USB не относится) и передаёт управление ядру, которое должно прочитать всё остальное, но в нашем случае оно ничего не найдёт. Соответственно, сам напрашивается вариант: надо сказать загрузчику, что USB критически важен и надо бы сначала его загрузить, а потом передавать управление.

И, что характерно, в Microsoft дали такие возможности: надо в реестре по адресам [HKLM/System/CurrentControlSet/services/usb*] установить значение ключа Start в 0. Самым неприятным оказывается то, что периодически это поле само сбрасывается в 3, судя по всему при появлении новых устройств. Но и это не проблема.

Существует 2 возможных решения (суть которых, естественно, совпадает):

usbbotfix.bat - мне понравился больше, ибо командный файл, который легко правится. Взят отсюда и мною добавлены улучшения: отключение создания имён 8.3, отключение обновления времени последнего обращения (ну зачем нам лишние операции записи) и запрет удаления страниц с исполняемым кодом, дабы случайно не сбросился в своп код драйвера USB (вполне возможно, что это не обязательно, но лучше перестраховаться). Этот файл также скажет планировщику вызывать его при Event 20003 - т.е. при добавлении новых устройств.

Содержимое файла такое:

@echo off

if "%1"=="fix" goto :fix

 

rem -- install task

copy /y "%~f0" "%SystemRoot%\system32\usbbootfix.bat"

SCHTASKS /Create /RU SYSTEM /SC ONEVENT /MO "*[System[Provider[@Name='Microsoft-Windows-UserPnp'] and EventID=20003]]" /EC System /TN USBBootFix /TR "'%SystemRoot%\system32\usbbootfix.bat' fix" /F

rem -- apply other settings

fsutil behavior set disablelastaccess 1

fsutil behavior set disable8dot3 1

reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" /v DisablePagingExecutive /t REG_DWORD /d 1 /f

reg add HKLM\SYSTEM\CurrentControlSet\services\pciide /v Start /t REG_DWORD /d 0x0 /f

reg add HKLM\SYSTEM\CurrentControlSet\services\msahci /v Start /t REG_DWORD /d 0x0 /f

reg add HKLM\SYSTEM\CurrentControlSet\services\intelide /v Start /t REG_DWORD /d 0x0 /f

reg add HKLM\SYSTEM\CurrentControlSet\services\viaide /v Start /t REG_DWORD /d 0x0 /f

rem -- run :fix once after install

 

:fix

call :fixservice usbehci "Boot Bus Extender"

call :fixservice usbohci "Boot Bus Extender"

call :fixservice usbuhci "Boot Bus Extender"

call :fixservice usbhub "System Bus Extender"

call :fixservice usbstor "SCSI miniport"

goto :eof

 

:fixservice

setlocal

set Start=

set Group=

for /f "skip=2 tokens=1,2,*" %%I in ('reg query HKLM\SYSTEM\CurrentControlSet\services\%~1') do (

 if "%%I"=="Start" set Start=%%K

 if "%%I"=="Group" set Group=%%K

)

if not "%Start%"=="0x0" reg add HKLM\SYSTEM\CurrentControlSet\services\%~1 /v Start /t REG_DWORD /d 0x0 /f

if not "%Group%"=="%~2" reg add HKLM\SYSTEM\CurrentControlSet\services\%~1 /v Group /t REG_SZ /d "%~2" /f

endlocal

goto :eof

UsbBootWatcher.exe - проверенное временем решение, устанавливается как сервис и вызывается при изменении выбранных нами ключей реестра. Можно взять тут.

Если загрузка системы не происходит

 В случае, если мы уже пришли на новое место и там оказалось, что ОС запускаться не хочет, придётся чинить тем, что есть: раздел загрузки Repair, в который Windows скорее всего сам и предложит загрузиться после неудачной попытки (если не предложит - перед загрузкой нажимать F8). Затем открываем "Command Prompt" (в случае неудавшегося автоматического восстановления перед этим нажимаем "View advanced options").

Запускаем редактор реестра командой "regedit". Стоит отметить, что это - реестр системы восстановления.

Подключаем нужный реестр (точнее, улей). Нас интересует "[HKLM/SYSTEM/]", он хранится в файле %WINDIR%\System32\Config\System. Для этого наводим фокус на "HKEY_LOCAL_MACHINE", в меню выбираем File -> Load Hive -> нужный файл -> Key name: "nn" (в случае установки на VHD, необходимо его в подключить в консоли).
В загруженном улье должно быть несколько ControlSet*, нужный записан в "Select/Current". Переходим в "ControlSet*/services". В разделе чуть выше описано, что и зачем делать. Но стоит отметить, что в случае запуска не с USB, могут заинтересовать ключи вроде "atapi", "pciide", "intelide", "msahci" и аналогичные им.

Загрузка с USB

 Т.к. перезапускаться лишний раз всем лень, проверимся мы снова в виртуальной машине. Выключаем её, в настройках удаляем все HDD, запускаемся, перебрасываем USB-HDD в виртуалку и… Понимаем, что наш диск не видно. Но ведь в списке того, что требуется не была упомянута поддержка BIOS'ом загрузки с USB.
 Качаем plop boot manager - в архиве есть образы iso и img. Указываем виртуальной машине грузиться с диска plpbt.iso (или plpbt.img для floppy) и уже он передаст управление загрузчику с USB. Всё должно пройти успешно и в итоге запустится Windows 7 и скажет, что найдено новое устройство.

Теперь мы можем перенести внешний диск на любую другую реальную машину и запуститься. Вот и всё. Интересны Ваши предложения по практическому применению.

Краткое резюме

  1. запускаем виртуальную машину, подключив usb-hdd и установщик Windows 7;
  2. в процессе установки указываем, что хотим установить на VHD (по желанию);
  3. меняем приоритет загрузки драйверов;
  4. запускаемся с USB, если BIOS не может, то пользуемся plpbt.

Важные замечания/нерешённые проблемы

  • до загрузки ядра возможны проблемы с доступом к диску по адресам выше 137Gb (у меня были) - можно посоветовать лишь перенести раздел в начало диска (собственно, в т.ч. и из-за этого ограничения я и устанавливал на VHD, а не создавал новый раздел);
  • после каждой загрузки Windows сообщает о том, что что-то поменялось и надо переуказать своп - лучше всего указать руками явный размер свопа и назначить его на D: (физический раздел, C: - виртуальный диск), но при запуске на другой машине вопрос снова возникнет, а если там размер памяти другой, то своп будет выбран автоматически;
  • совсем честные хлопцы предлагают вызывать %windir%\system32\sysprep\sysprep.exe перед переносом на другое железо, но я заметил, что это не обязательно и даже вредно (заново предлагают создать пользователя/сбрасываются настройки/требуется лишний перезапуск после поиска драйверов) - лично у меня всё прекрасно работает и при условии обычного выключения и, что характерно, если ранее система запускалась на данном оборудовании, то повторный запуск пройдёт мгновенно, все драйвера подцепятся автоматически и без перезапусков;
  • загрузчик (bootmgr, Boot\) должен находиться именно на физическом диске (делается автоматически), а хотелось бы всё сбросить внутрь VHD и уже из grub передавать ему управление. Вот эти ребята сделали свой grub с модулем vhd, однако я его не осилил (сначала пришлось править Makefile'ы, чтобы vhd.mod таки создался, но после копирования в /boot/grub/, команда "insmod vhd" завершилась ошибкой "incompatible license"; более детальное изучение кода vhd.c показало, что были внесены изменения в код самого grub-1.97, что меня не устроило, ибо в Ubuntu используется grub-1.99).

Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=27253