專題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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章