Uboot编写(一)

来源:互联网 发布:西安交通大学网络 编辑:程序博客网 时间:2024/04/30 11:25

初始化异常向量表:

异常:因为外部或内部一些事件,导致处理器停下正在处理的工作,转而处理这些发生的事件。共七种异常: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  $^

 

 



0 0
原创粉丝点击