u-boot核心初始化
异常向量表:
异常:因为内部或者外部的一些事件,导致处理器停下正在处理的工作,转而去处理这些发生的事件。ARM Architecture Reference Manual p54页。
7种异常的类型:
Reset异常:突然按下重启键。
Undefined Instruction:未定义指令。()
software interrup:软中断()
Prefetch Abort (instruction fetch memory about):预取中止
Data Abort:提取数据失败。
IRQ:中断
FIQ:快速中断 (响应速度更快)
------------------------------------------------------
异常向量:(p54)
当一种异常发生的时候,ARM处理器会跳转到对应该异常的固定地址去执行异常处理程序,这个固定的地址,称之为异常向量。
-------------------------------------------
异常向量表:由七个异常向量及其处理函数跳转关系组成的表
0x0000000:b reset
0x0000004:ldr pc,_undefined_instruction
0x0000008:ldr pc,_software_interrupt
0x000000c:ldr pc,_prefetch_abort
0x0000010:ldr pc,_data_abort
0x0000014:ldr pc,_not_used //使用无用的指令占据这个地址
0x0000018:ldr pc,_irq
0x000001c:ldr pc,_fiq
在start.S中我们是可以看到这张表的。
------------------------------------------------
代码的编写(start.S,makefile,gboot.lds):
start.S
touch start.S
chmod 777 start.S
.text
.global_start
_start:
b reset
ldr pc,_undefined_instruction //
ldr pc,_software_interrupt
ldr pc,_data_abort
ldr pc,_not_used
ldr pc,_irq
ldr pc,_fiq //将_fiq中的值存放到pc中
_undefined_instruction:.word undefined_instruction
_software_interrupt:.word software_interrupt
_data_abort:.word data_abort
_not_used:.word not_used
_irq:.word irq
_fiq:.word fiq //_fiq中存放的地址为fiq
undefined_instruction:
nop
software_interrupt:
nop
data_abort:
nop
not_used:
nop
irq:
nop
fiq:
nop
reset:
nop
-----------------------------------------------------------
gboot.lds
touch gboot.lds
chmod 777 gboot.lds
OUTPUT_ARCH(arm) @输出格式为arm
ENTRY(_start) @表明程序的路口处为:_start
SECTIONS{
. =0x50008000 @定义起始地址
. =ALIGN(4);
.text :
{start.o(.text) @代码段放的第一个文件。
*(.text)
}
. =ALIGN(4);
.data :
{
*(.data) @所有的数据
}
. =ALIGN(4);
bss_start = .;
.bss :
{
*(.bss)
}
bss_end = .;
}
-----------------------------------------------
touch Makefile
chmod 777 Makefile
all : %.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 : %.s
-----------------------------------------------
设置SVC模式:p 52页,49页M[0:4]设置模式(cpsr)
要让处理器工作在SVC模式就是要将程序状态寄存器cpsr的后五位设置为10011.
思路:先将这五位全部清理(bic指令)
置1的操作:orr(位或)
然后再加上mrs,msr指令。
首先我们应该是在开发板上电以后,然后来设置处理器的工作模式。所以:reset:
bl set_svc
set_svc:
mrs r0,cpsr //将状态寄存器中的值取出到通用寄存器中
bic r0,r0,#0x1f //将该值置0
orr r0,r0,#0xd3(或0x13) //位或操作,设置模式编号
msr cpsr,r0 //将该编号重新放到状态寄存器中。
------------------------------------------------------
关闭看门狗:
watchdog一般是一个硬件模块,其作用就是在系统死机时,帮助系统实现自动重新启动。
看门狗工作原理:watchdog在硬件上实现了计时功能,启动计时后,启动计时后,软件必须在计时结束前(5分钟或更久)重新开始计时,称为喂狗,如果到超时的时候还没有重新开始计时,那么它就认为系统死机了,就自动重新启动系统。
资料s3c6410page:1137图34-1
应为我们的bootloader比较简单,所以不需要看门狗:关闭。
如何关闭看门狗:通过prescaler(PCLK)这个寄存器来关闭。
控制寄存器:WTCON(watch timer control register):0x7E004000
reset:
bl set_svc
bl disable_watchdog
#define pWTCON 0x7E00400 //保存寄存器的地址
diable_watchdog:
ldr r0,=pWTCON //将立即数pWTCON中的内容装载到r0中
mov r1,#0x0 //r1寄存器中装入0x0
str r1,[r0] //将r1中的内容存储到r0中的有效地址
----------------------------------------------------------
关闭中断:
cpsr中N Z C V I F其中I位是控制中断的,F位是控制快速中断的。
分为两步:先将I,F位设置为1.在之前设置svc时已经设置好了
设置中断屏蔽寄存器ps3c2440 389,378
2440的操作:bl disable_interrupt
disable_interrupt:
mvn r1,#0x0
ldr r0,=0x4a000008
str r1,[r0]
6410一般采用的是向量中断的模式,更多的时候采用的是硬件中断。找到interrupt enable这个寄存器。p419页,需要关闭两个寄存器,VIC0INTENCLEAR(中断使能寄存器),VIC1INTRNCLEAR (关闭中断)。
disable_interrupt:
mvn r1,#0x0 //将0x0取反存放到r1中
ldr r0,=0x71200014 //将寄存器地址装载到r0中,相当与r0为该地址的替身。
str r1,[r0] //把r1中的值存放到r0中。
ldr r0,=0x71300014
str r1,[r0]
210则需关闭四个VICxINTENCLEAR.
----------------------------------------------------
关闭mmu和caches
ARM存储体系:处理器内部寄存器(通用,状态寄存器,速度快,数量少),TMC:紧耦合存储器(Cache,主存储器,容量大,速度稍慢),辅助存储器(Flash,SD等!)
cache:是一种容量小,但存取速度非常快的存储器,它保存最近用到的存储器中数据的拷贝。
按功能分:
I-Cache:指令Cache,用于存放指令.
D-Cache:数据Cache,用于存放数据.
mmu:将虚拟地址映射到物理地址。
虚拟地址:可以解决访问内存冲突,让进程使用更大的空间。
虚拟地址原理:用户指定了一个虚拟地址(4G),然后会通过映射将这些地址映射到不同的物理地址中。
因为使用mmu和cache需要一个正确的配置才能正常的使用。所以在这里我们先不使用,否则会导致意向不到的后果。
cache和mmu都是通过协处理器来控制的co-processor.
2440arm核手册p35 register control(read/write control register)先利用指令MRC p15,r0,c1,c0,0 把Register 1中的内容度到r0中,然后再修改r0中的值,在利用指令MRC p15,0,r0,c1,c0,0
Register1p36,看到第12位控制ICache,Cache disabled,第2位控制DCache,第0位控制mmu.
p41,还有一些数据我们需要设置,在Register7中是cache无效,invalidate cache。instruction:MCR p15,0,Rd,c7,c7,0
----------------------------------------------------
如何关闭cache//在arm11中操作是相同的。
1.使ICache和DCache失效。
2.关闭I/Dcache,关闭mmu
代码: bl disable_mmu
disable_mmu:
mcr p15,0,R0,c7,c7,0 //使I/Dcache失效。
mrc p15,0,r0,c1,c0,0
bic r0,r0,#0x00000007
mcr p15,0,r0,c1,c0,0
---------------------------------------------
最后再检查一遍:发现执行完每个bl之后没有返回,所以在每个bl所跳转的程序完成之后,需要加上一个mov pc,lr