Эти скрипты обеспечивают поддержку для упрощения отладки кода UEFI на виртуальных машинах, таких как VMware Fusion или QEMU. Код основан на DebugPkg Андрея Варкентина (Andrei Warkentin) с улучшениями поддержки macOS, улучшенной печатью и исправлением ошибок.
Общий подход заключается в следующем:
По умолчанию EDK II оптимизирует создаваемые двоичные файлы, поэтому для создания «настоящего» отладочного двоичного файла следует ориентироваться на NOOPT. Помните, что это сильно влияет на размер результирующего двоичного файла:
build -a X64 -t XCODE5 -b NOOPT -p OpenCorePkg/OpenCorePkg.dsc # для macOS
build -a X64 -t CLANGPDB -b NOOPT -p OpenCorePkg/OpenCorePkg.dsc # для других систем
GdbSyms.dll создаётся как часть OpenCorePkg, но также доступны готовые двоичные файлы:
Чтобы дождаться подключения отладчика при запуске, можно использовать функции WaitForKeyPress из OcMiscLib.h. Помните, что эта функция дополнительно вызывает функцию DebugBreak, которая может быть нарушена во время инициализации GDB/LLDB.
VMware Fusion содержит специальный debugStub, который можно включить, добавив следующие строки в файл .vmx. После этого vmware-vmx будет прослушивать TCP-порты 8832 и 8864 (на хосте) для 32-битных и 64-битных соединений gdb соответственно, аналогично QEMU:
debugStub.listen.guest32 = "TRUE"
debugStub.listen.guest64 = "TRUE"
Если сеанс отладки удалённый, следует добавить следующие строки:
debugStub.listen.guest32.remote = "TRUE"
debugStub.listen.guest64.remote = "TRUE"
Чтобы остановить виртуальную машину после выполнения первой инструкции, добавьте следующую строку. Обратите внимание, что она не работает на VMware Fusion 11 и приводит к зависанию:
monitor.debugOnStartGuest32 = "TRUE"
Для принудительного использования аппаратных точек останова используйте следующую строку:
debugStub.hideBreakpoints = "TRUE"
В качестве альтернативы для принудительного использования программных точек останова INT 3 используйте следующую строку:
debugStub.hideBreakpoints = "FALSE"
В зависимости от версии VMware Fusion и версии хоста macOS может работать только один из вышеперечисленных методов для пошагового выполнения и достижения точек останова, поэтому вам может потребоваться попробовать оба варианта.
При настройке виртуальной машины для отладки полезно иметь возможность легко входить в настройки прошивки UEFI. Чтобы остановиться во время POST на 3 секунды, добавьте следующую строку. Нажатие любой клавиши во время этой паузы приведёт к загрузке настроек прошивки:
bios.bootDelay = "3000"
Чтобы протестировать AudioDxe.efi в VMware Fusion, файл .vmx должен содержать строку:
sound.virtualDev = "hdaudio"
Это присутствует по умолчанию в виртуальной машине, настроенной как гостевая ОС macOS, и может быть добавлено вручную в гостевую ОС Linux. Текущее качество звука UEFI AudioDxe.efi в VMware Fusion не соответствует качеству, доступному на реальном оборудовании.
Помимо VMware, также можно использовать QEMU. Отладка QEMU на хосте macOS обычно довольно ограничена и медленна, но её достаточно для общего устранения неполадок, когда не требуется загрузка гостевой ОС macOS.
Соберите прошивку OVMF в режиме NOOPT, чтобы иметь возможность её отлаживать:
git submodule init
git submodule update # to clone OpenSSL
build -a X64 -t XCODE5 -b NOOPT -p OvmfPkg/OvmfPkgX64.dsc # for macOS
build -a X64 -t CLANGPDB -b NOOPT -p OvmfPkg/OvmfPkgX64.dsc # for other systems
Чтобы собрать OVMF с поддержкой SMM, добавьте -D SMM_REQUIRE=1
. Чтобы собрать OVMF с отладкой через последовательный порт, добавьте -D DEBUG_ON_SERIAL_PORT=1
.
Примечание: При желании вы можете собрать OvmfPkg с помощью собственного скрипта сборки, который находится в каталоге OvmfPkg. Используйте, например, ./build.sh -a X64
или ./build.sh -a X64 -b NOOPT
. Дополнительные аргументы сборки, такие как для последовательной отладки или поддержки SMM, могут быть добавлены к этому.
Подготовьте каталог запуска с OpenCore, как обычно. Например, создайте каталог с именем QemuRun и перейдите в него. У вас должна быть аналогичная структура каталогов:
.
└── ESP
└── EFI
├── BOOT
│ └── BOOTx64.efi
└── OC
├── OpenCore.efi
└── config.plist
Запустите QEMU
Скрипт сборки OvmfPkg также может запустить виртуальную машину, которую он только что построил, например, ./build.sh -a X64 qemu -drive format=raw,file=fat:rw:ESP
должно быть достаточно для запуска OpenCore; все параметры после qemu передаются непосредственно QEMU. При таком запуске используется файл OVMF.fd из каталога сборки OVMF, который представляет собой OVMF_CODE.fd и OVMF_VARS.fd, объединённые вместе; вы можете предпочесть следовать второму примеру ниже, в котором эти файлы указаны отдельно.
В оставшихся примерах OVMF_BUILD должен указывать на каталог сборки OVMF, например, $HOME/UefiWorkspace/Build/OvmfX64/NOOPT_XCODE5/FV
.
Чтобы запустить QEMU напрямую и с более реалистичной архитектурой машины:
qemu-system-x86_64 -L . -bios "$OVMF_BUILD/OVMF.fd" -drive format=raw,file=fat:rw:ESP \
-machine q35 -m 2048 -cpu Penryn -smp 4,cores=2 -usb -device usb-mouse -gdb tcp::8864
Для запуска QEMU с поддержкой SMM; также указывая CODE и VARS отдельно; также указав порт, необходимый для подключения отладчика (следующий раздел):
qemu-system-x86_64 -L . -global driver=cfi.pflash01,property=secure,value=on \
-drive if=pflash,format=raw,unit=0,file="$OVMF_BUILD"/OVMF_CODE.fd,readonly=on \
-drive if=pflash,format=raw,unit=1,file="$OVMF_BUILD"/OVMF_VARS.fd \
-drive format=raw,file=fat:rw:ESP \
-global ICH9-LPC.disable_s3=1 -machine q35,smm=on,accel=tcg -m 2044 -cpu Penryn \
-smp 4,cores=2 -usb -device usb-mouse -gdb tcp::8864
Вы можете дополнительно передать флаг -S
в QEMU, чтобы остановиться на первой инструкции и дождаться соединения GDB. Чтобы использовать последовательную отладку, добавьте -serial stdio
(это приводит к тому, что вывод журнала консоли OpenCore отправляется в оболочку, которая запустила QEMU).
Поддержка клавиатуры и мыши при запуске OpenCore в QEMU:
Включить поддержку клавиатуры и мыши практически так же, как на обычном компьютере, однако некоторые типичные варианты:
Для поддержки клавиатуры либо а) используйте KeySupport=true, либо б) используйте KeySupport=false, в этом случае передайте -usb -device usb-kbd
в QEMU и используйте драйвер OpenUsbKbDxe.efi.
Для поддержки мыши либо а) используйте драйвер Ps2MouseDxe.efi, либо б) передайте -usb -device usb-mouse
в QEMU и используйте драйвер UsbMouseDxe.efi.
Поддержка звука в QEMU:
Флаги QEMU для включения поддержки звука в QEMU, работающем на хосте macOS, — -audiodev coreaudio,id=audio0 -device ich9-intel-hda -device hda-output,audiodev=audio0
.
— coreaudio — это специфический драйвер аппаратного аудио macOS.
— intel-hda можно использовать вместо ich9-intel-hda, чтобы использовать программный драйвер Intel HDA ICH6 QEMU вместо ICH9.
— Обратите внимание, что текущее качество звука AudioDxe.efi UEFI в QEMU не соответствует качеству, доступному на реальном оборудовании.
Для простоты efidebug.tool выполняет все необходимые сценарии GDB или LLDB. Обратите внимание, что это добавляет команду reload-uefi в отладчике, которую необходимо запускать после загрузки любого нового двоичного файла.
Сценарий будет запущен и попытается подключиться с разумными настройками по умолчанию без дополнительной настройки, но проверьте заголовок efidebug.tool для переменных среды, чтобы настроить вашу настройку. Например, вы можете использовать переменную EFI_DEBUGGER, чтобы принудительно установить LLDB (LLDB) или GDB (GDB).
Рекомендуется использовать GDB Multiarch на случай, если планируется использовать разные архитектуры отладки. Это можно сделать несколькими способами:
— https://www.gnu.org/software/gdb/ — из исходного кода. — https://macports.org/ — через MacPorts (sudo port install gdb +multiarch). — Ваш предпочтительный метод здесь.
После установки GDB вы можете использовать efidebug.tool для отладки. Если вы не хотите использовать efidebug.tool, можно использовать следующий набор команд в качестве справочного:
$ ggdb /opt/UDK/Build/OpenCorePkg/NOOPT_XCODE5/X64/OpenCorePkg/Debug/GdbSyms/GdbSyms/DEBUG/GdbSyms.dll.dSYM/Contents/Resources/DWARF/GdbSyms.dll
target remote localhost:8864
source /opt/UDK/OpenCorePkg/Debug/Scripts/gdb_uefi.py
set pagination off
reload-uefi
b DebugBreak
CLANGDWARF — это набор инструментов на основе LLVM, который напрямую генерирует образы PE/COFF с отладочной информацией DWARF через компоновщик LLD. Для работы требуется LLVM 9.0 или более новая версия с работающим удалением мёртвого кода в LLD (патчи LLD).
Установка: После применения патча ClangDwarf к EDK II инструмент CLANGPDB будет вести себя как CLANGDWARF.
Для поддержки отладки может потребоваться установить переменную среды EFI_SYMBOL_PATH в список путей с разделителями «:» к файлам .debug, например:
export EFI_SYMBOL_PATH="$WORKSPACE/Build/OvmfX64/NOOPT_CLANGPDB/X64:$WORKSPACE/Build/OpenCorePkg/NOOPT_CLANGPDB/X64"
Причина этого требования заключается в хрупкой реализации опции --add-gnudebug-link
в llvm-objcopy (ошибка LLVM. Она удаляет путь из файла отладки, сохраняя только имя файла, и также не обновляет запись DataDirectory отладки.
После того как вы настроите отладку на уровне командной строки с помощью GDB или LLDB, настройка отладки на уровне IDE (если вы предпочитаете её использовать) сводится к выбору IDE, которая уже знает о том, какой GDB или LLDB вы будете использовать, а затем извлечению соответствующей конфигурации, которую efidebug.tool применил бы за вас.
Например, это рабочая настройка для отладки LLDB в VS Code на macOS:
{
"name": "OC lldb",
"type": "cppdbg",
"request": "launch",
"targetArchitecture": "x64",
"program": "${workspaceFolder}/Debug/GdbSyms/Bin/X64_XCODE5/GdbSyms.dll",
"cwd": "${workspaceFolder}/Debug",
"MIMode": "lldb",
"setupCommands": [
{"text": "settings set plugin.process.gdb-remote.target-definition-file Scripts/x86_64_target_definition.py"},
],
"customLaunchSetupCommands": [
{"text": "gdb-remote localhost:8864"},
{"text": "target create GdbSyms/Bin/X64_XCODE5/GdbSyms.dll", "ignoreFailures": true},
{"text": "command script import Scripts/lldb_uefi.py"},
{"text": "command script add -c lldb_uefi.ReloadUefi reload-uefi"},
{"text": "reload-uefi"},
],
"launchCompleteCommand": "exec-continue",
"logging": {
"engineLogging": false,
"trace": true,
"traceResponse": true
}
}
Примечание 1: Тип отладки cppdbg является частью стандартных инструментов VSCode cpp — вам не нужно устанавливать какие-либо другие инструменты LLDB с торговой площадки.
Примечание 2: Шаг b DebugBreak из efidebug.tool опущен в customLaunchSetupCommands, вам нужно добавить точку останова вручную в VSCode перед запуском первого сеанса отладки, иначе VSCode будет жаловаться на попадание в точку останова, которую он не устанавливал.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарий ( 0 )