1. 程式人生 > >專題5-核心初始化

專題5-核心初始化

一、異常向量表

1.1 異常定義–execption
因為內部或外部的一些事件,導致處理器停下正在處理的工作,轉而去處理髮生的事件。

1.2 異常型別
7種異常:復位異常、未定義指令異常、軟中斷異常(SWI)、預取失敗異常、資料儲存異常、IRQ、FIQ。
這裡寫圖片描述

1.3 異常向量
當一種異常發生的時候,arm處理器會跳轉到對應異常的固定地址去執行異常處理程式,而這個固定的地址,就稱之為異常向量。

1.4 異常向量表
這裡寫圖片描述

2、手把手教你寫程式碼
start.S的程式碼如下(先寫異常向量表

.text
.global _start
_start:
                b reset
                ldr pc, _undifined_instruction
                ldr pc, _software_interrupt
                ldr pc, _prefetch_abort
                ldr pc, _data_abort
                ldr pc, _not_used
                ldr pc, _irq
                ldr pc, _fiq

#採用巨集的方式,否則上面可以寫為 eg:ldr pc, =undifined_instruction,此時ldr是一個偽指令
_undifined_instruction: .word undifined_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 undifined_instruction: nop software_interrupt: nop prefetch_abort:
nop data_abort: nop not_used: nop irq: nop fiq: nop reset: nop

連結器指令碼gboot.lds如下:

OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS{  #注意這裡是{}不是()
                . = 0x30008000;#2440

                . =ALIGN(4);#4位元組對齊,c語言中是用#pragma pack(4)來對齊
                .text :
                {
                start.o
(.text) *(.text) } . =ALIGN(4); .data : { *(.data) } . =ALIGN(4); bss_start = .; .bss : { *(.bss) } bss_end = .; }

makefile如下:

all : start.o
    arm-linux-ld -Tgboot.lds -o gboot.elf $^         #-o 不要忘記了
    arm-linux-objcopy -O binary gboot.elf gboot.bin

%.o : %.S
    arm-linux-gcc -g -c $^

%.0 : %.c
    arm-linux-gcc -g -c $^

210處理器BL1頭資訊新增:(2440和6410不用加頭)
這裡寫圖片描述
這裡寫圖片描述

二、設定svc模式

通過程式狀態暫存器來設定:
這裡寫圖片描述
這裡寫圖片描述
設定方法:因為狀態暫存器是不能直接01操作的,要先將其複製到通用暫存器(指令:mrs),再對通用暫存器進行01操作(清零:bic 置1:orr),再複製到狀態暫存器(指令:msr)。

備註:bl是一個分支指令,在分支之前,在暫存器14中裝載暫存器15中的內容。即會將連結暫存器lr的值賦給pc指標。

reset:
    bl set_svc

set_svc:
    mrs r0,cpsr
    bic r0,r0,#0x1f
    orr r0,r0,#0xd3  
    msr cpsr,r0
    mov pc,lr

上面置1操作時,對最後5位進行操作可以寫為:orr r0,r0,#0x13(10011),之所以寫為0xd3(11010011),最後5位是一樣的,同時對I、F位進行了置1操作(目的:關閉中斷)。
這裡寫圖片描述

三、關閉看門狗

這裡寫圖片描述
3.1 原理:
這裡寫圖片描述

3.2 看門狗控制暫存器:
這裡寫圖片描述
這裡寫圖片描述

#define pwTCON 0x53000000
disable_watchdog:
    ldr r0,=pwTCON
    mov r1,#0x0     #乾脆全賦值為0
    str r1,[r0]     #把暫存器的值賦給記憶體,str為儲存器訪問指令
    mov pc,lr

四、關閉中斷

首先:cpsr暫存器的 I 、F為設定為1(在設定處理器的工作模式時已經完成)
其次:設定中斷遮蔽暫存器(MASK),設為全1
2440:
這裡寫圖片描述

reset:
    bl disable_interrupt
#define inmask 0x4A000008
disable_interrupt:
    mvn r1,#0x0    #先取反再賦值,寫入全1
    ldr r0,=inmask
    str r1,[r0]
    mov pc,lr

6410:
這裡寫圖片描述

reset:
    bl disable_interrupt
disable_interrupt:
    mvn r1,#0x0
    ldr r0,=0x71200014
    str r1,[r0]

    ldr r0,=0x71300014
    str r1,[r0]
    mov pc,lr

210:
這裡寫圖片描述

reset:
    bl disable_interrupt
disable_interrupt:
    mvn r1,#0x0
    ldr r0,=0xf2000014
    str r1,[r0]

    ldr r0,=0xf2100014
    str r1,[r0]

    ldr r0,=0xf2200014
    str r1,[r0]

    ldr r0,=0xf2300014
    str r1,[r0]
    mov pc,lr

五、關閉mmu和cache

5.1 cache:
這裡寫圖片描述

5.2 mmu之前,先介紹虛擬地址
這裡寫圖片描述
那麼誰來幫助系統完成虛擬地址實體地址之間的轉化呢?—-mmu來完成
(在arm11及以後,訪問cache要經過mmu)

5.3 為什麼要關閉?
在arm初始化的時候並沒有正確的去配置mmu,所以在使用之前要關閉它,防止一些意想不到的錯誤。後面再使用的時候,會配置好再開啟。

5.4 怎麼關閉?—通過協處理器cp15來關閉
第一步:使Icache和Dcache失效
這裡寫圖片描述
第二步:關閉IDcache、mmu
先將控制暫存器(control register)讀到r0暫存器
這裡寫圖片描述
這裡寫圖片描述

reset:
    bl disable_mmu
disable_mmu:
    mcr p15,0,r0,c7,c7,0  #第一步:使Icache和Dcache失效

    #第二步:關閉Dcache、mmu
    mrc p15,0,r0,c1,c0,0
    bic r0,r0,#0x00000007
    mcr p15,0,r0,c1,c0,0
    mov pc,lr