2021年5月17日 星期一

Beyond BIOS Note - CH3 UEFI Driver Model


Things should be made as simple as possible - but not simpler
- Albert Einstein

Driver initialization

Load Image

Driver image的檔案必須儲存於ROM、硬碟或網路等媒體裝置,當系統找到driver image時,
就可以透過 gBS->LoadImage() 將image加載至記憶體,而此Image必須符合PE/COFF 格式。

當gBS->LoadImage()執行後,系統就會為driver建立一個handle,這個handle被稱為
Image Handle,並且將一個 EFI_LOADED_IMAGE_PROTOCOL實體放在這handle下。
這時的driver還沒有執行(start),只存在於記憶體之中。

Image Handle
   └ ─ ─ ─ EFI_LOADED_IMAGE_PROTOCOL

Start Image

UEFI Driver Model 的driver 不能直接touch hardware,只能在本身的 Image Handle上
Install Protocol,且還必須安裝EFI_DRIVER_BINDING_PROTOCOL,有
EFI_DRIVER_BINDING_PROTOCOL 的Image Handle 則被稱為Driver Image Handle

若driver要能被unload,則必須實作EFI_LOADED_IMAGE_PROTOCOL 中的Unload() function。

Driver Image Handle
   └ ─ ─ ─ EFI_LOADED_IMAGE_PROTOCOL
   └ ─ ─ ─ EFI_DRIVER_BINDING_PROTOCOL
   └ ─ ─ ─ EFI_DRIVER_CONFIGURATION_PROTOCOL (optional)
   └ ─ ─ ─ EFI_DRIVER_DIAGNOSTICS_PROTOCOL (optional)
   └ ─ ─ ─ EFI_DRIVER_COMPONENT_NAME2_PROTOCOL (optional)

Host Bus Controllers

UEFI Driver Model driver 通常用來操作一至多個controller,而在driver與controller連接之
前,需要操作某些controller,這些controller稱為Host Bus Controller。

每個host bridge都表示成一個device handle,device handle中有 Device Path Protocol及
其IO抽象化操作的Protocol。以PCI Host Bus Controller為例,其提供PCI Host Bridge IO
Protocol。

PCI Host Bridge Device Handle
   └ ─ ─ ─ EFI_DEVICE_PATH_PROTOCOL
   └ ─ ─ ─ EFI_PCI_HOST_BRIDGE_IO_PROTOCOL

PCI Bus Driver可以連接在此PCI Host Bridge,並建立其child handle給每個系統中的PCI
device。而PCI Device Driver 則必須連接這些child handle並提供其抽象化IO操作給系統使用。

Device Drivers

Device Driver不允許建立新的device handle,只在現有的device handle上添加protocol。
其最常見的行為是在Bus driver所建立的handle上提供IO抽象化操作,例如Simple Text
Output、Simple Input、Block I/O及Simple Network Protocol。

Device Handle
   └ ─ ─ ─ EFI_DEVICE_PATH_PROTOCOL
   └ ─ ─ ─ EFI_XYZ_IO_PROTOCOL

    ↓ Start()   ↑ Stop()

Device Handle
   └ ─ ─ ─ EFI_DEVICE_PATH_PROTOCOL
   └ ─ ─ ─ EFI_XYZ_IO_PROTOCOL
   └ ─ ─ ─ EFI_BLOCK_IO_PROTOCOL

連接Device handle的Device Driver必須有Driver Binding Protocol在其本身的image handle上。

Driver Binding Protocol包含Supported ()、Start ()及Stop ()三個functions。
  • Supported ()
  • 功用為測試此driver是否支援特定controller。以上面的Device handle為例,driver
    可以檢查此device handle是否支援 Device Path Protocol及EFI_XYZ_IO_PROTOCOL。
    若 Supported()通過,driver就能透過 Start()來連接controller。

  • Start ()
  • driver透過Start() 在device handle上添加額外的IO protocol。以上面例子來看
    ,Block IO protocol就被建立在device handle上。

  • Stop ()
  • 相對於Start(),Stop() 用來終止driver對device handle的操作,並要負責將原來
    driver安裝在device handle 上的任何protocol移除。

