版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、1 2幾種常見的boot方式12.1從epcs串行存貯器中boot12.2從外部cfi 并行flash中boot13從epcs中boot13.1epcs控制器的bootloader分析23.2epcs控制器33.3epcs串行存貯器件54從并行flash中boot54.1并行flash配置控制器54.2直接在flash中運(yùn)行程序54.3在ram中運(yùn)行程序65bootloader解讀75.1boot_loader.s解讀85.2boot_loader_epcs_bits.s解讀105.3boot_loader_cfi_bits.s解讀216crt0.s解讀231 概述nios ii 的boot過
2、程要經(jīng)歷兩個(gè)過程。1. fpga器件本身的配置過程。fpga器件在外部配置控制器或自身攜帶的配置控制器的控制下配置fpga的內(nèi)部邏輯。如果內(nèi)部邏輯中使用了nios ii,則配置完成的fpga中包含有nios ii軟核cpu。2. nios ii本身的引導(dǎo)過程。一旦fpga配置成功后,nios ii 就被邏輯中的復(fù)位電路復(fù)位,從reset地址開始執(zhí)行代碼。nios ii 的reset地址可以在sopc builder的“nios ii morecpusetting”頁表中設(shè)置。2 幾種常見的boot方式2.1 從epcs串行存貯器中boot這種boot方式,fpga的配置數(shù)據(jù)和nios ii的程
3、序都存放在epcs器件中。fpga配置數(shù)據(jù)放在最前面,程序放在后面,程序可能有多個(gè)段,每個(gè)段前面都插有一個(gè)“程序記錄”。一個(gè)“程序記錄”由2個(gè)32位的數(shù)據(jù)構(gòu)成,一個(gè)是32位的整數(shù),另一個(gè)是32位的地址,分別用于表示程序段本身的長度和程序段的運(yùn)行時(shí)地址。這個(gè)“程序記錄”用于幫助bootloader把各個(gè)程序段搬到程序執(zhí)行時(shí)真正的位置。epcs是串行存貯器,nios ii 不能直接從epcs中執(zhí)行程序,它實(shí)際上是執(zhí)行epcs控制器的片內(nèi)rom的代碼(即bootloader),把epcs中程序的搬到ram中執(zhí)行。2.2 從外部cfi 并行flash中boot這種boot方式還可以分為2種情況。1.
4、程序直接在flash中運(yùn)行。這種情況程序不需要另外的bootloader,nios ii 復(fù)位時(shí)reset地址(指向flash內(nèi)部)開始執(zhí)行程序,程序必須有啟動(dòng)代碼用于搬移.rwdata段(因?yàn)?rwdata段是可讀寫的不能存放在flash中),同時(shí)如果.rodata段和.exceptions段連接時(shí)沒有指定在flash中話(比如在ram中),也會(huì)被搬到ram中,并對.bss段清零,設(shè)置棧的指針。這些工作都在crt0.s中完成。2. 程序在ram(包括on-chip ram,sdram,ssram泛指一般的ram)中運(yùn)行。這種情況需要有一個(gè)專門的bootloader,它把存放在flash中的各
5、個(gè)程序段搬到程序執(zhí)行時(shí)各個(gè)段真正的位置。3 從epcs中boot要支持nios ii從epcs中boot首先要求fpga器件要支持主動(dòng)串行配置。altera的cyclone,cyclone ii和stratix ii系列的fpga支持主動(dòng)串行配置。直到nios ii 5.1版本,nios ii 從epcs中boot在stratix ii系列的fpga上實(shí)現(xiàn)上仍有問題。所以這種方式主要用于cyclone和cyclone ii系列的器件。為了實(shí)現(xiàn)這種boot方式,用戶必須在sopc builder中添加一個(gè)epcs控制器,無須給它分配管腿,quartus ii 會(huì)自動(dòng)給它分配到專用管腿上。添完ep
6、cs控制器后,sopc builder會(huì)給它分配一個(gè)base address,這個(gè)地址是epcs控制器本身攜帶的片上rom在nios ii系統(tǒng)中的基地址,這個(gè)rom存有一小段bootloader代碼,用于引導(dǎo)整個(gè)過程。所以,必須在sopc builder的“nios ii morecpusetting”頁表中把reset地址設(shè)置為這個(gè)基地址,使得nios ii 復(fù)位后從這個(gè)地址開始執(zhí)行以完成整個(gè)引導(dǎo)過程。3.1 epcs控制器的bootloader分析epcs控制器帶有一塊片內(nèi)rom,內(nèi)有bootloader代碼,nios ii 就靠這段代碼完成boot過程。它把epcs里的nios ii程序
7、映象復(fù)制到ram中,然后跳轉(zhuǎn)到ram中運(yùn)行。由于程序映象是由elf2flash輸出的,bootloader對被搬運(yùn)的程序映象的位置和結(jié)構(gòu)的解讀必須和elf2flash工具一致。fpga的配置數(shù)據(jù)從epcs偏移為0的地址開始存放,緊挨著配置數(shù)據(jù)后面是一個(gè)32位的整數(shù),指示程序段的長度,接著是一個(gè)32位的地址,指示程序執(zhí)行時(shí)該程序段的地址,我們把這個(gè)長度和地址一起稱為“程序記錄”,“程序記錄”隨后就是程序段映象。一個(gè)程序可能有多個(gè)程序段,所以也就有多個(gè)“程序記錄”和程序段映象。bootloader必須知道fpga配置數(shù)據(jù)的長度以讀取配置數(shù)據(jù)后面的內(nèi)容,不同型號的fpga的配置數(shù)據(jù)長度是不同的,所以
8、必須讀取配置數(shù)據(jù)的頭部信息獲取配置數(shù)據(jù)的長度,進(jìn)而逐個(gè)讀取程序段映象的長度和運(yùn)行時(shí)地址,然后把程序段映象搬到目的運(yùn)行時(shí)地址。為了存取epcs,bootloader構(gòu)造了一些位置無關(guān)匯編代碼。epcs的存貯布局如下所示:剩余空間4字節(jié)的最后一個(gè)“程序記錄”的目的地址域a0x00000000,4字節(jié)的最后一個(gè)“程序記錄”的長度域lln個(gè)字節(jié)的第n個(gè)程序段映象4字節(jié)的第n個(gè)程序段的目的地址an4字節(jié)的第n個(gè)程序段的長度lnl2個(gè)字節(jié)的第2個(gè)程序段映象4字節(jié)的第2個(gè)程序段的目的地址a24字節(jié)的第2個(gè)程序段的長度l2length+8length+l+7l1字節(jié)的第1個(gè)程序段映象length+4lengt
9、h+74字節(jié)的第1個(gè)程序段目的地址a1lengthlength+34字節(jié)的第1個(gè)程序段長度l10length-1fpga配置數(shù)據(jù),長度為length當(dāng)bootloader讀取到l時(shí),l0,表示前面所有的程序記錄已經(jīng)處理完畢,這個(gè)是最后的程序記錄就直接跳到地址a的地方執(zhí)行。顯然a必須是程序的入口地址。如果l0xffffffff(即-1),那么就忽略a并停機(jī),這樣,即使是一個(gè)只有fpga配置數(shù)據(jù)而沒有程序的epcs也是安全的。當(dāng)一個(gè)epcs只有配置數(shù)據(jù)而沒有程序的時(shí)候,sof2flash會(huì)在配置數(shù)據(jù)的末尾增加4個(gè)字節(jié)的0xff使bootloader不會(huì)有誤動(dòng)作。bootloader的工作流程如下:
10、3.2 epcs控制器epcs控制器手冊沒有對epcs進(jìn)行詳細(xì)的說明只是建議用戶使用altera的hal函數(shù)來存取。其實(shí)epcs控制器由兩個(gè)獨(dú)立的部件構(gòu)成:1.rom。大小是512個(gè)字節(jié),也就是128 words。盡管epcs控制器手冊表述了rom的大小是1k字節(jié),實(shí)際上直到nios ii 5.1 epcs控制器的rom仍然是512個(gè)字節(jié),因此手冊中給出的寄存器偏移地址都需要修正。2.spi master控制器。epcs串行存貯器的接口符合spi標(biāo)準(zhǔn)。nios ii 可以通過spi master來存取epcs串行存貯器。這兩個(gè)部件的地址(從nios ii 的角度看,以字節(jié)為單位)安排如下:偏移
11、地址寄存器r/w位描述31.00x000boot rom memoryrboot loader code epcs_controller_boot_rom.hexor epcs_controller_boot_rom.dat0x0040x1fc0x200rx datar31.8 (not implemented)rx data(7.0)0x204tx dataw31.8 (not implemented)tx data(7.0)0x208statusr/w31.11109876543210eoperrdytrdytmttoeroe0x20ccotrolr/w31.11109876543210i
12、eopieirrdyitrdyitoeiroe0x210reserved-0x214slaver enabler/w31.161514133210ss_15ss_14ss_13ss_3ss_2ss_1ss_00x218end of packetr/w31.8 (not implemented)end of character(7.0)l rx data寄存器nios ii從rx data寄存器中讀出從epcs中接收到的數(shù)據(jù)。當(dāng)接收移位寄存器收到滿8位的數(shù)據(jù),status寄存器的rrdy位被置1,同時(shí)數(shù)據(jù)被傳入rx data寄存器。讀取rx data寄存器會(huì)把rrdy位清掉,而往rx data寫
13、則沒有影響。l tx data寄存器nios ii把要發(fā)送的數(shù)據(jù)寫到tx data寄存器。status寄存器中的trdy位置1表示tx data寄存器準(zhǔn)備好接收來自nios ii的新數(shù)據(jù)。tx data被寫了之后,trdy位就被置0,直到數(shù)據(jù)從tx data轉(zhuǎn)移到發(fā)送移位寄存器又會(huì)被重新置為1。l status寄存器status寄存器包含有指示當(dāng)前狀態(tài)的位。幾乎每一位都和control寄存器的一個(gè)中斷允許位相關(guān)。nios ii任何時(shí)候都可以讀取status寄存器,不會(huì)影響該寄存器的值。往status寄存器寫將清除roe,toe和e這些位。下表描述了各個(gè)位的含義:位名稱含義3roe接收溢出錯(cuò)誤。
14、當(dāng)rx data寄存器數(shù)據(jù)滿的時(shí)候(rrdy為1),接收移位寄存器又往rx data寄存器寫,那roe位將被置1。而新的數(shù)據(jù)會(huì)覆蓋老的數(shù)據(jù)。往status寄存器寫可以把roe位清0。4toe發(fā)送溢出錯(cuò)誤。如果tx data寄存器數(shù)據(jù)還沒有被轉(zhuǎn)移到發(fā)送移位寄存器(trdy為0),又往tx data寄存器寫,那toe就會(huì)被置為1。新的數(shù)被忽略。往status寄存器寫可以清toe為0。5tmt發(fā)送移位寄存器空。如果一個(gè)發(fā)送過程正在進(jìn)行中,那tmt為0;如果發(fā)送移位寄存器為空,則tmt為1。6trdy發(fā)送器準(zhǔn)備好接收新的發(fā)送數(shù)據(jù)。當(dāng)tx data寄存器空的時(shí)候,trdy為1。7rrdy接收器準(zhǔn)備好送出
15、接收到的數(shù)。當(dāng)rx data寄存器滿的時(shí)候,rrdy為1。8e有錯(cuò)誤產(chǎn)生。它是toe和roe的邏輯或。只要toe或roe中有一個(gè)為1,那它也為1。它給程序提供了一個(gè)判斷有錯(cuò)誤發(fā)生的方便的途徑。往status寄存器寫可以把e位清0。9eop包結(jié)束標(biāo)志。該標(biāo)志在下列情況下被置1:1. 一個(gè)eop字節(jié)被寫入tx data寄存器2. 一個(gè)eop字節(jié)從rx data寄存器中讀出eop字節(jié)就是end of packet寄存器中的end of character字節(jié)。往status寄存器寫可以把eop位清0。l control寄存器control寄存器控制spi master的操作。nios ii可以在任何
16、時(shí)候讀取control寄存器而不改變它的值。大部分control寄存器的位(iroe,itoe,itrdy,irrdy和ie)控制status寄存器相應(yīng)位的中斷。比如當(dāng)iroe設(shè)為1,就允許當(dāng)status中的roe為1時(shí)產(chǎn)生中斷。只有當(dāng)control寄存器和stauts寄存器中的相應(yīng)位都為1的情況下,spi master才會(huì)產(chǎn)生中斷。位名稱含義3iroe允許roe條件滿足時(shí)產(chǎn)生中斷。4itoe允許toe條件滿足時(shí)產(chǎn)生中斷。6itrdy允許trdy條件滿足時(shí)產(chǎn)生中斷。7irrdy允許rrdy條件滿足時(shí)產(chǎn)生中斷。8ie允許e條件滿足時(shí)產(chǎn)生中斷。9ieop允許eop條件滿足時(shí)產(chǎn)生中斷。10sso強(qiáng)制
17、slave enable寄存器器中為1的位對應(yīng)的ss_n有效,即輸出電平0。l slave enable寄存器slave enable寄存器中的某一位置1表示相應(yīng)的ss_n信號可以被驅(qū)動(dòng)有效(即在control寄存器中寫sso位為1,或者有數(shù)據(jù)寫入tx data寄存器準(zhǔn)備開始傳送數(shù)據(jù))。slave enable寄存器可以多位為1,但是需要有其它邏輯來處理多個(gè)spi slave的沖突問題。l end of packet寄存器end of packet寄存器包含end of character,當(dāng)某一avalon master讀出的rx data寄存器字節(jié)和end of character一樣,或
18、者寫入tx data的字節(jié)和end of character一樣時(shí),spi master產(chǎn)生eop標(biāo)志。如果該avalon master支持endofpacket信號,則會(huì)中斷傳輸。epcs控制器在例化spi master時(shí)使用下列參數(shù):數(shù)據(jù)位8位;spi時(shí)鐘sclk頻率20mhz;mosi(asdo)在sclk的下降沿處輸出;miso(data0)在sclk上升沿處采樣;sclk的初始相位為0;msb先輸出,lsb后輸出;目標(biāo)延遲100us(即ss_n輸出為低到sclk開始驅(qū)動(dòng)輸出時(shí)鐘脈沖的延遲為100us)。3.3 epcs串行存貯器件altera的器件手冊對epcs器件有完整清楚的表述。
19、在read byte,read status和read silicon id操作時(shí),發(fā)出命令后,所要的數(shù)據(jù)會(huì)馬上從epcs的data管腿移出。所以epcs控制在發(fā)出命令后繼續(xù)發(fā)送虛擬數(shù)據(jù)(比如0或隨便什么值),在發(fā)送虛擬數(shù)據(jù)的同時(shí)接收epcs送出的數(shù)據(jù),就可以獲取所要的數(shù)據(jù)。spi接口的發(fā)送和接收是同時(shí)的,為了接收數(shù)據(jù),你必須發(fā)送點(diǎn)什么,盡管這些數(shù)據(jù)是對方不需要的,同樣在你發(fā)送命令或數(shù)據(jù)的同時(shí)也會(huì)收到點(diǎn)什么,盡管這些也不一定是你需要的。4 從并行flash中boot4.1 并行flash配置控制器nios ii應(yīng)用常常把nios ii 程序和fpga配置數(shù)據(jù)都存放在flash中。這就需要一個(gè)配
20、置控制器來驅(qū)動(dòng)flash輸出配置數(shù)據(jù)完成fpga的配置。配置控制器可以用一片cpld來實(shí)現(xiàn)。flash除了可以存貯fpga配置數(shù)據(jù)和nios ii程序外還可以存貯其它數(shù)據(jù)(比如只讀文件系統(tǒng))。flash中的配置數(shù)據(jù)區(qū)還可以分為兩個(gè)區(qū),一個(gè)用于用戶邏輯,另一個(gè)用于出廠邏輯。當(dāng)用戶邏輯配置失敗后,就會(huì)自動(dòng)使用出廠邏輯,保證任何時(shí)候都有一個(gè)配置可以工作。另外,配置控制器還可以接收來自nios ii 的重配置請求,并驅(qū)動(dòng)fpga重新配置,完成fpga的現(xiàn)場升級。stratix開發(fā)板的配置控制安排偏移量為0的地方存放nios ii程序,而fpga用戶配置邏輯從偏移量0x600000開始,出廠配置則從偏移
21、量0x700000開始。stratix開發(fā)板的并行flash配置控制器其實(shí)是一個(gè)地址序列生成器,地址生成器的輸入時(shí)鐘是板上時(shí)鐘的4分頻(比如,板上的晶振時(shí)鐘是50mhz,則地址生成器的時(shí)鐘就是12.5mhz)。上電的時(shí)候,由上電復(fù)位芯片提供的復(fù)位信號復(fù)位,地址生成器初始化為用戶邏輯的配置數(shù)據(jù)的偏移量(比如stratix板是0x600000),然后開始計(jì)數(shù)并驅(qū)動(dòng)地址由低往高增長,使flash送出對應(yīng)地址的配置數(shù)據(jù)。配置控制器監(jiān)測fpga的config_done信號,一旦發(fā)現(xiàn)fpga配置完成就停止計(jì)數(shù),并置flash的地址和其它控制線為高阻,以免影響nios ii對flash的操作。fpga配置完
22、成后,內(nèi)部邏輯開始生效,復(fù)位nios ii,nios ii開始從reset地址執(zhí)行程序。4.2 直接在flash中運(yùn)行程序嵌入式應(yīng)用有時(shí)希望程序能夠直接在flash中運(yùn)行,以節(jié)約ram空間,降低成本。為了使程序直接在flash中運(yùn)行,可以在sopc builder中設(shè)置reset地址在flash中,連接程序的時(shí)候可以指定程序的.text段和.rodata段存放在flash中,而讓.rwdata和堆棧放在ram中(這2個(gè)段都是可讀寫的,不能放在flash中)。同時(shí)還可以在sopc builder中指定exception地址到flash中,也可以節(jié)約一點(diǎn)ram空間。由于最后的flash映象文件.f
23、lash文件(.flash文件其實(shí)是.srec格式的文件)中沒有bss段,所以程序的開始必須在ram中建立bss段并清0,同時(shí)也把.rwdata段從flash中拷貝到ram中(.rwdata段在程序運(yùn)行的時(shí)候必須在ram中),并設(shè)置好棧,建立好c程序的工作環(huán)境然后調(diào)用c用戶入口函數(shù)。這些工作都是由crt0.s來完成的。下面是crt0.s在flash中運(yùn)行的工作流程:4.3 在ram中運(yùn)行程序程序在flash運(yùn)行通常比在ram中慢,所以有時(shí)也希望程序能夠在ram中運(yùn)行。nios ii的reset地址仍然指向flash中(reset地址不能指向ram,ram在上電復(fù)位時(shí)還沒有被初始化),在連接程序
24、的時(shí)候可以把每個(gè)段都指定到ram中,在sopc builder中也可以把exception部分指定到ram中。這樣連接生成的可執(zhí)行文件.elf文件就是適合在ram中運(yùn)行的程序。但在實(shí)際應(yīng)用中這個(gè)程序最終存放在flash中,所以需要有一段bootloader代碼,用于把flash中的程序映象拷貝到ram中運(yùn)行。工具elf2flash能夠根據(jù)情況自動(dòng)給你的程序在生成.flash文件時(shí)添加“程序記錄”和bootloader。elf2flash判斷其后隨參數(shù)reset地址(就是nios ii的reset地址)和程序的入口地址是不是一樣,如果一樣就不添加“程序記錄”和bootloader,如果不一樣就添
25、加。這個(gè)bootloader根據(jù)各個(gè)“程序記錄”把程序映象拷貝到到ram中并從ram中執(zhí)行。和epcs一樣,每個(gè)“程序記錄”由兩個(gè)32位的數(shù)據(jù)組成,一個(gè)是程序的長度,一個(gè)目的執(zhí)行地址(即程序的運(yùn)行地址)。stratix 開發(fā)板上flash中的存貯分布如下:0x7000000x7fffff出廠邏輯safe logic0x6000000x6fffff用戶邏輯user logic剩余空間4字節(jié)的最后一個(gè)“程序記錄”的目的地址域a0x00000000,4字節(jié)的最后一個(gè)“程序記錄”長度域lln個(gè)字節(jié)的第n個(gè)程序段映象4字節(jié)的第n個(gè)程序段的目的地址an4字節(jié)的第n個(gè)程序段的長度lnl2個(gè)字節(jié)的第2個(gè)程序段
26、映象4字節(jié)的第2個(gè)程序段的目的地址a24字節(jié)的第2個(gè)程序段的長度l2length+8length+l+7l1字節(jié)的第1個(gè)程序段映象length+4length+74字節(jié)的第1個(gè)程序段的目的地址a1lengthlength+34字節(jié)的第1個(gè)程序段的長度l10length-1bootloaderbootloader的工作流程如下:運(yùn)行完bootloader后仍然要執(zhí)行crt0.s,但此時(shí)crt0.s的流程和程序在flash中直接運(yùn)行的情況有一些區(qū)別:它沒有初始化指令cache,也不會(huì)企圖去裝載別的段,這些步驟已經(jīng)在bootloader中完成。程序映象已經(jīng)包含這些段,在搬移程序映象的同時(shí)也裝載了相應(yīng)
27、的段(.rodata段,.rwdata段和.exceptions段),程序映象中不包含.bss段和棧,所以仍然需要清.bss段以及設(shè)置棧指針和全局指針。bootloader沒有存取存貯器數(shù)據(jù),因此沒有初始化數(shù)據(jù)cache,所以crt0.s仍然要初始化數(shù)據(jù)cache。5 bootloader解讀altera提供了兩個(gè)bootloader程序,一個(gè)用于從epcs器件中boot,另一個(gè)用于從flash器件中boot。它們的匯編源碼和makefile都在c:alterakits ios2_51componentsaltera_nios2sdksrcoot_loader_sources目錄中。其中boo
28、t_loader.s是公共部分,而boot_loader_epcs_bits.s則用于從epcs器件中boot,boot_loader_cfi_bits.s用于從flash中boot。5.1 boot_loader.s解讀#ifdef epcs #define find_payload sub_find_payload_epcs/ 查找epcs中數(shù)據(jù)負(fù)荷子程序 #define read_int sub_read_int_from_flash_epcs/ 從epcs中讀取一個(gè)32位word #define streaming_copy sub_streaming_copy_epcs/ 從epcs
29、中拷貝流的子程序 #define close_device sub_epcs_close/ 關(guān)閉epcs器件的子程序#else #define find_payload sub_find_payload_cfi/ 查找cfi并行flash中數(shù)據(jù)負(fù)荷的子程序 #define read_int sub_read_int_from_flash_cfi/ 從cfi并行flash中讀取一個(gè)32位的word #define streaming_copy sub_streaming_copy_cfi/ 從cfi并行flash中拷貝流的子程序#endif#include boot_loader.h .glob
30、al reset .global _start .global main .global end_of_boot_copierreset:_start:main: / 清除cpu的狀態(tài)寄存器禁止中斷,這個(gè)動(dòng)作在硬件復(fù)位的時(shí)候其實(shí)已經(jīng)自動(dòng)完成。. wrctl status, r_zero / 沖刷指令cache. / nios ii 最多支持64kbytes的指令cache,所以只初始化了64kbytes的指令cache movhi r_flush_counter,%hi(0x10000)cache_loop: initi r_flush_counter / 沒有必要初始化數(shù)據(jù)cache, bo
31、otloader不存取存貯器數(shù)據(jù) addi r_flush_counter, r_flush_counter,-32 bne r_flush_counter, r_zero, cache_loop / 沖刷流水線 flushp / r_flash_ptr = find_payload(); / 調(diào)用查找數(shù)據(jù)負(fù)荷子程序?qū)ふ覕?shù)據(jù)負(fù)荷 nextpc return_address_less_4 br find_payload / 拷貝. / / 在循環(huán)的開始,寄存器r_flash_ptr 包含“程序記錄”的地址。 / / 1) 讀取“程序記錄”的長度域(4-bytes)(r_data_size) /
32、2) 讀取“程序記錄”的目的地址域(4-bytes)(r_dest) / 3) 循環(huán): / 拷貝 r_data_size 個(gè)字節(jié), 一次一個(gè)字節(jié): *r_dest+ = *r_flash_ptr+ / 把0xffffffff裝入r_halt_record,用于測試是否要停機(jī)。 subi r_halt_record, r_zero, 1per_record_loop: /讀取“程序記錄”的長度域,r_data_size = read_int(r_flash_ptr+)。 nextpc return_address_less_4 br read_int mov r_data_size, r_rea
33、d_int_return_value / 讀取“程序記錄”的目的地址域,r_dest = read_int(r_flash_ptr+)。 nextpc return_address_less_4 br read_int mov r_dest, r_read_int_return_value / 測試長度域是否為0 / 如果是就直接運(yùn)行程序 beq r_data_size, r_zero, last_program_record / 如果長度域?yàn)?1(0xffffffff),就停機(jī)。halt_record_forever: beq r_data_size, r_halt_record, halt
34、_record_forever / 使用拷貝流子程序搬移數(shù)據(jù) nextpc return_address_less_4 br streaming_copy / 程序運(yùn)行到這里,表明已經(jīng)處理了當(dāng)前的“程序記錄”了, / 而且知道這不是最后一個(gè)“程序記錄”因?yàn)樗拈L度域不為0, / 這就意味著要處理下一個(gè)“程序記錄”。 br per_record_looplast_program_record: / 處理完最后一個(gè)程序記錄后就要把控制權(quán)轉(zhuǎn)給實(shí)際的運(yùn)行程序. / r_dest是實(shí)際程序的入口地址 / 在中止boot-loader之前要關(guān)閉epcs器件,如果不做這一步, / 會(huì)導(dǎo)致hal的open()
35、調(diào)用要花好幾秒鐘才能打開epcs器件#ifdef epcs nextpc return_address_less_4 br close_device#endif / 跳轉(zhuǎn)到目的地址運(yùn)行程序 callr r_destafterlife: / 程序跑到這里表明有問題。 br afterlife .end5.2 boot_loader_epcs_bits.s解讀/ 從epcs串行flash設(shè)備讀取字節(jié)的子過程/ 通過寄存器和epcs打交道獲取字節(jié)數(shù)#include boot_loader.h .global sub_find_payload_epcs .global sub_read_int_fro
36、m_flash_epcs .global sub_streaming_copy_epcs .global sub_epcs_close/ epcs控制和狀態(tài)寄存器的偏移量#define epcs_rxdata_offset 0x00#define epcs_txdata_offset 0x04#define epcs_status_offset 0x08#define epcs_control_offset 0x0c/ epcs的位掩碼#define epcs_status_tmt_mask 0x20#define epcs_status_trdy_mask 0x40#define epcs_
37、status_rrdy_mask 0x80#define epcs_control_sso_mask 0x400/ epcs命令#define epcs_command_read 0x03 .text/ 查找epcs的數(shù)據(jù)負(fù)荷/ 過程:/ - 在偏移量為0的地方打開epcs器件(fpga配置數(shù)據(jù)在這里)/ - 分析配置數(shù)據(jù)獲取數(shù)據(jù)負(fù)荷開始的地址/ - 關(guān)閉epcs/ - 在數(shù)據(jù)負(fù)荷的開始的地址再次打開epcs/sub_find_payload_epcs: / 修正并存貯返回地址 addi r_findp_return_address, return_address_less_4, 4 / /
38、計(jì)算epcs控制/狀態(tài)寄存器塊的地址 / 它在離本段代碼的開頭偏移量為512個(gè)字節(jié)的地方 / 因?yàn)檫@段代碼必須在512字節(jié)邊界處, / 我們簡單地把當(dāng)前地址園整到下一個(gè)512個(gè)地址的邊界。 / / | / | 為了調(diào)試,你可以定義epcs_regs_base / | 作為epcs寄存器基地址。否則就假設(shè)下一個(gè)512字節(jié)邊界。 / | nextpc r_findp_temp#ifdef epcs_regs_base movhi r_epcs_base_address, %hi(epcs_regs_base) addi r_epcs_base_address, r_epcs_base_addres
39、s, %lo(epcs_regs_base)#else ori r_epcs_base_address, r_findp_temp, 511 addi r_epcs_base_address, r_epcs_base_address, 1#endif / / 在偏移量為0的地方打開epcs器件 / movi r_flash_ptr, 0 nextpc return_address_less_4 br sub_epcs_open_address / / 分析器件配置數(shù)據(jù)順序讀出字節(jié)直到下面任一個(gè)條件滿足 / 1) 我們找到0xa6 (其實(shí)應(yīng)該是0x56,因?yàn)槲覀儧]有把位序顛倒過來) / 當(dāng)我們找
40、到它時(shí)表示我們找到配置數(shù)據(jù),可以接著算出它的長度。 / 2) 我們找到不是xff字節(jié),在這種情況我們根本沒有在配置數(shù)據(jù)里查找 / 我們假定我一定是在一個(gè)boot loader記錄。跳過整個(gè)配置數(shù)據(jù)長度的計(jì)算 / 開始裝載。 / 3) 我們在任意長的時(shí)間內(nèi)找到的都是0xff。我們猜測flash是空的沒有其它可利用資源 / / 搜索隨意的一大塊字節(jié) movi r_findp_count, 0x400 / 我們要找的模板是0x56 movi r_findp_pattern, 0x56 / 在我們找到0x56之前唯一可以接受的字節(jié)是0xff movi r_findp_temp, 0xfffp_look
41、_for_56_loop: nextpc return_address_less_4 br sub_read_byte_from_flash_epcs / 我們發(fā)現(xiàn)模板了嗎? beq r_read_byte_return_value, r_findp_pattern, fp_found_sync / 我們發(fā)現(xiàn)非0xff的字節(jié)了嗎? bne r_read_byte_return_value, r_findp_temp, fp_short_circuit / 更新循環(huán)計(jì)數(shù)器開始循環(huán) subi r_findp_count, r_findp_count, 1 bne r_findp_count, r_
42、zero, fp_look_for_56_loop / 我們沒有找到模板或其它匹配的字節(jié),掛起。 / 先關(guān)閉epcs器件 nextpc return_address_less_4 br sub_epcs_closefp_hang: br fp_hangfp_found_sync: / 同步模板后面緊跟著的4個(gè)字節(jié)是我們感興趣 nextpc return_address_less_4 br sub_read_int_from_flash_epcs / 這4個(gè)字節(jié)是配置的長度,它們的字節(jié)順序是little-endian,但位序是反的。 nextpc return_address_less_4 br
43、 sub_read_int_from_flash_epcs / 把長度放到r_flash_ptr 中 mov r_flash_ptr, r_read_int_return_value / 此時(shí)我們獲得了長度但是在epcs器件中quarts / 以相反的位序存貯字節(jié) / / 我們先把4位組反過來,再把2位組反過來,然后再把所有的位反過來。 / 就象這樣: / / 76543210 4位組反序- 32107654 兩位組反序 - 10325476 位反序 - 01234567 / / 下面是整個(gè)循環(huán)的進(jìn)行機(jī)制 / 你會(huì)注意到這個(gè)反序過程只展示了一次 / 不用擔(dān)心,所有的字節(jié)都會(huì)被反序 / / (x
44、 = unknown, . = zero) / / byte temp mask count / - - - - / 初始態(tài) 76543210 xxxxxxxx 00001111 4 / / 1 temp = byte & mask 76543210 .3210 00001111 4 / 2 temp = count xxxx7654 3210. 00001111 4 / 4 byte &= mask .7654 3210. 00001111 4 / 5 byte |= temp 32107654 3210. 00001111 4 / 6 count = 1 32107654 3210. 00
45、001111 2 / 7 temp = mask count 32107654 00111100 00001111 2 / 8 mask = temp 32107654 00111100 00110011 2 / / loop on (count != 0) / / temp = byte & mask 32107654 .10.54 00110011 2 / temp = count xx321076 10.54. 00110011 2 / byte &= mask .32.76 10.54. 00110011 2 / byte |= temp 10325476 10.54. 0011001
46、1 2 / count = 1 10325476 10.54. 00110011 1 / temp = mask count 10325476 01100110 00110011 1 / mask = temp 10325476 01100110 01010101 1 / / loop on (count != 0) / / temp = byte & mask 10325476 .0.2.4.6 01010101 1 / temp = count x1032547 0.2.4.6. 01010101 1 / byte &= mask .1.3.5.7 0.2.4.6. 01010101 1
47、/ byte |= temp 01234567 0.2.4.6. 01010101 1 / count = 1 01234567 0.2.4.6. 01010101 0 / temp = mask count 01234567 01010101 01010101 0 / mask = temp 01234567 01010101 00000000 0 / / 初始化mask movhi r_revbyte_mask, 0x0f0f addi r_revbyte_mask, r_revbyte_mask, 0x0f0f / 裝入count movi r_findp_count, 4fp_reve
48、rse_loop: / 屏蔽高一半的位把結(jié)果裝入temp寄存器 and r_findp_temp, r_flash_ptr, r_revbyte_mask / 1 / 把temp中的位左移4位 sll r_findp_temp, r_findp_temp, r_findp_count / 2 / 把ptr中字節(jié)右移4位 srl r_flash_ptr, r_flash_ptr, r_findp_count / 3 / 屏蔽掉高4位 and r_flash_ptr, r_flash_ptr, r_revbyte_mask / 4 / 把ptr和temp中的位組合起來 or r_flash_ptr, r_flash_ptr, r_findp_temp / 5 / 更新移位計(jì)數(shù)器 srli r_findp_count, r_findp_count, 1 / 6 / 左移mask 2位 sll r_findp_temp, r_re
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 浙江省金華市東陽中學(xué)2025屆高三第一次調(diào)研測試語文試卷含解析
- 11.1《過秦論》課件 2024-2025學(xué)年統(tǒng)編版高中語文選擇性必修中冊-1
- 2025屆湖南省邵東縣創(chuàng)新實(shí)驗(yàn)學(xué)校高三壓軸卷語文試卷含解析
- 《solidworks 機(jī)械設(shè)計(jì)實(shí)例教程》 課件 任務(wù)2.2 支架草圖的設(shè)計(jì)
- 廣州黃埔區(qū)第二中學(xué)2025屆高三沖刺模擬語文試卷含解析
- 2025屆四川省南充市高三第二次聯(lián)考英語試卷含解析
- 2025屆四川省蓉城名校高三最后一卷語文試卷含解析
- 廣東東莞外國語學(xué)校2025屆高三第六次模擬考試語文試卷含解析
- 哈爾濱市第九中學(xué)2025屆高三最后一模英語試題含解析
- 2025屆廣東省肇慶聯(lián)盟校高三第三次測評語文試卷含解析
- 小學(xué)生體檢表1頁
- 上級建設(shè)政府部門檢查監(jiān)理公司用表
- 糖尿病 第九版內(nèi)科學(xué)
- 市政工程溝槽開挖與回填自動(dòng)計(jì)算表
- 濱江大道西段污水管道施工工程施工組織設(shè)計(jì)
- 電熱水器澳洲標(biāo)準(zhǔn)中文版(doc 83頁)
- 第二章珠江水系
- 牛頭刨床說明書
- SJ8002B電子測量原理實(shí)驗(yàn)指導(dǎo)書(V3.1)
- 《解析幾何》教案
- CJJ_T134-2019建筑垃圾處理技術(shù)標(biāo)準(zhǔn)
評論
0/150
提交評論