1、.global _start_start:bl disable_watch_dog 关闭WATCHDOG,否则CPU会不断重启 bl memsetup 设置存储控制器 copy_steppingstone_to_sdram 复制代码到SDRAM中ldr pc, =on_sdram 跳到SDRAM中继续执行on_sdram: ldr sp, =0x34000000 设置堆栈 mainhalt_loop: b halt_loopdisable_watch_dog: 往WATCHDOG寄存器写0即可 mov r1, #0x53000000 mov r2, #0x0 str r2, r1 mov pc
2、, lr 返回copy_steppingstone_to_sdram: 将Steppingstone的4K数据全部复制到SDRAM中去 Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000 mov r1, #0 ldr r2, =SDRAM_BASE mov r3, #4*10241: ldr r4, r1,#4 从Steppingstone读取4字节的数据,并让源地址加4 str r4, r2,#4 将此4字节的数据复制到SDRAM中,并让目地地址加4 cmp r1, r3 判断是否完成:源地址等于Steppingstone的未地址? bne
3、1b 若没有复制完,继续memsetup: 设置存储控制器以便使用SDRAM等外设 #MEM_CTL_BASE 存储控制器的13个寄存器的开始地址 adrl r2, mem_cfg_val 这13个值的起始存储地址 add r3, r1, #52 13*4 = 54 ldr r4, r2, #4 读取设置值,并让r2加4 str r4, r1, #4 将此值写入寄存器,并让r1加4 cmp r1, r3 判断是否设置完所有13个寄存器 若没有写成,继续.align 4mem_cfg_val: 存储控制器13个寄存器的设置值 .long 0x22011110 BWSCON 0x00000700
4、BANKCON0 BANKCON1 BANKCON2 BANKCON3 BANKCON4 BANKCON5 0x00018005 BANKCON6 BANKCON7 0x008C07A3 REFRESH 0x000000B1 BANKSIZE 0x00000030 MRSRB6 MRSRB7下面来看看反汇编代码sdram_elf: file format elf32-littlearmDisassembly of section .text:30000000 :30000000: eb000005 3000001c 30000004:eb000010 3000004c 30000008:eb0
5、00007 3000002c 3000000c:e59ff090 ldrpc, pc, #144; 300000a4 30000010 30000010:e3a0d30d movsp, #872415232 0x3400000030000014:eb000033 300000e8 30000018 30000018:eafffffe b3000001c:e3a01453 r1, #1392508928 0x5300000030000020:e3a02000 r2, #030000024:e5812000 strr2, r130000028:e1a0f00e pc, lr3000002c:e3a
6、01000 r1, #030000030:e3a02203 r2, #80530636830000034:e3a03a01 r3, #4096 0x100030000038:e4914004 r4, r1, #43000003c:e4824004 r4, r2, #430000040:e1510003 cmpr1, r330000044:1afffffb bne30000038 30000048:3000004c:e3a01312 r1, #120795955230000050:e28f2018 addr2, pc, #2430000054:e1a00000 nop (mov r0, r0)3
7、0000058:e2813034 r3, r1, #52 0x343000005c:e4924004 30000060:e4814004 30000064:30000068:3000005c 3000006c:30000070 30000070:22011110 andcsr1, r1, #430000074:00000700 andeqr0, r0, r0, lsl #1430000078:3000007c:30000080:30000084:30000088:3000008c:00018005 r8, r1, r530000090:30000094:008c07a3 addeqr0, ip
8、, r3, lsr #1530000098:000000b1 strheqr0, r0, -r13000009c:00000030 r0, r0, r0, lsr r0300000a0:300000a4:30000010andccr0, r0, r0, lsl r0300000a8:300000ac:300000b0 300000b0:e52db004 pushfp (str fp, sp, #-4!)300000b4:e28db000 fp, sp, #0300000b8:e24dd00c subsp, sp, #12300000bc:e50b0008 r0, fp, #-8300000c0
9、:ea000002 300000d0 300000c4:e51b3008 r3, fp, #-8300000c8:e2433001 r3, r3, #1300000cc:e50b3008 300000d0:300000d4:e3530000 r3, #0300000d8:1afffff9 300000c4 300000dc:e28bd000 sp, fp, #0300000e0:e8bd0800 popfp300000e4:e12fff1e bxlr300000e8:e92d4800 fp, lr300000ec:e28db004 fp, sp, #4300000f0:e24dd008 sp,
10、 sp, #8300000f4:e3a03000 300000f8:300000fc:e59f3030 r3, pc, #48 30000134 30000100:e3a02b55 r2, #87040 0x1540030000104:e5832000 r2, r330000108:e59f0028 r0, pc, #40 30000138 3000010c:ebffffe7 30000110:e59f3024 r3, pc, #36 3000013c 30000114:30000118:3000011c:e59f0014 r0, pc, #2030000120:ebffffe2 300001
11、24:e59f3010 r3, pc, #1630000128:e3a02e1e r2, #480 0x1e03000012c:30000130:eafffff4 30000108 30000134:56000010 undefined instruction 0x5600001030000138:00007530 r7, r0, r0, lsr r53000013c:56000014 undefined instruction 0x56000014Disassembly of section .ARM.attributes:00000000 0:00002541 r2, r0, r1, as
12、r #10 4:61656100 cmnvsr5, r0, lsl #2 8:01006962 tsteqr0, r2, ror #18 c:0000001b r0, r0, fp, lsl r0 10:00543405 subseqr3, r4, r5, lsl #8 14:01080206 r8, r6, lsl #4 18:04120109 ldreqr0, r2, #-265 0x109 1c:01150114 r5, r4, lsl r1 20:01180317 r8, r7, lsl r3 24:Address 0x00000024 is out of bounds.Disasse
13、mbly of section .comment:.comment3a434347 bcc10d0d24 74632820 strbtvcr2, r3, #-2080 0x820312d676e teqccsp, lr, ror #14312e362e lr, lr, lsr #122e342029 cdpcs0, 3, cr2, cr4, cr9, 100332e34 eorseqr2, r3, r4, lsr lr当我们从Nand flash启动时,硬件会自动将Nand flash前4kB代码拷贝到片内SRAM中,然后CPU从SRAM的0x00000000地址处开始执行程序。在这里我想纠正
14、一个错误的观点,网上很多人都说是CPU自动把Nand flash前4kB代码拷贝到片内SRAM中,其实不然,是Nand flash控制器完成的,这个过程中CPU根本就没有参与 。通过上面的Makefile文件,我们可以知道 bl这条指令的运行地址是0x30000000,但是它现在保存在SRAM的0x00000000的地址处,那么这条指令能够正确执行吗?of course,why?因为这条指令是位置无关码,虽然它的运行地址是在SDRAM中的0x30000000,但是它可以在Steppingstone中执行。这条指令的功能是跳转到标号disable_watch_dog处执行,它是一个相对跳转,PC
15、=当前PC的值+偏移量OFFSET。其中当前PC的值等于下两条指令的地址,通过反汇编可以看到下两条指令的地址为0x0000 0008,而不是0x3000 0008.因为现在指令是保存在SRAM中。这条指令的机器码为eb00 0005,将机器码低24位按符号位扩展成32位得到0x0000 00005.然后将0x0000 0005左移2位得到0x0000 0014。这个值就是偏移量OFFSET=0X0000 0014。所以PC=0X0000 0008+0X0000 0014=0X0000 001c.那么CPU就会到SRAM中的0x0000 001c地址处执行程序。可以发现bl指令依赖当前PC的值,
16、这个特性使得bl指令不依赖指令的运行地址。所以接下来的bl mensetup ,bl cope_steppingstone_to_sdram都能够执行。接下来的ldr pc,=on_sdram是一条位置有关码,经过反汇编可以看到,它是当前pc的值+偏移量,得到一个地址Addr,然后从内存中的这个地址去取数据Data赋给pc。现在我们计算一下Addr这个地址。Addr=当前PC的值+144。当前PC的值等于下两条指令的地址0x0000 0014,而不是0x3000 0014,因为现在程序是保存在SRAM中。所以Addr=0x0000 0014+144=0x0000 0014+0x0000 009
17、0=0x0000 00a4.那么这个地址0x0000 00a4中保存了什么数据。通过反汇编可以看到SRAM中的0x0000 00a4这个地址保存的机器码为30000010,所以cpu会跳转到0x30000010这个地址处执行程序。这个地址0x30000010是在SDRAM中,这样程序就跳到SDRAM中去了。因为我们前面的指令 bl cope_stepping_to_sdram 已经把SRAM中4kB的程序拷贝到了SDRAM中,所以现在SDRAM中有程序了。但是如果在程序的开头放置一条这样的指令:ldr pc,=disable_watch_dog ,那么整个程序就不能够正确执行了。why?我们先来看看启动代码*
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1