ARM的位置在Bootloader中的應(yīng)用_第1頁
ARM的位置在Bootloader中的應(yīng)用_第2頁
ARM的位置在Bootloader中的應(yīng)用_第3頁
ARM的位置在Bootloader中的應(yīng)用_第4頁
ARM的位置在Bootloader中的應(yīng)用_第5頁
已閱讀5頁,還剩16頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、ARM的位置在Bootloader中的應(yīng)用引言1 位置無關(guān)代碼及程序設(shè)計(jì)方法1.1 基本概念與實(shí)現(xiàn)原理1.2 arm處理器的位置無關(guān)程序設(shè)計(jì)要點(diǎn)(1) 程序設(shè)計(jì)規(guī)范(2) 程序設(shè)計(jì)規(guī)范22 位置無關(guān)代碼在Bootloader設(shè)計(jì)中的應(yīng)用使用位置無關(guān)設(shè)計(jì)Bootloader程序有如下優(yōu)點(diǎn):3 結(jié)論arm處理器支支持位置置無關(guān)的的程序設(shè)設(shè)計(jì),這這種程序序加載到到存儲(chǔ)器器的任意意地址空空間都可可以正常常運(yùn)行,其設(shè)計(jì)計(jì)方法在在嵌入式式應(yīng)用系系統(tǒng)開發(fā)發(fā)中具有有重要的的作用。本文首首先介紹紹位置無無關(guān)代碼碼的基本本概念和和實(shí)現(xiàn)原原理,然然后闡述述基于arm匯編位置置無關(guān)的的程序設(shè)設(shè)計(jì)方法法和實(shí)現(xiàn)現(xiàn)過程,最

2、后以以嵌入式式Bootloader程序設(shè)計(jì)計(jì)為例,介紹位位置無關(guān)關(guān)程序設(shè)設(shè)計(jì)在Bootloader程序設(shè)計(jì)計(jì)中的作作用?;谖恢弥脽o關(guān)代代碼PIC(PositionIndependentCode)的程序序設(shè)計(jì)在在嵌入式式應(yīng)用系系統(tǒng)開發(fā)發(fā)中具有有重要的的作用,尤其在在裸機(jī)狀狀態(tài)下開開發(fā)Bootloader程序及進(jìn)進(jìn)行內(nèi)核核初始化化設(shè)計(jì);利用位位置無關(guān)關(guān)的程序序設(shè)計(jì)方方法還可可以在具具體應(yīng)用用中用于于構(gòu)建高高效率動(dòng)動(dòng)態(tài)鏈接接庫,因因而深入入理解和和熟練掌掌握位置置無關(guān)的的程序設(shè)設(shè)計(jì)方法法,有助助于開發(fā)發(fā)人員設(shè)設(shè)計(jì)出結(jié)結(jié)構(gòu)簡單單、清晰晰的應(yīng)用用程序。本文首首先介紹紹位置無無關(guān)代碼碼的基本本概念和和實(shí)

3、現(xiàn)原原理,然然后闡述述基于arm匯編位置置無關(guān)的的程序設(shè)設(shè)計(jì)方法法和實(shí)現(xiàn)現(xiàn)過程,最后以以Bootloader程序設(shè)計(jì)計(jì)為例,介紹了了位置無無關(guān)程序序設(shè)計(jì)在在Bootloader程序設(shè)計(jì)計(jì)中的作作用。引言1.1基本概念念與實(shí)現(xiàn)現(xiàn)原理應(yīng)用程序序必須經(jīng)經(jīng)過編譯譯、匯編編和鏈接接后才變變成可執(zhí)執(zhí)行文件件,在鏈鏈接時(shí),要對所所有目標(biāo)標(biāo)文件進(jìn)進(jìn)行重定定位(relocation),建立符符號引用用規(guī)則,同時(shí)為為變量、函數(shù)等等分配運(yùn)運(yùn)行地址址。當(dāng)程程序執(zhí)行行時(shí),系系統(tǒng)必須須把代碼碼加載到到鏈接時(shí)時(shí)所指定定的地址址空間,以保證證程序在在執(zhí)行過過程中對對變量、函數(shù)等等符號的的正確引引用,使使程序正正常運(yùn)行行。在具

