В данной статье хочу рассмотреть вопросы по установке на внешний 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:
Убеждаемся, что имеем 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 :fixrem -- 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 и скажет, что найдено новое устройство.
Теперь мы можем перенести внешний диск на любую другую реальную машину и запуститься. Вот и всё. Интересны Ваши предложения по практическому применению.
Краткое резюме
запускаем виртуальную машину, подключив usb-hdd и установщик Windows 7;
в процессе установки указываем, что хотим установить на VHD (по желанию);
меняем приоритет загрузки драйверов;
запускаемся с 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).