顯示廣告
隱藏 ✕
看板 million
作者 emulators (模擬器)
標題 [note] FW storage & SPI flash 作業做法紀錄
時間 2014年11月19日 Wed. PM 12:02:03


// Notes:
	

//  The global variables initialized by this function are:
//   pST             Pointer to the EFI System Table.
//   pBS             Pointer to the Boot Services Table.
//   pRS             Pointer to the Runtime Services Table.
//   TheImageHandle  Image handle.

為什麼要 locate EFI protocol?
喔喔~因為要使用這個protocol內的function 所以要locate出有這個protocol 的Handle 才能去使用


看 bin/buildbios.log, 最後往回拉 可看有幾個FV
有些 FV 會掛在 protocol 裡面 有些不會, 其原因是 那些 FV 並不需要被存取到.
而那些 FV 在 Build/ROMlayout.c 中, 最後的參數是0. 若是 ROM_AREA_FV_DXE 則表示它在 DXE 階段被加入 protocol



1. 顯示 EFI file 的 GUID, size, type. 若其裡面還有區塊 (section), 一樣照同樣方式顯示.
   另外, 顯示出來 sections 大小總合要接近 file size.

要用 locateHandleBuffer, 再用 HandleProtocol ( <--- ? )
因 HandleProtocol 函式可以把 EFI_FIRMWARE_VOLUME_PROTOCOL 的變數指向一個 FW volume 的實體,
進而可以使用 EFI_FIRMWARE_VOLUME_PROTOCOL 變數中的 member func, 來存取 FW volume 的相關資訊.

以下, 將 EFI_FIRMWARE_VOLUME_PROTOCOL 宣告出之指標變數以 fv 代稱之.
fv->findFile()



2. 把 SPI flash 中, 任意一個 FW vol 的 signature 清掉成FF.

需要把 SPI flash 中, 有關 signature 的部分複製出來, 改掉 signature 部分後再寫回去.
因為 SPI flash 不能直接把 0變1, 要用 SPI flash command "erase" 才行,
而 erase 一次刷掉就刷 4kBytes, 但讀取和寫入只能針對 64 Bytes, 所以要先備份 4kBytes 的資料,
到時用迴圈把備份的資料再寫回去. 讀取時方法亦需要回圈.

status register: 在 pSPIBASE 的 offset 10h 的一個 byte 長. (即 10h ~ 10h)

write protection:
PCI Intel ISA Bridge (bus00 dev1F func00) 的 offset DCh 處, 其 bit5 決定 bit0 是否只能在
SMM (system management mode) 下修改. bit0 若為0則是 write protect.

故要先將 bit 5 = 0, 再 bit0 = 1.

解掉之後, 要依序把 SPI flash 的內容讀出來.
spec 指出, pSPIBASE + 91h, 92h 是指令部分,
98h~9Fh 為指令 slot, 根據 spec 設好 fast read 的指令以後, 將 92h 設為 7F,  
91h 的 bit4~6 設好指令 slot 位置, 91h 的 bit2 若讀則為0, 寫與抹除則為1.
另外需要在 08h ~ 0Ah 設好起始位址為 0x180000, 即 flash 的內容起始位址.
依此規則, 當 91h bit1 為 1 時, 即執行在 bit4~6 所指定到的 slot 的 SPI 指令.
注意每個 SPI 指令做完後需等待其完成, 可將 SPIFlash.c 中之程式碼拿來用.
另外寫入與抹除指令需另外再等待其寫入與抹除完成, 一樣從前述程式碼中取得.

 Fast read 指令所讀出的內容 (起始位置從180000h 開始往後64 Bytes的內容)
將會呈現到 pSPIBASE + 10h ~ pSPIBASE + 4Fh 裡, 共 64 Bytes.
其中將會包含 signature. 用 array 或其他資料結構, 將讀出來之 64 Bytes, 順序存起.
存完後, 參考 spec 下抹除指令, 使 180000h 起始的 4k Bytes 內容全變 FFFF.

之後, 將備份內容中的 signature 改掉成 FFFFFFFF, 再用寫入方式, 將備份內容還原,
即完成.
寫入為 pSPIBASE + 08h ~ 0Ah 的位址為起始, 將 offset 10h 到 4Fh 的 64kBytes 內容寫回.
記得寫入一次, 下次要再寫之前, 要更新 08h ~ 0Ah 之內容,
避免同樣位置之資料被新資料覆蓋.

--
※ 作者: emulators 時間: 2014-11-19 12:02:03
※ 編輯: emulators 時間: 2014-12-03 21:18:41
※ 看板: million 文章推薦值: 0 目前人氣: 0 累積人氣: 519 
r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