4、具有操作作系統(tǒng)的的系統(tǒng)中中,重定定位過程程由操作作系統(tǒng)自自動(dòng)完成成。在設(shè)計(jì)Bootloader程序時(shí),必須在在裸機(jī)環(huán)環(huán)境中進(jìn)進(jìn)行,這這時(shí)Bootloader映像文件件的運(yùn)行行地址必必須由程程序員設(shè)設(shè)定。通通常情況況下,將將Bootloader程序下載載到ROM的0 x0地址進(jìn)行行啟動(dòng),而在大大多數(shù)應(yīng)應(yīng)用系統(tǒng)統(tǒng)中,為為了快速速啟動(dòng),首先將將Bootloader程序拷貝貝到SDRAM中再運(yùn)行行。一般般情況下下,這兩兩者的地地址并不不相同,程序在在SDRAM中的地址址重定位位過程必必須由程程序員完完成。實(shí)實(shí)際上,由于Bootloader是系統(tǒng)上上電后要要執(zhí)行的的第一段段程序,Bootloader程序

5、的拷拷貝和在在這之前前的所有有工作都都必須由由其自身身來完成成,而這這些指令令都是在在ROM中執(zhí)行的的。也就就是說,這些代代碼即使使不在鏈鏈接時(shí)所所指定的的運(yùn)行時(shí)時(shí)地址空空間,也也可以正正確執(zhí)行行。這就就是位置置無關(guān)代代碼,它它是一段段加載到到任意地地址空間間都能正正常執(zhí)行行的特殊殊代碼。1位置無關(guān)關(guān)代碼及及程序設(shè)設(shè)計(jì)方法法 程序序在運(yùn)行行期間動(dòng)動(dòng)態(tài)加載載到內(nèi)存存; 程序序在不同同場合與與不同程程序組合合后加載載到內(nèi)存存(如共享的的動(dòng)態(tài)鏈鏈接庫); 在運(yùn)運(yùn)行期間間不同地地址相互互之間的的映射(如Bootloader程序)。雖然在用用GCC編譯時(shí),使用-fPIC選項(xiàng)可為為C語言產(chǎn)生生位置無無關(guān)代

6、碼碼,但這這并不能能修正程程序設(shè)計(jì)計(jì)中固有有的位置置相關(guān)性性缺陷。特別是是匯編語語言代碼碼,必須須由程序序員遵循循一定的的程序設(shè)設(shè)計(jì)準(zhǔn)則則,才能能保證程程序的位位置無關(guān)關(guān)性。位置無關(guān)關(guān)代碼常常用于以以下場合合:arm程序的位位置無關(guān)關(guān)可執(zhí)行行文件PIE(PositionIndependent Executable)包括位位置無關(guān)關(guān)代碼PIC和位置無無關(guān)數(shù)據(jù)據(jù)PID(PositionIndependent Data)兩部分分。PID主要針對對可讀寫寫數(shù)據(jù)段段(.data段),其其中保存存已賦初初值的全全局變量量。為實(shí)實(shí)現(xiàn)其位位置無關(guān)關(guān)性,通通常使用用寄存器器R9作為靜態(tài)態(tài)基址寄寄存器,使其指指向

7、該可可讀寫段段的首地地址,并并使用相相對于基基址寄存存器的偏偏移量來來對該段段的變量量進(jìn)行尋尋址。這這種方法法常用于于為可重重入程序序的多個(gè)個(gè)實(shí)例產(chǎn)產(chǎn)生多個(gè)個(gè)獨(dú)立的的數(shù)據(jù)段段。在程程序設(shè)計(jì)計(jì)中,一一般不必必考慮可可讀寫段段的位置置無關(guān)性性,這主主要是因因?yàn)榭勺x讀寫數(shù)據(jù)據(jù)主要分分配在SDRAM中。1.2arm處理器的的位置無無關(guān)程序序設(shè)計(jì)要要點(diǎn)PIC包括程序序中的代代碼和只只讀數(shù)據(jù)據(jù)(.text段),為為保證程程序能在在ROM和SDRAM空間都能能正確運(yùn)運(yùn)行(如如裸機(jī)狀狀態(tài)下的的Bootloader程序),必須采采用位置置無關(guān)代代碼程序序設(shè)計(jì)。下面重重點(diǎn)介紹紹PIC的程序設(shè)設(shè)計(jì)要點(diǎn)點(diǎn)。PIC遵循