Support ()、Start ()及Stop ()需呼叫OpenProtocol ()來取得protocol和CloseProtocol ()
來釋出Protocol。OpenProtocol ()及CloseProtocol ()會更新handle database,讓系統能追蹤
哪些protocol正在被使用。可透過OpenProtocolInformation ()來獲取component正在使用
protocol的相關列表。

Bus Drivers

Bus driver 負責對其 bus上的 child controller建立 device handle。
A、B、C、D和E代表此Bus controller 的child controller。其上的箭頭代表其parent controller
,如果此Bus controller 為 Host Bus Controller的話,則沒有parent controller。

    ↙
 Bus Controller

    ↓ Start()   ↑ Stop()

    ↙
 Bus Controller
    └ ─ A
    └ ─ B
    └ ─ C
    └ ─ D
    └ ─ E

Bus driver至少必須在其child handle上安裝IO抽象化操作的protocol(EFI_XYZ_IO_PROTOCOL),
若child handle代表physical device,則還需安裝DEVICE_PATH_PROTOCOL。Bus Specific
Driver Protocol為optional,在driver connect child controller時會使用到(Boot Service 的
ConnectController ())。

Child Device Handle
   └ ─ ─ ─ EFI_DEVICE_PATH_PROTOCOL
   └ ─ ─ ─ EFI_XYZ_IO_PROTOCOL
   └ ─ ─ ─ EFI_BUS_SPECIAL_DRIVER_OVERRIDE_PROTOCOL (optional)

Platform Components

driver 的connect與disconnect controller由platform firmware透過Boot Service
ConnectController()和DisconnectController()來決定,通常為UEFI Boot Manager
的一部分。

若platform想要執行系統檢測或安裝作業系統,則其會connect driver到所有可能的 boot
device。若platform想開機到預安裝好的作業系統,則其只需connect 該作業系統需要的
device及其所需的driver。

platform 也可以選擇安裝optional的 protocol Platform Driver Override Protocol,其作用與
Bus Specific Driver Protocol相同,但擁有更高的priority。

Hot Plug Event

當 Hot Plug Event因新增 device觸發時,Bus driver需要負責:
  1. 建立 device 的child handle
  2. 呼叫 ConnectController()

2021年5月13日 星期四

[Python] 將 Qt Designer的 .ui檔轉換成 .py檔

Qt Designer

PySide2

使用 pyside2-uic

pyside2-uic.exe <UI_FILE> -o <OUTPUT_FILE>

pyside2-uic預設安裝位置為%PYTHON_INSTALL_PATH%\Scripts\



PyQt5 & PyQt6

使用 pyuic5pyuic6

pyuic6.exe <UI_FILE> -o <OUTPUT_FILE>

pyuic5及 pyuic6預設安裝位置為%PYTHON_INSTALL_PATH%\Scripts\


2021年5月5日 星期三

建置 Windows Debugger(WinDbg) 環境 via Serial Cable

本篇文章參考
Debugging Tools for Windows

其他WinDbg相關細節
建置 Windows Debugger(WinDbg) 環境 via USB 3.0 cable

Setup Target Computer

1. 使用 Device Manager確認 COM port number。

2. 使用系統管理員權限開啟command prompt,並輸入以下命令
bcdedit /debug on
bcdedit /dbgsettings serial debugport:n baudrate:115200
n為 COM port number。

3. 重新開機。

Setup and Use WinDbg

1. 開啟WinDbg
(C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe)

2. 點選"File" > "Kernel Debugging"

3. 標籤頁切換到"COM",並輸入 HOST端所連接的 COM port number。

3. 按下確定,開始執行WinDbg