新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM裸機(jī)開(kāi)發(fā)bootloader核心初始化

ARM裸機(jī)開(kāi)發(fā)bootloader核心初始化

作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
一、異常向量表

1、異常的定義

本文引用地址:http://m.butianyuan.cn/article/201611/318209.htm

異常:因?yàn)閮?nèi)部或者外部的一些事件,導(dǎo)致處理器停下正在處理的工作,轉(zhuǎn)而去處理這些發(fā)生的事情。

2、異常的類型

ARM處理器有7種Exception type分別為:Reset、Undefined instructions、Software interrupt、Prefetch Abort、Data Abort、IRQ、FIQ

2、什么是異常向量

當(dāng)一種異常發(fā)生的時(shí)候,ARM處理器會(huì)跳轉(zhuǎn)到對(duì)應(yīng)該異常的固定地址去執(zhí)行異常處理程序,而這個(gè)固定的地址,就稱為異常向量。

3、異常向量表

由七個(gè)異常向量及其處理函數(shù)跳轉(zhuǎn)關(guān)系組成的表為異常向量表。

下面是一個(gè)例子:

start.S

.text.global _start_start:b resetldr pc, _undefined_instructionldr pc, _software_interruptldr pc, _prefetch_abortldr pc, _data_abortldr pc, _irqldr pc, _fiq_undefined_instruction:	.word undefined_instruction_software_interrupt:	.word software_interrupt_prefetch_abort: 	.word prefetch_abort_data_abort: 	.word data_abort_not_used: 	.word not_used_irq:	.word irq_fiq:	.word fiqundefined_instruction:nopsoftware_interrupt:nopprefetch_abort:nopdata_abort:nopnot_used:nopirq:nopfiq:nopreset:nop	

gboot.lds

OUTPUT_ARCH(arm)ENTRY(_start)SECTIONS{. = 0x50008000;. = ALIGN(4);.text :{start.o(.text)*(.text)}. = ALIGN(4);.data :{*(.data)}. = ALIGN(4);bss_start = .;.bss :{*(.bss)}bss_end = .;}


Makefile

all : start.oarm-linux-ld -Tgboot.lds -o gboot.elf $^arm-linux-objcopy -O binary gboot.elf gboot.bin%.o : %.Sarm-linux-gcc -g -c %.S %.o : %.carm-linux-gcc -g -c %.c .PHONY: cleanclean:rm *.o *.elf *.bin
關(guān)于異常向量表,對(duì)于2440和6410以上就結(jié)束了,不過(guò)對(duì)于210還要添加BL1頭

./mkv210_image led.bin 210.bin

/home/dnw 210.bin 0x50008000

如果不加頭的話,就無(wú)法正常工作。原因是210在上電后會(huì)運(yùn)行廠家已經(jīng)固化在SRAM中的BL0,這個(gè)時(shí)候,由BL0來(lái)調(diào)用BL1,BL1運(yùn)行會(huì)產(chǎn)生校驗(yàn)碼(這個(gè)校驗(yàn)碼就在添加的頭里面)并與BL0里的校驗(yàn)碼進(jìn)行比對(duì),確認(rèn)是否為要運(yùn)行的BL1。成功后就運(yùn)行BL1.

Header Info (check sum(user writing)、BL1 size(user writing)).

二、設(shè)置SVC模式

此時(shí)設(shè)置ARM的工作模式為SVC(supervisor),這樣可以使用更多的寄存器,同時(shí)擁有很大的操作權(quán)限。具體可以參考下圖


通過(guò)上圖對(duì)ARM的狀態(tài)寄存器的解釋,我們可以得知將CPSR的后五位設(shè)置為0b10011就可以使用SVC模式。同時(shí)我們還要關(guān)閉irq和fiq。

具體實(shí)現(xiàn)代碼:

續(xù)上start.S

reset:bl set_svcset_svc:mrs r0, cpsrbic r0, r0, #ox1forr r0, r0, #oxd3msr cpsr, r0

