前面把内核的引导启动整理了~ 想想顺便把uboot也看看吧 = 3=
uboot版本 : 1.3.0-rc3 由朗成的weibing进行了修改以提供板子的nand引导启动功能
板子 : AT2440EVB
在分析启动代码之前先看一下S3C2440的NAND启动:
在配置NAND启动模式之后,S3C2440上电会先将NAND中的0x0 - 0x1000共4096字节的数据拷贝到位于Bank0中的Boot Internal SRAM上
Bank0如下图:
可以看出Boot Internal SRAM为4KB大小,也正是因为Boot Internal SRAM只有4KB大小,所以只能从NAND中拷贝4K的内容 = 3= 这个Boot Internal SRAM是配置为NAND FLASH启动模式才有的
这4K内容是什么呢?~ 这就要看Uboot的镜像文件中是如何进行连接的了~
连接脚本在board/smdk2440/u-boot.lds中,如下
SECTIONS { ????. = 0x00000000;
????. = ALIGN(4); ????.text : ????{ ???? cpu/arm920t/start.o????(.text) ???? cpu/arm920t/s3c24x0/nand_read.o (.text) ???? *(.text) ????}
????. = ALIGN(4); ????.rodata : { *(.rodata) }
????. = ALIGN(4); ????.data : { *(.data) }
????. = ALIGN(4); ????.got : { *(.got) }
????. = .; ????__u_boot_cmd_start = .; ????.u_boot_cmd : { *(.u_boot_cmd) } ????__u_boot_cmd_end = .;
????. = ALIGN(4); ????__bss_start = .; ????.bss : { *(.bss) } ????_end = .; } |
.text为代码段,可以看出cpu/arm920t/start.o在代码段的最前面,所以会先执行start.o中的代码
连接完成后的镜像文件的前4K如下
cpu/arm920t/start.o(.text) ?.text 0x33f80000 0x4e0 cpu/arm920t/start.o ????????????????0x33f80050 IRQ_STACK_START ????????????????0x33f80048 _bss_start ????????????????0x33f8004c _bss_end ????????????????0x33f80044 _armboot_start ????????????????0x33f80000 _start ????????????????0x33f80054 FIQ_STACK_START ?cpu/arm920t/s3c24x0/nand_read.o(.text) ?.text 0x33f804e0 0x1b8 cpu/arm920t/s3c24x0/nand_read.o ????????????????0x33f804e0 nand_read_ll ?*(.text) ?.text 0x33f80698 0x64 board/smdk2440/libsmdk2440.a(lowlevel_init.o) ????????????????0x33f8069c lowlevel_init ?.text 0x33f806fc 0x280 cpu/arm920t/libarm920t.a(interrupts.o) ????????????????0x33f80934 do_fiq ????????????????0x33f80880 do_undefined_instruction ????????????????0x33f80744 show_regs ????????????????0x33f80958 do_irq ????????????????0x33f80728 bad_mode ????????????????0x33f808c8 do_prefetch_abort ????????????????0x33f8070c disable_interrupts ????????????????0x33f80910 do_not_used ????????????????0x33f808ec do_data_abort ????????????????0x33f808a4 do_software_interrupt ????????????????0x33f806fc enable_interrupts ?.text 0x33f8097c 0x250 cpu/arm920t/s3c24x0/libs3c24x0.a(interrupts.o) ????????????????0x33f80aa4 set_timer ????????????????0x33f80a20 reset_timer ????????????????0x33f8097c interrupt_init ????????????????0x33f80ba0 get_tbclk ????????????????0x33f80a90 get_timer ????????????????0x33f809f0 reset_timer_masked ????????????????0x33f80a24 get_timer_masked ????????????????0x33f80ab4 udelay ????????????????0x33f80b10 udelay_masked ????????????????0x33f80bac reset_cpu ????????????????0x33f80b8c get_ticks ?.text 0x33f80bcc 0x150 cpu/arm920t/s3c24x0/libs3c24x0.a(speed.o) ????????????????0x33f80c4c get_HCLK ????????????????0x33f80cec get_PCLK ????????????????0x33f80c44 get_FCLK ????????????????0x33f80d14 get_UCLK ?.text 0x33f80d1c 0x1e8 cpu/arm920t/s3c24x0/libs3c24x0.a(cmd_s3c24xx.o) ????????????????0x33f80d8c do_s3c24xx ?.text 0x33f80f04 0xdc cpu/arm920t/s3c24x0/libs3c24x0.a(serial.o) ????????????????0x33f80f04 serial_setbrg ????????????????0x33f80fa8 serial_tstc ????????????????0x33f80f80 serial_putc ????????????????0x33f80f58 serial_init ????????????????0x33f80fb8 serial_puts ????????????????0x33f80f68 serial_getc ?.text 0x33f80fe0 0x140 lib_arm/libarm.a(_divsi3.o) ????????????????0x33f80fe0 __divsi3 |
如何设置从0x33f80000开始呢?~这是链接的时候指定的 在根目录下面的config.mk中有下面一句 LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS) 关键就是其中的-Ttext $(TEXT_BASE),这句指明了代码段的起始地址 而TEXT_BASE在board/smdk2440/config.mk中定义 TEXT_BASE = 0x33F8 0000 为什么是0x33F8 0000呢?~
这是将NAND中Uboot拷贝到RAM中的起始地址,所以在代码拷贝到RAM之前不能使用绝对地址来寻址数据,只能用相对地址
在以下将用虚拟地址来指Uboot在RAM中的地址,也就是0x33F8 0000
现在来看代码cpu/arm920t/start.S
_start:???? ????b start_code ????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 |
b? start_code在虚拟地址0x33F8 0000处,拷贝到Boot Internal SRAM后则位于0x0处,所以b? start_code是第一条执行的指令,
start_code在cpu/arm920t/start.S中 代码如下:
????//读取CPSR寄存器的内容到R0 ????mrs????r0,cpsr ????//清除R0中的0 - 4 这5个位后保存到R0中 ????//也就是清除用户模式位 ????bic????r0,r0,#0x1f ????//置R0的0 1 4 6 7 位为真 ????//也就是选择SVC模式 ????//关闭中断和快速中断 ????orr????r0,#0xd3 ????//将R0中的值保存到CPSR上 ????msr????cpsr,r0 # define pWTCON????????0x53000000 # define INTMSK????????0x4A000008????/* Interupt-Controller base addresses */ # define INTSUBMSK????0x4A00001C # define LOCKTIME????0x4c000000 # define MPLLCON ????0x4c000004 # define UPLLCON ????0x4c000008 # define CLKDIVN????0x4C000014????/* clock divisor register */
# define INTSUBMSK_val????0xffff # define MPLLCON_val????((184 << 12) + (2 << 4) + 2)????/*406M*/ # define UPLLCON_val ????((60 << 12) + (4 << 4) + 2) /* 47M */ # define CLKDIVN_val????7 /* FCLK:HCLK:PCLK = 1:3:6 */ # define CAMDIVN????0x4C000018 ????//取得看门狗寄存器的地址 ????ldr r0, =pWTCON ????//将R1寄存器清0 ????mov r1, #0x0 ????//将看门狗寄存器清0 ????str r1, [r0] ????/* ???? * mask all IRQs by setting all bits in the INTMR - default ???? */ ????//设R1寄存器为0xFFFF FFFF ????mov????r1, #0xffffffff ????//读取中断屏蔽寄存器的地址 ????ldr????r0, =INTMSK ????//将中断屏蔽寄存器中的位全设1,屏蔽所有中断 ????str????r1, [r0] ????//# define INTSUBMSK_val????0xffff ????//设R1寄存器为0xFFFF ????ldr????r1, =INTSUBMSK_val ????//读取辅助中断屏蔽寄存器的地址 ????ldr????r0, =INTSUBMSK ????//将辅助中断屏蔽寄中的11个中断信号屏蔽掉 ????str????r1, [r0] ????//# define LOCKTIME????0x4c000000 ????//读取PLL锁频计数器寄存器地址到R0中 ????ldr r0,=LOCKTIME ????//将R1设为0x00FF FFFF ????ldr r1,=0xffffff ????//M_LTIME为0xFFFF ????//U_LTIME为0x00FF ????str r1,[r0]???? ????/* FCLK:HCLK:PCLK = 1:2:4 */ ????/* default FCLK is 120 MHz ! */ ????//# define CLKDIVN????0x4C000014????/* clock divisor register */ ????//读取时钟分频寄存器的地址 ????ldr????r0, =CLKDIVN ????//# define CLKDIVN_val????7 /* FCLK:HCLK:PCLK = 1:3:6 */ ????//将R1设为0x7 ????mov????r1, #CLKDIVN_va ????//PDIVN - 1: PCLK has the clock same as the HCLK/2. ????//HDIVN - 11 : HCLK = FCLK/3 when CAMDIVN[8] = 0. ????// HCLK = FCLK/6 when CAMDIVN[8] = 1. ????str????r1, [r0] ????/* Make sure we get FCLK:HCLK:PCLK = 1:3:6 */ ????//# define CAMDIVN????0x4C000018 ????//读取摄像头时钟分频寄存器的地址 ????ldr r0, =CAMDIVN ????//将R1设为0 ????mov r1, #0 ????//将摄像头时钟分频寄存器清0 ????str r1, [r0] ????/* Clock asynchronous mode */ ????//MRC p15,Rd,c1,c0,0 ; read control register ????//读取控制寄存器中的值到R1中 ????mrc p15, 0, r1, c1, c0, 0 ????//31 iA bit Asynchronous clock select ????//30 nF bit notFastBus select ????orr r1, #0xc0000000 ????//MCR p15,0 ; write control register ????//将R1中的值写到控制寄存器中 ????mcr p15, 0 ????//# define UPLLCON ????0x4c000008 ????//读取UPLL设置寄存器的地址到R0中 ????ldr????r0,=UPLLCON ????//# define UPLLCON_val ????((60 << 12) + (4 << 4) + 2) /* 47M */ ????ldr????r1,=UPLLCON_val ????//将R1中的值写入UPLL设置寄存器中 ????str????r1,[r0] ????//ARM920T为5级流水线,需要至少5个周期来让指令生效 ????nop???? ????nop ????nop ????nop ????nop ????nop ????nop ????nop ????//读取MPLL设置寄存器的地址到R0中???? ????ldr????r0,=MPLLCON ????//# define MPLLCON_val????((184 << 12) + (2 << 4) + 2)????/*406M*/ ????ldr????r1,=MPLLCON_val ????//将R1中的值写入MPLL设置寄存器中 ????str????r1,[r0] #define GPJCON 0x560000D0 #define GPJDAT 0x560000D4 #define GPJUP???????????? 0x560000D8 ????//跳转到cpu_init_crit处执行 ????//并将下一条指令的地址写入LR寄存器中 ????bl????cpu_init_crit |
cpu_init_crit在cpu/arm920t/start.S中 代码如下:
cpu_init_crit: ????/* ???? * flush v4 I/D caches ???? */ ????//将R0寄存器置0 ????mov????r0, #0 ????//Invalidate ICache and DCache SBZ MCR p15,c7,0 ????//禁止指令和数据cache ????mcr????p15, r0, c7, 0????/* flush v3/v4 cache */ ????//Invalidate TLB(s) SBZ MCR p15,c8,0 ????mcr????p15, c8, 0????/* flush v4 TLB */ ????/* ???? * disable MMU stuff and caches ???? */ ????//MRC p15,0 ; read control register ????mrc????p15, 0 ????//清除[8] [9] [13] 这3个位 ????//8 - System protection ????//9 - ROM protection ????//13 - Base location of exception registers - 0 = Low addresses = 0x00000000. ????bic????r0, #0x00002300????// clear bits 13,9:8 (--V- --RS) ????//清除[0] [1] [2] [7] 这4个位 ????// 0 - MMU enable - 0 = MMU disabled. ????// 1 - Alignment fault enable - 0 = Fault checking disabled. ????// 2 - DCache enable - 0 = DCache disabled. ????// 7 - Endianness - 0 = Little-endian operation. ????bic????r0, #0x00000087????// clear bits 7,2:0 (B--- -CAM) ????//设置位[1]为真 ????// 1 - Alignment fault enable - 1 = Fault checking enabled. ????orr????r0, #0x00000002????// set bit 2 (A) Align ????//设置位[12]为真 ????//12 - ICache enable - 1 = ICache enabled. ????orr????r0, #0x00001000????// set bit 12 (I) I-Cache ????//MCR p15,0 ; write control register ????mcr????p15, 0 ????//将返回地址保存到IP中 ????mov????ip, lr ????//跳转到lowlevel_init中执行 ????bl????lowlevel_init |
cpu_init_crit在cpu/arm920t/start.S中 代码如下:
.globl lowlevel_init ????//读取下面标号为SMRDATA处的地址到R0中 ????ldr r0, =SMRDATA ????//读取上面标号为_TEXT_BASE处的地址内容到R1中 ????//也就是取得TEXT_BASE的值到R1中 ????ldr????r1, _TEXT_BASE ????//计算SMRDATA的相对地址保存到R0中 ????//SMRDATA为虚拟地址,而TEXT_BASE为虚拟地址的起始地址 ????//而现在Uboot的起始地址并不为虚拟地址 ????//TEXT_BASE为0x33F8 0000,SMRDATA为0x33F8 06C8 ????//而现在程序运行在起始地址为0x0000 0000的地方 ????//所以需要计算以0x0000 0000为标准的相对地址 ????sub????r0, r1 ????//取得带宽与等待状态控制寄存器地址到R1中 ????ldr????r1, =BWSCON????/* Bus Width Status Controller */ ????//一共需要设置13个寄存器,每个寄存器4字节 ????add r2, #13*4 0: ????//读取R0所指的项的值到R3中后R0自加4字节 ????ldr r3, [r0], #4 ????//将R3中的值保存到R1所指的地址中后R1自加4字节 ????str r3, [r1], #4 ????//比较R0和R2是否相等,相等则说明13个寄存器全部设置完毕 ????cmp r2, r0 ????//不等则跳转到上面标号为0处的地址继续执行 ????bne 0b ????//跳回到返回地址中继续执行 ????mov????pc, lr ????.ltorg /* the literal pools origin */ SMRDATA: ????.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) ????.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ????.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ????.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ????.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ????.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ????.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ????.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ????.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ????.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) ????.word 0x32 ????.word 0x30 ??? .word 0x30 |
执行mov? pc,lr后将返回到cpu_init_crit中 剩下来还有2条指令
????//恢复返回地址到LR ????mov????lr, ip ????//跳转到返回地址 ????mov????pc, lr |
执行完毕之后将返回到start_code中执行接下来的代码 代码如下:
??????? //#define GPJCON 0x560000D0 ??????? //取得J端口控制寄存器的地址到R0中 ????????LDR R0, = GPJCON ????????//将R1设置为0x1 5555 ????????LDR R1, = 0x15555 ????????//将R1中的值保存到J端口控制寄存器 ????????//GPJ0 - 01 - Output ????????//GPJ1 - 01 - Output ????????//GPJ2 - 01 - Output ????????//GPJ3 - 01 - Output ????????//GPJ4 - 01 - Output ????????STR R1, [R0] ????????//#define GPJUP????????0x560000D8 ??????? //取得J端口上拉功能寄存器的地址到R0中 ????????LDR R0, = GPJUP ????????//将R1设置为0x1F ????????LDR R1, = 0x1f ????????//将R1中的值保存到J端口上拉功能寄存器 ????????//禁止GPJ0 - GPJ4的上拉功能 ????????STR R1, [R0] ????????//#define GPJDAT 0x560000D4 ??????? //取得J端口数据寄存器的地址到R0中 ????????LDR R0, = GPJDAT ????????//将R1设为0x0 ????????LDR R1, = 0x00 ????????//将R1中的值保存到J端口数据寄存器 ????????//将J端口数据寄存器清0 ????????STR R1, [R0]
//下面是NAND数据拷贝过程
//relocate: copy_myself: ????//#define S3C2440_NAND_BASE????????0x4E000000 ????//取得Nand Flash设置寄存器的地址 ????mov????r1, #S3C2440_NAND_BASE ????//将R2设为0xFFF0 ????ldr????r2, =0xfff0????????// initial value tacls=3,rph0=7,rph1=7 ????//#define oNFCONF????????????0x00 ????//读取Nand Flash设置寄存器中的值到R3中 ????ldr????r3, [r1, #oNFCONF] ????//将R3或上R2后保存到R3中 ????orr????r3, r3, r2 ????//将R3中的值保存到Nand Flash设置寄存器中 ????//TWRPH0 - 111 - Duration = HCLK * (TWRPH0 + 1) ????//TACLS - 11 - Duration = HCLK * TACLS ????str????r3, #oNFCONF] ????//#define oNFCONT????????????0x04 ????//读取Nand Flash控制寄存器中的值到R3中 ????ldr????r3, #oNFCONT] ????//将R3的[0]位置1 ????orr????r3, #1????????// enable nand controller ????//将R3中的值保存到Nand Flash控制寄存器中 ????//Mode - 1:Nand Flash Controller Enable ????str????r3, #oNFCONT] ????//读取虚拟起始地址到R0中 ????ldr????r0, _TEXT_BASE????????/* upper 128 KiB: relocated uboot */ ????//预留malloc所需要的空间 ????sub????r0, #CFG_MALLOC_LEN????/* malloc area */ ????//预留bdinfo所需要的空间 ????sub????r0, #CFG_GBL_DATA_SIZE /* bdinfo */ ????//预留中断和快速中断向量表空间 ????sub????r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) ????//预留12字节给中断栈 ????sub????sp, #12????????/* leave 3 words for abort-stack */ ????// copy u-boot to RAM ????//读取虚拟起始地址到R0中,作为目标地址 ????ldr????r0, _TEXT_BASE ????//将R1设为0,作为源地址 ????mov r1, #0x0 ????//将UBOOT大小的值保存在R2中,作为数据大小 ????mov????r2, #CFG_UBOOT_SIZE ????//跳转到nand_read_ll处执行 ????//并将下一条指令的地址保存在LR中 ????bl????nand_read_ll |
nand_read_ll的原型为 int nand_read_ll(unsigned char *buf,unsigned long start_addr,int size) 之前设置的R0 R1 R2为它的3个参数 R0 - buf R1 - start_addr R2 - size
nand_read_ll的代码在cpu/arm920t/s3c24x0/nand_read.c中
int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) { ????int i, j; ????//检测源地址和大小是否在NandFlash的边界上 ????if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) ????????//不在边界上则返回-1表示出错 ????????return -1;????/* invalid alignment */ ????/* chip Enable */ ????// #define nand_select()????(NFCONT &= ~(1 << 1)) ????//置NAND Flash控制寄存器中除Reg_nCE外所有的位为1 ????//Reg_nCE - NAND FLASH Memory nFCE signal control ????//0 - Force nFCE to low (Enable chip select) ????nand_select(); ????// #define nand_clear_RnB()????(NFSTAT |= (1 << 2)) ????//置NAND Flash操作状态寄存器中的RnB_TransDetect位为1 ????//When RnB low to high transition is occurred,this value set and issue interrupt if enabled.? ????//To clear this value write '1' ????//1: RnB transition is detected ????nand_clear_RnB(); ????for (i=0; i<10; i++); ????//从源地址的首地址开始历便所要拷贝的数据大小 ????for (i=start_addr; i < (start_addr + size);) ????{ ????????//检测地址是否在NAND Flash的边界上 ????????if (start_addr % NAND_BLOCK_SIZE == 0) ????????{ ????????????//检测是否为坏块 ????????????if (is_bad_block(i)) ????????????{ ????????????????/* Bad block */ ????????????????//向后延伸一个存储块 ????????????????i += NAND_BLOCK_SIZE; ????????????????size += NAND_BLOCK_SIZE; ????????????????//跳到下一块 ????????????????continue; ????????????} ????????} ????????j = nand_read_page_ll(buf, i); ????????//指向下一块 ????????i += j; ????????buf += j; ????//????LED_FLASH(); ????} ????/* chip Disable */ ????// #define nand_deselect()????(NFCONT |= (1 << 1)) ????//置Reg_nCE位为1 ????//NAND Flash Memory nFCE signal control ????//1: Force nFCE to High(Disable chip select) ????nand_deselect(); ????return 0; } |
nand_read_ll将Uboot从NAND中拷贝到RAM中
拷贝完成后将返回到start_code 接下来的代码如下:
????//检测R0是否为0,R0为nand_read_ll的返回值 ????tst????r0, #0x0 ????//为0则说明无错,跳转到ok_nand_read处执行 ????beq????ok_nand_read ok_nand_read: ????//将R0设为0 ????mov????r0, #0 ????//ldr????r1,=0x33f00000 ????//将R1设为虚拟地址起始处 ????ldr????r1, _TEXT_BASE ????//检测0x400个字节 ????mov????r2, #0x400????// 4 bytes * 1024 = 4K-bytes go_next: ????//读取R0处地址的数据到R3中 ????//然后R0自加4字节 ????ldr????r3, #4 ????//读取R1处地址的数据到R4中 ????//然后R1自加4字节 ????ldr????r4, #4 ????//比较R3和R4的数据是否相等 ????//也就是检测Boot Internal SRAM和RAM中的数据是否相等 ????//以保证数据无错 ????teq????r3, r4 ????//不等则跳转到notmatch ????bne????notmatch ????//相等则R2自减4 ????subs????r2, r2, #4 ????//当R2为0则跳转到done_nand_read ????beq????done_nand_read ????//R2不为0则跳转回go_next继续检测 ????bne????go_next done_nand_read: ??? LDR R0, = GPJDAT ??? LDR R1, = 0x2 ??? STR R1, [R0] stack_setup: ????//读取虚拟起始地址到R0中 ????ldr????r0, #12????????/* leave 3 words for abort-stack */ clear_bss: ????//读取BSS段的起始地址 ????ldr????r0, _bss_start????????/* find start of bss segment */ ????//读取BSS段的结束地址 ????ldr????r1, _bss_end????????/* stop here */ ????//将R2设为0x0 ????mov ????r2, #0x00000000????????/* clear */ clbss_l: ????//将R2中的值保存在R0所指的地址 ????str????r2, [r0]????????/* clear loop... */ ????//R0自加4字节 ????add????r0, #4 ????//比较R0和R1是否相等 ????cmp????r0, r1 ????//不等则说明清0还没结束 ????ble????clbss_l ??? LDR R0, = 0x1 ??? STR R1, [R0] ????//跳转到start_armboot处执行 ????ldr????pc, _start_armboot
_start_armboot:????.word start_armboot
|
这里start_armboot是一个绝对地址,在朗成所修改的这个Uboot中为0x33F8 13F4 执行ldr?pc,_start_armboot之后将会跳到RAM中的绝对地址继续执行
整理了一个流程图,分为3个存储器: 1 Boot Internal SRAM,接在BANK0,起始地址为0x0 2 RAM,接在BANK6,起始地址为0x3000 0000 3 NAND FLASH,为单独寻址 流程如下图:
红字为流程序号:
1.?首先将NAND FLASH中的前0x1000字节内容拷贝到Boot Internal SRAM中
2.?从Boot Internal SRAM的0x0地址处开始执行指令
3.?将Uboot从Flash拷贝到RAM中
4.?执行ldr?pc,_start_armboot
从Boot Internal SRAM中跳转到RAM中的绝对地址0x33F8 13F4处继续执行
?
在汇编中,像这样的代码
mcr?p15,r0,0
为操作协处理器
详细的操作可以看ARM920T? Technical Reference Manual
?
还有就是关于端口J的操作~
我看了一下AT2440EVB的原理图,端口J是连接到了Camera上,不知道具体有什么用处了~ -_- 又不是操作LED
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|