天天看點

嵌入式基礎學習-核心初始化1 異常向量表2 設定svc模式3 關閉看門狗4 關閉中斷5 關閉mmu與Cache

文章目錄

  • 1 異常向量表
    • 1.1 異常定義
    • 1.2 異常類型
    • 1.3 異常向量
    • 1.4 程式設定
  • 2 設定svc模式
  • 3 關閉看門狗
    • 3.1 作用
    • 3.2 工作方式
    • 3.3 原理圖
  • 4 關閉中斷
  • 5 關閉mmu與Cache
    • 5.1 ARM存儲體系
    • 5.2 Cache
    • 5.3 虛拟位址
    • 5.4 mmu作用

注意:使用mini2440開發闆

1 異常向量表

1.1 異常定義

    因為内部或者外部的一些事件,導緻處理器停下正在處理的工作,轉而去處理這些發生的事件

1.2 異常類型

嵌入式基礎學習-核心初始化1 異常向量表2 設定svc模式3 關閉看門狗4 關閉中斷5 關閉mmu與Cache

圖上可以看出有兩個位址,預設的情況下是Normal address,當然也可以通過CP15這個寄存器來程序設定。

1.3 異常向量

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

    由七個異常向量及其處理函數跳轉關系組成的表即為異常向量表.

0x00000000: b reset
0x00000004: ldr pc, _undefined_instruction
0x00000008: ldr pc, _software_interrupt
0x0000000c: ldr pc, _prefetch_abort
0x00000010: ldr pc, _data_abort
0x00000014: ldr pc, _not_used
0x00000018: ldr pc, _irq
0x0000001c: ldr pc, _fiq
           

為了讓異常向量表

0x00000010

位址指令到

0x00000018

,加入了一個

0x00000014

,這裡

0x00000014: ldr pc, _not_used

并麼有什麼作用

1.4 程式設定

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
_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:
		nop
           

gboot.lds

OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS {
	. = 0x30008000;
	
	. = ALIGN(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 $^
	arm-linux-objcopy -O binary gboot.elf gboot.bin
	
%.o : %.S
	arm-linux-gcc -g -c $^
	
%.o : %.c
	arm-linux-gcc -g -c $^
	
.PHONY: clean
clean:
	rm *.o *.elf *.bin
           

2 設定svc模式

對于

linux系統、bootloader、uboot

而言,工作在svc模式,這樣就可以執行更多的指令和更多的寄存器。

設定svc模式,通過設定程式狀态寄存器

Program status registers

來完成。

嵌入式基礎學習-核心初始化1 異常向量表2 設定svc模式3 關閉看門狗4 關閉中斷5 關閉mmu與Cache

0-4這5位就可以确定設定工作模式。

修改start.S檔案。

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
_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

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

           

    要通路這兩個cpsr、spsr寄存器,需要将寄存器中的值導入到通用寄存器中,在通用寄存器中修改,修改後在從通用寄存器中導入cpsr/spsr寄存器中。

3 關閉看門狗

3.1 作用

    系統自身帶有一種自動重新開機的功能。 watchdog一般是一個硬體子產品,其作用就是在系統當機時,幫助系統實作自動重新開機

3.2 工作方式

    Watchdog在硬體上實作了計時功能,啟動計時後,使用者(軟體)必須在計時結束前重新開始計時,俗稱“喂狗”,如果到逾時的時候還沒有重新開始計時,那麼它就認為系統是當機了,就自動重新開機系統

3.3 原理圖

嵌入式基礎學習-核心初始化1 異常向量表2 設定svc模式3 關閉看門狗4 關閉中斷5 關閉mmu與Cache

通過watchdog timer control register這個寄存器來關閉看門狗。

修改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
_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
	
set_svc:
	mrs r0, cpsr
	bic r0, r0, #0x1f
	orr r0, r0, #0xd3
	msr cpsr, r0
	mov pc, lr

#define pWTCON 0x53000000
disable_watchdog:
	ldr r0, =pWTCON
	mov r1, #0x0
	str r1, [r0]
	mov pc, lr
           

如果是6440或者這裡的pWTCON要修改。具體檢視手冊。

4 關閉中斷

INTERRUPT MASK REGISTER

寄存器中全部寫1。所對應位的中斷就會被屏蔽掉了

修改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
_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
	
set_svc:
	mrs r0, cpsr
	bic r0, r0, #0x1f
	orr r0, r0, #0xd3
	msr cpsr, r0
	mov pc, lr

#define pWTCON 0x53000000
disable_watchdog:
	ldr r0, =pWTCON
	mov r1, #0x0
	str r1, [r0]
	mov pc, lr
           

5 關閉mmu與Cache

5.1 ARM存儲體系

嵌入式基礎學習-核心初始化1 異常向量表2 設定svc模式3 關閉看門狗4 關閉中斷5 關閉mmu與Cache

5.2 Cache

Cache是一種容量小但存取速度非常快的存儲器,它儲存最近用到的存儲器中資料的拷貝。對于程式員來說,Cache是透明的。它自動決定儲存哪些資料、覆寫哪些資料。按照功能劃分:

I-Cache: 指令Cache,用于存放指令

D-Cache: 資料Cache,用于存放資料

5.3 虛拟位址

虛拟位址:程式中使用的位址。

實體位址:實體存儲單元實際的位址

使用虛拟位址:

-可以讓程序使用更大的空間

-可以解決沖突

5.4 mmu作用

mmu作用:虛拟位址到實體位址的映射。

分兩步來做:

首先使I-cache和D-cache失效,然後關閉I,D-cache,mmu

修改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
	

_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 reset

undifined_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
	bl disable_mmu

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

#define pWTCON 0x53000000
disable_watchdog:
	ldr r0, =pWTCON
	mov r1, #0x0
	str r1, [r0]
	mov pc, lr

disable_interrupt:
	mvn r1, #0x0
	ldr r0, =0x4a000008
	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