ARM在線升級FPGA程序方法(逆向工程)
公司有款產(chǎn)品采用FPGA做處理器,需要 遠程升級 —— 不使用燒寫器,通過網(wǎng)絡(luò)對其升級。領(lǐng)導(dǎo)提議既然程序是存儲在外部存儲器上的,那么能否通過EPCS4與ARM SPI 總線通信連接刷新FPGA程序呢?于是就有了下文的實踐。
要實現(xiàn)該功能有幾種方式:
1. 解析編譯出的FPGA下載文件jic、pof,將解析后的內(nèi)容燒錄到EPCS4中。但是否這兩種文件格式公開存儲結(jié)構(gòu)呢?芯片廠商是否對此保密?
2. 直接讀取EPCS4的程序,燒錄到另一塊EPCS4中。但是否讀取的EPCS4內(nèi)容以及根據(jù)FPGA序列號做了加密呢?
權(quán)衡任務(wù)安排時間,選擇第二種方案,畢竟就算第一種方案可行,也需要設(shè)計第二方案的讀寫操作。 可喜的是這次逆向工程就這么搞定了。
具體實現(xiàn)
ARM用IO模擬SPI總線燒FPGA配置芯片EPCS4完成軟件升級,在TQ2440上測試,工程可以通過下面的 github連接獲得。該工程與TQ2440平臺定制,在其他平臺未必能運行,建議只看 BitOpt.h,EPCS4.c,EPCSxx.h,mainboot.c 幾個文件,其他無關(guān)代碼不必多看。
升級步驟:
1、 一塊已經(jīng)用下載器燒錄FPGA程序的EPCS4與ARM連接,ARM讀出EPCS4“所有扇區(qū)”數(shù)據(jù)保存到NandFlash中,然后拷貝到電腦備份。
2、 另一塊待燒錄的FPGA與ARM連接,將剛讀出的數(shù)據(jù)燒寫進去。
讀取的數(shù)據(jù)是最終執(zhí)行的二進制Bin文件,因為Altera開發(fā)環(huán)境所生成的jic、pof與最終EPCS4內(nèi)的內(nèi)容不一樣(除非找到生成Bin的方法)。之所以讀取“所有扇區(qū)”數(shù)據(jù)是因為不知道實際Bin文件大小,干脆全部讀出。EPCS4存儲空間是512KB。IO模擬SPI時序的方式速度有限,讀/寫512KB各需要40S,用SPI總線速度會快不少。該方法已經(jīng)在2塊FPGA里運行沒問題,證明Bin文件并沒有在燒寫過程中綁定FPGA芯片序列號。
演示:
啟動后按“5”進入EPCS4測試代碼。
按“N”將Bin文件從Nand拷貝到SDRAM的0x30200000,長度512KB。
按“W”將0x30200000的數(shù)據(jù)燒錄到EPCS4中,寫入后計算寫入前數(shù)據(jù)校驗碼得0x00000039,然后再讀出EPCS4中“所有”數(shù)據(jù),計算讀出內(nèi)容的校驗碼也是0x00000039,比較校驗移植返回“Success?。?!”,否則返回“Check sum Error!!!”。
硬件連接:
升級過程中FPGA需要掉電,或者將FPGA與EPCSxx連接的引腳斷開,否則3個設(shè)備連接到共用信號線無法通信。
EPCS4驅(qū)動編寫、移植注意事項:
1、 演示代碼驅(qū)動部分EPCS4.c、EPCSxx.h采用的是IO模擬SPI總線協(xié)議,不能直接使用,需要看的是各函數(shù)實現(xiàn)的邏輯,照搬到WinCE上。該代碼可以直接兼容EPCS4、EPCS16、EPCS64。對于EPCS1、EPCS128只要修改頁面大小、扇區(qū)大小相關(guān)宏。EPCS1、EPCS128不支持epcs_read_silicon_id(具體查看EPCSxx芯片手冊)。
2、 Mainboot.c文件只需要看3個函數(shù):epcs4_write_file()、epcs4_read_file()、check_sum(),其中讀寫函數(shù)必須根據(jù)具體芯片容量而定,可以通過讀取芯片ID而獲得芯片類型,動態(tài)修改燒寫代碼容量。
3、 SPI時序CLK脈沖寬度“能寬不能窄”,芯片手冊建議脈沖跨度大于20nS,演示代碼中IO模擬SPI速率很低,脈沖寬度3uS,所以未加任何延時。據(jù)說2440SPI總線速率能達到20MB,所以有必要適當(dāng)添加延時,或配置脈沖寬度,
4、 Read Status命令可以再任何時候發(fā)送,返回0表示處于空閑狀態(tài)(具體狀態(tài)意義查看芯片手冊),發(fā)送Read Status以外的命令必須確定芯片處于空閑狀態(tài),否則命令被拋棄。
5、 “每次”發(fā)送寫、擦除命令前必須發(fā)送寫使能命令
6、 發(fā)送“連續(xù)”讀、寫字節(jié)命令最大長度只能在一個Page范圍之內(nèi),讀寫到Page末地址若還有數(shù)據(jù)請求,多余的部分被芯片拋棄。
7、 不允許在一個CS周期內(nèi)發(fā)送兩個命令
正確的命令是:CS拉低——發(fā)送命令1——CS拉高;CS拉低——發(fā)送命令2——CS拉高;
不允許:CS拉低——發(fā)送命令1——發(fā)送命令2——CS拉高;
建議移植代碼測試步驟
1、讀取芯片ID號(silicon ID或Device Identification)
2、如果讀取錯誤的話用示波表查看時序,保證CLK脈沖周期大于40ns,以及MOSI發(fā)送的內(nèi)容正確(Read silicon ID——0xAB或Read silicon ID——0x 9F)。
3、讀取扇區(qū)內(nèi)容。
4、擦除、寫入(寫入前必須先擦除)所有扇區(qū),并讀出寫入數(shù)據(jù)。
5、讀取EPCSxx數(shù)據(jù)在NandFlash里建立bin文件,最后燒寫到EPCSxx能運行
6、與節(jié)點管理器添加更新FPGA通信協(xié)議
評論