三、關(guān)閉看門狗

1、什么是看門狗

有些嵌入式設(shè)備要長(zhǎng)期工作在無(wú)人看管的情況下,這個(gè)時(shí)候就需要,當(dāng)發(fā)生死機(jī)時(shí),設(shè)備可以實(shí)現(xiàn)自啟動(dòng)。而watchdog就可以完成這樣一種功能。watchdog模塊是一硬件設(shè)備。其作用就是當(dāng)系統(tǒng)發(fā)生死機(jī)時(shí),幫助系統(tǒng)實(shí)現(xiàn)自啟動(dòng)。

2、看門狗如何工作

看門狗模塊有三部分組成,分別為時(shí)鐘產(chǎn)生器,計(jì)時(shí)器,重啟器。當(dāng)開(kāi)啟看門狗時(shí),計(jì)時(shí)器就開(kāi)始了計(jì)時(shí),系統(tǒng)必須在計(jì)時(shí)結(jié)束前對(duì)看門狗重新設(shè)置使其重新計(jì)時(shí),簡(jiǎn)稱喂狗。否則它會(huì)認(rèn)為系統(tǒng)發(fā)生了死機(jī),就重啟系統(tǒng)。

3、為什么要關(guān)閉看門狗

一般情況下,bootloader的運(yùn)行過(guò)程中不會(huì)發(fā)生死機(jī),所以我們就關(guān)閉看門狗。否則我們還要不斷的喂狗,而占用系統(tǒng)時(shí)間。

下面是6410中的watchdog的解釋


代碼編寫(xiě):

reset:bl set_svcbl disable_watchdogset_svc:mrs r0, cpsrbic r0, r0, #0x1forr r0, r0, #0xd3msr cpsr, r0#define pWTCON 0x7E004000disable_watchdog:ldr r0, =pWTCON	/*mov的操作數(shù)最多為8位*/mov r1, #0x0str r1, [r0]
注:我們這里把watchdog的控制寄存器直接清零,也可以達(dá)到效果。

四、關(guān)閉中斷

關(guān)閉中斷要兩個(gè)環(huán)節(jié):1、CPSR中的I F位 置1,在設(shè)置SVC時(shí)我們已經(jīng)做過(guò),所以這里就不做了。2、對(duì)中斷屏蔽寄存器進(jìn)行設(shè)置

2440的板子需要設(shè)置INTMSK寄存器

210的板子需要設(shè)置4組寄存器VICINTENCLEAR

6410的板子需要設(shè)置2組寄存器VIC0INTENCLEAR和VIC1INTENCLEAR

下面我們以6410為例子進(jìn)行介紹:


編碼如下

disable_interrupt:mvn r1, #0x0ldr r0, =0x71200014str r1, [r0]ldr r0, =0x71300014str r1, [r0]

五、關(guān)閉MMU和Cache

1、前言


從ARM的存儲(chǔ)體系,我們可以看到,位于金子塔頂端的是處理器的寄存器,后面依次為TCM和輔助存儲(chǔ)器。顯然從金子塔的底部到頂部存儲(chǔ)器的存取速度愈來(lái)愈快,價(jià)格也越來(lái)越高,而數(shù)量卻越來(lái)越少。

2、什么是Cache

我們都知道處理器的訪問(wèn)速度是非??斓模鴥?nèi)存的速度卻慢的很。這樣當(dāng)處理器在訪問(wèn)內(nèi)存時(shí)就出現(xiàn)了問(wèn)題。而Cache恰恰就用來(lái)解決這個(gè)問(wèn)題。從物理結(jié)構(gòu)上來(lái)講,Cache位于處理器與內(nèi)存之間,cache中存儲(chǔ)了處理器經(jīng)常從內(nèi)存訪問(wèn)的數(shù)據(jù)與指令,也就是cache是內(nèi)存的部分拷貝。這時(shí)處理器往往先訪問(wèn)cache,如果cache中沒(méi)有想要的數(shù)據(jù),才去內(nèi)存查找。而cache的訪問(wèn)速度要比內(nèi)存大的多,這樣就提高了整個(gè)的運(yùn)行效率。

