SMM是CPU一個獨有的運作模式, 當CPU SMI Pin被觸發時, 就會進入到SMM Mode, 以程式而言, 它會取得Vector去看位址是多少, 而這個位址所指到的記憶體就稱為SMM RAM, 所有有關SMM的Driver都會放在這塊RAM裡面, 當產生中斷進入SMM時, 會去判斷發生中斷的人是誰, 然後去執行相關的Function, 當POST結束之後, 這塊SMM RAM就會被Lock起來, 避免Run Time時有人會去破壞.
在UEFI的架構中, SMM Driver是一個個獨立的Driver, EFI會有Dispatcher來負責執行Driver, 當執行過程中發現Driver是SMM Driver時, 這時會呼叫Kernel的Function, 將此Driver搬到SMM RAM裡面.
SMM Driver可以從Entry Point發現與DXE Driver的不同, SMM的Entry Point會先去Locate一個叫EFI_SMM_BASE_PROTOCOL Protocol, 透過此Protocol來知道目前是否在SMM Mode下, 如果不是在SMM Mode下的話, 程式會先去註冊(Register), 將這支SMM Driver的FV位址以及大小Register起來, 如此一來系統就會依照這些資訊將此SMM Driver搬到SMM RAM裡面去, 搬完之後系統會產生一次SMI, 此時會再進入一次SMM Driver的Entry Point, 第二次進入Entry Point透過EFI_SMM_BASE_PROTOCOL.InSmm ()就會知道目前是在SMM Mode下, 第二次就要透過EFI_SMM_BASE_PROTOCOL.RegisterCallback ()註冊Callback Function. 等下一次SMI觸發時, 就可以進入到Callback Function去執行.
ACPI Enable/Disable
ACPI在OS起來之後, 會去Locate DSDT Table, 在Locate之前, 會先找到FACS Table (Firmware ACPI Control Structure), FACE Table裡面有一個欄位, 會記載Software SMI的Port是多少, 以及ACPI Enable/Disable的Software SMI Number是多少, 如此一來就可以透過Out SMI_Port, ACPI_Number的方式去發SMI來執行ACPI Enable/Disable的Callback Function.
上述的動作可以參考Platform\PlatformSmm的Driver.
S3 Save
在系統進入S3之前, 有一些Chipset的內容需要儲存到記憶體內, 所以需要有一支Driver來處理這些儲存的動作, 在系統進入S3之前, 這些動作會在SMM中完成.
上述的動作可以參考Platform\PlatformS3的Driver.
要做這些儲存的動作, 會透過一種稱為"Boot Script"的命令去完成, Boot Script會在你S3回來後, 把一些已經初始化好的值回填到暫存器內, 如此一來系統才能夠S3回來之後還能夠繼續正常工作. "Boot Script"是EFI的Protocol - EFI_BOOT_SCRIPT_SAVE_PROTOCOL, 而回填的動作是在PEI完成的, 所以會透過EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI.Execute來完成.
當從S3回到OS, POST過程並不會經過DXE Driver, 但會經過PEI Driver, 所以會在PEI Driver上偵測目前的Boot Mode是否為S3, 如果是S3的話, 就透過Boot Script將值填回暫存器內.
感謝分享
回覆刪除