題外話
BootROM
BootROM Header Searching and Loading
總結
題外話
第一次使用Markdown編寫博客,之前都是直接用word或者onenote寫好之后復制到博客上,發(fā)現(xiàn)文字編排效果很差,不忍翻閱下去。所以轉投markdown懷抱。
這里將會新開一個章節(jié),專門更新關于Zynq的一些心得,我希望能夠完成以下幾個方面:
因此,我希望能夠通過Zynq片上強大的FPGA資源和ARM資源,來完成FPGA工程師和ARM工程師的協(xié)同工作,一般來說FPGA部分來完成所有高速接口驅動以及一些高速算法(并行獨立或者串行復用),然后ARM部分來完成通信協(xié)議的實現(xiàn),不管是私有的(如用戶自定義的串口協(xié)議的封包和解包)或者標準的(如TCP/IP或者USB等),以及FPGA的流程控制,錯誤狀態(tài)控制還有遠程更新控制等。
為了完成上述化學反應,一個很重要的方面就是如何協(xié)調ARM和FPGA(都是Zynq片上的資源),這個其實很多開發(fā)板的學習手冊都已經(jīng)給出了答案,那就是應用AXI4總線。那剩下的問題就是,如何實現(xiàn)Multiboot以及fallback。
因為在S6或者其他7系列的FPGA中,是有一套非常成熟的FPGA加載機制(Xilinx有很詳細的指導手冊),但是來到Zynq時代,這個方式變了。為什么呢?因為現(xiàn)在zynq上有ARM了,所有的加載工作實際上可以借由ARM來實現(xiàn),這無疑也給用戶帶來了靈活的操作空間,即用戶可以自己整一套屬于自己的,滿足要求的加載方式,這也是本文研究的重點:解析Zynq的加載方式。
這里將通過對比Zynq的TRM和FSBL源碼,來一步一步解析Zynq的加載流程,如下所示
運行流程簡單的說就是:
觸發(fā)條件 POR或者non-POR
ARM加載BootROM,這個程序停留在Zynq內部ROM,用戶無法修改,用于實現(xiàn)搜索FLASH中的BootROM header,然后根據(jù)Header(這個header在整個FLASH中至少需要一個,Xilinx的軟件會自動整合出來這哦頭文件)信息,將FSBL加載到OCM(on chip memory)
開始運行FSBL,進一步加載Bitstream(PL用,如果有bit文件在FLASH中的話)或者其他鏡像(PS用,裸機或者帶系統(tǒng))
run 上述的其他鏡像,裸機或者RTOS的話直接run,linux的話需要先運行u-boot
BootROM
永遠問自己,我們的芯片(在這里是Zynq)在POR復位或者non-POR 復位后,ARM是怎么樣一步一步最終來到用戶的main.c,對FPGA工程師而言,就是FPGA是怎么完成初始化任務的。
這里我們不妨寫的詳細一點,將所有的技術細節(jié)都呈現(xiàn)出來。這就需要我們打開Zynq的TRM:
可以看到,在non-POR或者POR以后,Zynq會完成:
鎖存配置引腳,如下圖所示,
2 初始化PLL(根據(jù)復位時鎖存的進行選擇初始化或者不初始化)
3 初始化APU(由兩個ARM CPU構成)
4 ROM CRC check
5 初始化boot用的引腳(Q-spi,NOR,SD,NAND等等),根據(jù)上一步鎖 存的配置引腳進行選擇。
6 出發(fā)并等待PL完成初始化,前提是PL部分上電已經(jīng)完成的話。如果此時PL8 上電沒有完成,這這一步直接跳過
7 開始搜索BootROM Header,如果搜索到了一個合法的header,就會基于這個header加載FSBL(加密或不加密)
8 被加載的FSBL可能是XIP(execute in place,在存儲器里直接運行)或者是被加載到了DDR中,加載完畢后BootROM完成任務,將控制權交給了FSBL。
通過上面的流程描述,我們可以獲得一個表觀的理解,原來Zynq加載蠻復雜的。因為Zynq里面包含了PS(APU,即兩個ARM Cortex-A9 cpu)和PL(根據(jù)系列的不同,可能是A7系列,也可能是K7系列)兩個部分。
這兩個部分的加載,會根據(jù)用戶選擇的不同而不同,如下所示:
從上面可以知道,PS的加載和PL的加載并不是完全獨立的,如下圖所示
Note 1: if PL was power-up(needed for JTAG or secure mode), BootROM will initial PL then wait until PL complete initialization
如上流程,就是整個PS和PL加載的過程,基本上我們只需要保證合適的文件被正確的燒寫到FLASH中,那么整個加載就會正確的跑下去,這個所謂的合適的文件包括:
1 BootROM Header, Xilinx的工具自動生成
2 FSBL,Xilinx由范例工程
3 BitStream,用戶根據(jù)項目自定義的PL固件,即ARM固件
4 Application.elf,用戶根據(jù)項目自定義的PS固件,即FPGA固件
整個BootROM是寫死在Zynq的片上ROM中,其中最重要,同時也會影響后面FSBL執(zhí)行的,就是BootROM Header的searching 和 loading。
BootROM Header Definition
類似于A7或者S6系列的multiboot過程需要一個header文件,它用于實現(xiàn):
1 同步,F(xiàn)LASH位數(shù)自動檢測
2 指定 Golden所需的Bin在FLASH中的Offset
3 指定Function所需的Bin在FLASH中的Offset
4 發(fā)送PROGRAM-B指令,讓FPGA開始加載Bin
在Zynq系列中,這個Header的功能被進一步的擴大,下面我們來看一下這個Header的定義吧:
接下來逐條來解釋其作用,同時留下一點伏筆,因為這些最終都會被FSBL所引用。
1 Interrupt Table for Execution-in-Place — 0x000 to 0x01C
這些數(shù)據(jù)用于XIP,這里不討論
2 Width Detection — 0x020
用于檢測Qspi的位寬到底是X1,X2,還是X4,如果是X8,還需要下面那個 Image Identification 寄存器
3 Image Identification — 0x024
固定為0x584C4E58,‘XLNX’,還可用于X8檢測
4 Encryption Status — 0x028
配置FSBL/User code到底是加密還是不加密
5 FSBL/User Defined — 0x02C
用于保存Header的版本,應該也是xilinx自動生成的
6 Source Offset — 0x030
用于保存FSLB/User code image被保存的offset地址,這個Offset是相對于Header的起始位置而言的,這個在FSBL中會有體現(xiàn),這留個記號
7 Length of Image — 0x034
用于保存被加載的FSLB/User code image的大小,<=192KB。該數(shù)據(jù)=0時意味著不需要copy,是XIP。
8 FSB Load Address— 0x038
FSLB/User code image copy的目標地址,因為該image是存在FLASH中的,需要被復制到其他OCM中去。
9 Start of Execution — 0x03C
copy完以后,cpu需要從哪里開始執(zhí)行第一條代碼,<= 0x30000,也即是192KB。這個很重要,會在介紹FSBL源碼的時候重新在驗證并確認這個功能。然而這樣地址,或者長度之類的,都是通過配置Xilinx提供的工具自動打包生成的。
10 Total Image Length — 0x040
load進OCM的總長度,這個長度會大于等于Length of Image — 0x034,因為在加密模式下,還會包含HMAC頭文件之類的。
11 QSPI Config Word — 0x044
固定為0x01
12 Header Checksum — 0x048
0x020 to 0x044的checksum,用于驗證Header是否完整,F(xiàn)SBL會應用到
13 FSBL/User Defined— 0x04C to 0x097
自定義數(shù)據(jù)
14 ???Boot Header Table Offset???— 0x098
TRM中這個數(shù)據(jù)的命名好像有問題
15 QSPI Config Word — 0x09C
指向Image Header Table,這個Table里面會記錄整個FLASH里面除了FSBL以外,還有幾個image,包括Bitstream,elf等等。每一個image會有一個Header(不是這里的BootROM Header,而是專門的Header,F(xiàn)SBL里面在介紹),所有的Header組成一個Table。
16 Register Initialization Parameters — 0x0A0 to 0x89C
利用Add+Data的方式,直接對某個地址進行數(shù)據(jù)寫操作,應該非常高效,估計也是xilinx工具自動生成的。
17 FSBL/User Defined — 0x8A0 - 0x8BF
18 FSBL Image or User Code Start Address — 0x8C0
FSBL Image or User Code 實際可以放置的起始地址,也就是上面的Source Offset — 0x030 >= 0x8C0
介紹了這么多,估計一時也不好消化,沒有關系,上面黃色標記了的數(shù)據(jù),會在FSBL中隆重的重新介紹。
BootROM Header Searching and Loading
回到老話題,BootROM會利用上述BootROM Header把FSBL拷貝到OCM中,然后讓FSBL接管CPU開始run。而實際上FSBL也會應用上面的BootROM Header文件去尋找下一步所需的image,包括BitStream等,這個以后再說。
那么BootROM 是如何找到BootROM Header的呢?
1 BootROM會首先在FLASH的0x00處尋找Header,依據(jù)就是Image Identification parameter – 0x024 是否等于 ‘XLNX’ . 其次就是檢查Header Checksum — 0x048
2 如果都沒有問題,就按照Header內容將FSBL的code加載到OCM的指定位置,然后run。
3 如果有問題,將Multiboot reg 加 1 ,然后自動發(fā)送non-POR,下一次運行的BootROM下一個32KB來尋找Header ,并重新檢查是否滿足條件。
4 Multiboot reg在這個寄存器不會被non-POR清除,會被保留到下一次的Boot中去
因此,BootROM Header 必須放置在32KB的整數(shù)倍位置,這個應該是Xilinx的工具自動完成的
這個檢查checksum的操作也同樣的在FSBL中被執(zhí)行,以后在介紹
總結
介紹了這么多,總結一下:
重啟后自動執(zhí)行BootROM
BootROM會自動尋找 BootROM Header
找到Header后,會將FSBL加載到OCM中
然后將CPU的PC指針指向目標地址,同時FSBL開始run
審核編輯 :李倩
-
FPGA
+關注
關注
1629文章
21736瀏覽量
603319 -
Zynq
+關注
關注
10文章
609瀏覽量
47181 -
bootrom
+關注
關注
0文章
6瀏覽量
3730
原文標題:FPGA - Zynq - 加載 - BootRom
文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論