8、只讀讀段位置置無關(guān)ROPI(ReadOnlyPositionIndependence)的ATPCS(armThumbProcedureCallStandard)的程序序設(shè)計(jì)規(guī)規(guī)范:引用同一一ROPI段或相對對位置固固定的另另一ROPI段中的符符號時(shí),必須是是基于PC的符號引引用,即即使用相相對于當(dāng)當(dāng)前PC的偏移量量來實(shí)現(xiàn)現(xiàn)跳轉(zhuǎn)或或進(jìn)行常常量訪問問。 位置置無關(guān)的的程序跳跳轉(zhuǎn)。在在arm匯編程序序中,使使用相對對跳轉(zhuǎn)指指令B/BL實(shí)現(xiàn)程序序跳轉(zhuǎn)。指令中中所跳轉(zhuǎn)轉(zhuǎn)的目標(biāo)標(biāo)地址用用基于當(dāng)當(dāng)前PC的偏移量量來表示示,與鏈鏈接時(shí)分分配給地地址標(biāo)號號的絕對對地址值值無關(guān),因而代代碼可以以在任何何位置進(jìn)進(jìn)行

9、跳轉(zhuǎn)轉(zhuǎn),實(shí)現(xiàn)現(xiàn)位置無無關(guān)性。另外,還還可使用用ADR或ADRL偽指令將將地址標(biāo)標(biāo)號值讀讀取到PC中實(shí)現(xiàn)程程序跳轉(zhuǎn)轉(zhuǎn)。這是是因?yàn)锳DR或ADRL等偽指令令會(huì)被編編譯器替替換為對對基于PC的地址值值進(jìn)行操操作,但但這種方方式所能能讀取的的地址范范圍較小小,并且且會(huì)因地地址值是是否為字字對齊而而異。但但在在arm程序中,使用LDR等指令直直接將地地址標(biāo)號號值讀取取到PC中實(shí)現(xiàn)程程序跳轉(zhuǎn)轉(zhuǎn)不是位位置無關(guān)關(guān)的。(1) 程序序設(shè)計(jì)規(guī)規(guī)范例如:LDRPC,=main上面的LDR匯編偽指指令編譯譯后的結(jié)結(jié)果為:LDRPC,PC,OFFSET_TO_LPOOLLPOOLDCDmain可見,雖雖然LDR是把基于于

10、PC的一個(gè)存存儲(chǔ)單元元LPOOL的內(nèi)容加加載到PC中,但該該存儲(chǔ)單單元中保保存的卻卻是鏈接接時(shí)所決決定的main函數(shù)入口口的絕對對地址,所以main函數(shù)實(shí)際際所在的的段不是是位置無無關(guān)。 位置置無關(guān)的的常量訪訪問。在在應(yīng)用程程序中,經(jīng)常要要讀寫相相關(guān)寄存存器以完完成必要要的硬件件初始化化。為增增強(qiáng)程序序的可讀讀性,利利用EQU偽指令對對一些常常量進(jìn)行行賦值,但在訪訪問過程程中,必必須實(shí)現(xiàn)現(xiàn)位置無無關(guān)性。下面以以PXA270的GPIO初始化介介紹位置置無關(guān)的的常量訪訪問方法法。GPIO_BASEEQU0 x40e00000;GPIO基址寄存存器地址址GPDR0EQU0 x00c;相對于GPIO基

11、址寄存存器的偏偏移量init_GPDR0EQU0 xfffbfe00;寄存器GPDR0初值LDRR1,=GPIO_BASELDRR0,=init_GPDR0STRR0,R1,#GPDR0上述匯編編代碼段段經(jīng)編譯譯后的結(jié)結(jié)果為:LDRR1,PC,OFFSET_TO_GPIO_BASELDRR0,PC,OFFSET_TO_init_GPDR0STRR0,R1,#0 xcGPIO_BASEDCD0 x40e00000GPDR0DCD0 x00cinit_GPDR0DCD0 xfffbfe00可見,LDR偽指令實(shí)實(shí)際上使使用基于于PC的偏移量量來對符符號常量量GPIO_BASE和init_GPDR0進(jìn)