cache又分為:I-Cache和D-Cache

3、MMU

談到MMU這個(gè)時(shí)候就要先說(shuō)一下虛擬地址:作為一個(gè)程序員,大家都知道有邏輯地址和物理地址之分,如果我們不直接和硬件打交道,我們根本不用去管物理地址,只要用邏輯地址就可以了。而MMU就是把邏輯地址轉(zhuǎn)換為物理地址的協(xié)議。

假如我們只使用物理地址就會(huì)出現(xiàn)兩個(gè)問(wèn)題要解決:1、地址沖突(兩段程序使用同一物理地址)。2、范圍小

我們使用了MMU就可以把邏輯地址映射到物理地址,再具體的說(shuō)就是兩段程序使用的是同一邏輯地址,而經(jīng)過(guò)映射后,它們都被映射到不同的物理地址。還有就是地址空間變大了。具體的物理地址的分配不用程序員來(lái)管,都要MMU來(lái)分配,這樣就可以更好的利用物理空間。

ARM11之間Cache位于MMU前面靠近處理器,也就是說(shuō)cache使用的是虛擬地址(邏輯地址),而ARM11之后包括ARM11的MMU靠近內(nèi)存,這個(gè)時(shí)候使用的是物理地址。

4、為什么要關(guān)閉MMU和Cache

MMU和Cache在使用之前要進(jìn)行配置,在ARM初始化的時(shí)候還沒(méi)有進(jìn)行配置,所以這個(gè)時(shí)候要關(guān)閉它們。還有就是避免Bootloader將linux內(nèi)核下載到D-cache中,而I-cache這個(gè)時(shí)候可以不管它。

關(guān)閉MMU和Cache的步驟:

1、使I-cache和D-cache失效

2、關(guān)閉I-Cache和D-Cache,關(guān)閉MMU

下面是cp15的寄存器解釋:


代碼如下:

disable_mmu:

mcr p15, 0, r0, c7, c7, 0

mrc p15, 0, r0, c1, c0, 0

bic r0, r0, #0x00000007

mcr p15, 0, r0, c1, c0, 0

2440、6410和210的cp15是一樣的。所以這里的代碼也是一樣的。

整個(gè)核心初始化的代碼為:

.text.global _start_start:b resetldr pc, _undefined_instructionldr pc, _software_interruptldr pc, _prefetch_abortldr pc, _data_abortldr pc, _irqldr pc, _fiq_undefined_instruction:	.word undefined_instruction_software_interrupt:	.word software_interrupt_prefetch_abort: 	.word prefetch_abort_data_abort: 	.word data_abort_not_used: 	.word not_used_irq:	.word irq_fiq:	.word fiqundefined_instruction:nopsoftware_interrupt:nopprefetch_abort:nopdata_abort:nopnot_used:nopirq:nopfiq:nopreset:bl set_svcbl disable_watchdogbl disable_interruptbl disable_mmuset_svc:mrs r0, cpsrbic r0, r0, #0x1forr r0, r0, #0xd3msr cpsr, r0mov pc, lr#define pWTCON 0x7E004000disable_watchdog:ldr r0, =pWTCON	/*mov的操作數(shù)最多為8位*/mov r1, #0x0str r1, [r0]mov pc, lrdisable_interrupt:mvn r1, #0x0ldr r0, =0x71200014str r1, [r0]ldr r0, =0x71300014str r1, [r0]mov pc, lrdisable_mmu:mcr p15, 0, r0, c7, c7, 0mrc p15, 0, r0, c1, c0, 0bic r0, r0, #0x00000007mcr p15, 0, r0, c1, c0, 0mov pc, lr


評(píng)論


技術(shù)專區(qū)

關(guān)閉