Uboot編寫(一)

初始化異常向量表:

異常:因爲外部或內部一些事件,導致處理器停下正在處理的工作,轉而處理這些發生的事件。共七種異常:resetundefined instructions, Software InterruptionSWI),Prefetch AbortData AbsortIRQFIQ。當一種異常發生,ARM處理器會跳轉到對應該異常的固定地址去執行異常程序,而這個固定地址就是異常向量。

由七個異常向量及其處理函數跳轉關係組成的表即爲異常向量表:

關閉看門狗:

Watchdog:在硬件上實現定時器的功能,當啓動後系統要在計時結束之前重新對計時器計時,  當系統死機時候能感知到事情的發生,然後重啓系統,


左邊PCLK經過分頻操作後輸出的就是定時器的時鐘,中間是計數的邏輯,一旦開始計數之後,每個時鐘WTCNT就會減一,減到0WTDAT還沒有設置新的值,他就認爲系統死機,後面就會產生重啓信號,讓CPU重啓。

關閉中斷:


中斷處理過程:當中斷產生之後,寄存器SRCPND記錄中斷產生的請求狀態,通過mask屏蔽寄存器設置要屏蔽的中斷請求,下面就通過mask屏蔽中斷請求,最終不會送到處理器。

關閉mmucache

ARM存儲體系,頂端:CPU內部寄存器,訪問速度快,數量太少。中間:緊耦合存儲器(cache,主存儲器)。下層:輔助存儲器(nandflash, SD卡)。


上面爲沒有使用cache的系統,CPU直接訪問主存儲器,由於兩者間速度巨大區別導致CPU訪問低效率,爲了改善這個情況,引入cache相比內存訪問速度更快,cache存放的是主存儲區一些數據的拷貝,當CPU訪問主存找數據時,CPU會根據地址在cache裏找有無這塊數據,如果沒有主存會把數據傳給CPU,還會把數據放入cache,第二次再訪問數據時,cache裏已有數據拷貝,不會在訪問慢的主存,直接從cache取走數據。

cache是容量小但訪問速度快的存儲器,他保存最近用到存儲器數據的拷貝。I-Cache指令cache用於存放指令。D-Cache,數據cache,存放數據。

虛擬地址:1:比如Linux有多個應用程序,都要用到同一個物理地址造成地址衝突。2:僅僅使用物理地址範圍只有64M,使用地址範圍較小。引入虛擬地址後多個應用程序使用同一個地址爲虛擬地址,但是經過硬件的映射能夠把相同的虛擬地址映射到不同地方,有效解決衝突問題。空間變大了,任何應用訪問的虛擬地址空間都是4G,真正使用的時候才映射,使進程使用更大的地址空間。mmu完成虛擬地址到物理地址的映射,要使用mmu需要一個正常的配置,才能正確的使用mmu,但是在進行arm初始化時還沒有配置好mmu,不能使用否則導致錯誤發生,在初始化階段暫時關掉,mmucache都通過cp15協處理器控制。 

 

//2440 , 6410版本

_start: b reset

ldr pc, _undefined_instruction

ldr pc, _software_interrupt

ldr pc, _prefetch_abort

ldr pc, _data_abort

ldr pc, _not_used

ldr pc, _irq

ldr pc, _fiq

下面編寫三個部分的代碼:

Start.s uboot.lds makefile

// Start.S

.text  ; 指明代碼段

_global  _start  ;聲明全局

_start: ;程序入口

b reset

ldr  pc, _undefined_instruction

ldr  pc, _software_interrupt

ldr  pc,_prefetch_abort

ldr  pc, _data_abort

ldr  pc, _not_used

ldr  pc, _irq

ldr  pc, _fiq

 

_undefined_instruction:  .word  undefined_instruction

//_undefined_instruction處存儲_undefined_instruction大小爲_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  fiq

 

undefined_instruction:

nop

software_interrupt:

nop 

prefetch_abort:

nop 

data_abort:

nop

not_used:

nop

irq:

nop

fiq:

nop

reset:

bl set_svc

bl disable_watchdog ;關閉看門狗

bl disable_interrupt ;屏蔽中斷,往INTMSK全部寫入1

bl diable_mmu

mov pc, lr

set_svc: ;設置爲svc工作模式

mrs r0, cpsr

bic r0, r0, #0x1f ;第二操作數哪些位爲1,第一操作數哪些就清除

orr r0, r0, #0x13

msr cpsr , r0

mov pc, lr

#define pwTCON 0x53000000

disable_watchdog: ;通過WTCON控制看門狗

 ldr  r0, =pwTCON 

     mov r1, 0x0

     str  r1, [r0]

     mov pc, lr

disable_interrupt:

 mov r1, #0x0

     ldr r0, =0x40000008

     str r1, [r0]

     mov pc, lr

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

mov pc, lr

 

uboot.lds鏈接器腳本,整個程序的構成將根據鏈接器腳本。

 //uboot.lds

OUTPUT_ARCH(arm) ;指明輸出格式

ENTRY (_start)   ;輸出程序的入口

SECTIONS {

. =  0x30008000  ;整個程序鏈接起始地址

. =  ALIGN(4)  ;4字節對齊

.text : ;代碼段

{

start.o  (.text) 

*(.text)

}

. =  ALIGN(4);   ;4字節對齊

.data :

{

*(.data)

}

. =  ALIGN(4);  ;4字節對齊

bss_start = .;  ;記錄bss開始結束

.bss :

{

*(.bss) 

}

bss_end = .;

}

//編寫makefilemakefile由一條條規則構成,首先創建兩條通用規則

all  :  start.o

arm-linux-ld -Tuboot.lds -o uboot.elf  $^

Arm-linux-objcopy -O -bin uboot.elf  uboot.bin  

%.o = %.s

arm-linux-gcc -o -c  $^

%.o = %.s

arm-linux-gcc -g -c  $^

 

 



發佈了56 篇原創文章 · 獲贊 5 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章