12、行引用用,因而而是位置置無關(guān)的的。由此此可以得得出如下下結(jié)論:使用LDR偽指令將將一個(gè)常常量讀取取到非PC的其他通通用寄存存器中可可實(shí)現(xiàn)位位置無關(guān)關(guān)的常量量訪問;但將一一個(gè)地址址值讀取取到PC中進(jìn)行程程序跳轉(zhuǎn)轉(zhuǎn)時(shí),跳跳轉(zhuǎn)目標(biāo)標(biāo)則是位位置相關(guān)關(guān)的。其他被ROPI段中的代代碼引用用的必須須是絕對對地址,或者是是基于可可讀寫位位置無關(guān)關(guān)(RWPI)段的靜態(tài)態(tài)基址寄寄存器的的可寫數(shù)數(shù)據(jù)。使用絕對對地址只只能引用用被重定定位到特特定位置置的代碼碼段中的的符號,通過在在位置無無關(guān)代碼碼中引入入絕對地地址,可可以讓程程序跳轉(zhuǎn)轉(zhuǎn)到指定定位置。例如,假設(shè)Bootloader的階段1將其自身身代碼拷拷貝到鏈鏈接時(shí)

13、所所指定的的SDRAM地址空間間后,當(dāng)當(dāng)要跳轉(zhuǎn)轉(zhuǎn)到階段段2的C程序入口口時(shí),可可以使用用指令“LDRPC, =main”跳轉(zhuǎn)到程程序在SDRAM中的main函數(shù)入口口地址開開始執(zhí)行行。這是是因?yàn)槌坛绦蛟诰幘幾g鏈接接時(shí)給main函數(shù)分派派絕對地地址,系系統(tǒng)通過過將main函數(shù)的絕絕對地址址直接賦賦給PC實(shí)現(xiàn)程序序跳轉(zhuǎn)。如果使使用相對對跳轉(zhuǎn)指指令“Bmain”,那么只只會(huì)跳轉(zhuǎn)轉(zhuǎn)到啟動(dòng)動(dòng)ROM內(nèi)部的main函數(shù)入口口。(2) 程序序設(shè)計(jì)規(guī)規(guī)范2在使用GNU工具開發(fā)發(fā)Bootloader時(shí),程序序在鏈接接時(shí)會(huì)通通過一個(gè)個(gè)鏈接腳腳本(linkerscript)來設(shè)定定映像文文件的內(nèi)內(nèi)存映射射。一個(gè)個(gè)簡單

14、的的鏈接腳腳本結(jié)構(gòu)構(gòu)如下:OUTPUT_ARCH(arm)ENTRY(_start)SECTIONS. =BOOTADDR;/*Bootloader的起始地地址*/_boot_start=.;.textALIGN(4):/*代碼段.text*/*(.text)2位置無關(guān)關(guān)代碼在在Bootloader設(shè)計(jì)中的的應(yīng)用.dataALIGN(4):/*數(shù)據(jù)段.data*/*(.data).gotALIGN(4): /*全局偏移移量表.got段*/*(.got)_boot_end =.;/*Bootloader映像文件件的結(jié)束束地址*/.bssALIGN(16):/*堆棧段.bss*/_bss_star

15、t= .;*(.bss)_bss_end=.;這里不再再介紹鏈鏈接腳本本的語法法。需要要指出的的是,鏈鏈接腳本本中所描描述的輸輸出段地地址為虛虛擬地址址VMA(Virtual MemoryAddress)。這里里的“虛擬地址址”僅指映像像文件執(zhí)執(zhí)行時(shí),各輸出出段所重重定位到到相應(yīng)的的存儲(chǔ)地地址空間間,與內(nèi)內(nèi)存管理理無關(guān)。因此,上面的的鏈接腳腳本實(shí)際際上指定定了Bootloader映像在執(zhí)執(zhí)行時(shí),將被重重定位到到BOOTADDR開始的存存儲(chǔ)地址址空間,以保證證在相關(guān)關(guān)位置對對符號進(jìn)進(jìn)行正確確引用,使程序序正常運(yùn)運(yùn)行。arm處理器復(fù)復(fù)位后總總是從0 x0地址取第第1條指令,因此只只需把BOOTAD

16、DR設(shè)置為0,再把編編譯后生生成的可可執(zhí)行二二進(jìn)制文文件下載載到ROM的0 x0地址開始始的存儲(chǔ)儲(chǔ)空間,程序便便可正常常引導(dǎo);但是,一旦在在鏈接時(shí)時(shí)指定映映像文件件從0 x0地址開始始,那么么Bootloader就只能在在0 x0地址開始始的ROM空間內(nèi)運(yùn)運(yùn)行,而而無法拷拷貝到SDRAM空間運(yùn)行行實(shí)現(xiàn)快快速引導(dǎo)導(dǎo)。當(dāng)然然,對PXA270等具有MMU功能的微微處理器器來說,雖然可可以先將將Bootloader映像整個(gè)個(gè)拷貝到到SDRAM中,再使使用MMU功能將SDRAM空間映射射到0 x0地址,進(jìn)進(jìn)而繼續(xù)續(xù)在SDRAM中運(yùn)行;但這樣樣一方面面會(huì)使得得Bootloader的設(shè)計(jì)與與實(shí)現(xiàn)復(fù)復(fù)雜化,另

17、一方方面在一一些必須須屏蔽MMU功能的應(yīng)應(yīng)用中(例如引引導(dǎo)armlinux系統(tǒng)),無法使使用MMU進(jìn)行地址址重映射射。利用ARM的基于位位置無關(guān)關(guān)的程序序設(shè)計(jì)可可以解決決上述問問題。只只需在程程序鏈接接時(shí),將將BOOTADDR設(shè)置為SDRAM空間的地地址(一一般情況況下利用用SDRAM中最高的的1 MB存儲(chǔ)空間間作為起起始地址址),這這樣arm處理器上上電復(fù)位位后Bootloader仍然可以以從地址址0開始執(zhí)行行,并將將自身拷拷貝到指指定的_boot_start起始的SDRAM中運(yùn)行。實(shí)現(xiàn)上上述功能能的鏈接接腳本所所對應(yīng)的的啟動(dòng)代代碼架構(gòu)構(gòu)如下:.section.text.globl_star

18、t_start:Breset/*復(fù)位異常常*/*其他異常常處理代代碼*/reset:/*復(fù)位處理理程序*/copy_boot:/*拷貝Bootloader到SDRAM*/LDRR0,=0 x0LDRR1,=_boot_startLDRR2,=_boot_end1:LDRMIAR0!, R3-R10 STRMIAR1!, R3-R10CMPR1,R2BLT1bclear_bss:/*清零.bss段*/BLinit_Stack/*初始化堆堆棧*/LDRPC,=main/*跳轉(zhuǎn)到階階段2的C程序入口口*/.end程序入口口為_start,即復(fù)位位異常,所有其其他異常常向量都都使用相相對跳轉(zhuǎn)轉(zhuǎn)指令B來

19、實(shí)現(xiàn),以保證證位置無無關(guān)特性性。在完完成基本本的硬件件初始化化后,利利用鏈接接腳本傳傳遞過來來_boot_start和_boot_end的參數(shù),將Bootloader映像整個(gè)個(gè)拷貝到到指定的的SDRAM空間,并并清零.bss段,初始始化堆棧棧后,程程序?qū)ain函數(shù)入口口的絕對對地址賦賦給PC,進(jìn)而跳跳轉(zhuǎn)到SDRAM中繼續(xù)運(yùn)運(yùn)行。程程序在跳跳轉(zhuǎn)到main函數(shù)之前前,所有有的代碼碼都在ROM中運(yùn)行,因而必必須要保保證代碼碼的位置置無關(guān)性性,所以以在調(diào)用用初始化化GPIO、存儲(chǔ)系系統(tǒng)和堆堆棧等子子程序時(shí)時(shí),都使使用相對對跳轉(zhuǎn)指指令來完完成。 簡化化設(shè)計(jì),方便實(shí)實(shí)現(xiàn)系統(tǒng)統(tǒng)的快速速引導(dǎo)。位置無無關(guān)代碼

20、碼可以避避免在引引導(dǎo)時(shí)進(jìn)進(jìn)行地址址映射,并方便便地跳轉(zhuǎn)轉(zhuǎn)到SDRAM中實(shí)現(xiàn)快快速引導(dǎo)導(dǎo)。 實(shí)現(xiàn)現(xiàn)復(fù)位處處理智能能化。由由于位置置無關(guān)代代碼可以以被加載載到任意意地址空空間運(yùn)行行,因此此其運(yùn)行行時(shí)的當(dāng)當(dāng)前地址址與鏈接接時(shí)所指指派的地地址并不不一定相相同。利利用這一一特性,可以在在復(fù)位處處理程序序中使處處理器進(jìn)進(jìn)入SVC模式并關(guān)關(guān)閉中斷斷后加入入如下代代碼,便便可根據(jù)據(jù)當(dāng)前運(yùn)運(yùn)行時(shí)的的地址進(jìn)進(jìn)行不同同的復(fù)位位處理:ADRR0,_start/*讀取當(dāng)前前PC附近的_start標(biāo)號所在在指令地地址*/LDRR1,=_boot_start/*讀取Bootloader在SDRAM的起始地地址*/CMPR0,R1BEQclear_

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論