S3C2440平台下调试u-boot的方法——代码加载
Author:梁桥江 转载请注明出处
本人曾经在csdn上发布了一篇<<调试u-boot的方法>>,该文章具有局限性,因为它把代码加载(代码从nand flash到SDRAM的搬移)部分代码注释掉了。这篇文章就是要讨论在<<调试u-boot的方法>>基础上,加入代码加载的调试,所以在阅读本文前,先要读懂<<调试u-boot的方法>>。
一. 代码加载源码:
//下面添加2440中u-boot从Nand Flash启动
#ifdef CONFIG_S3C2440_NAND_BOOT
mov r1, #NAND_CTL_BASE //复位Nand Flash
ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
str r2, [r1, #oNFCONF] //设置配置寄存器的初始值,参考s3c2440手册
ldr r2, [r1, #oNFCONF]
ldr r2, =( (1<<4)|(0<<1)|(1<<0) )
str r2, [r1, #oNFCONT] //设置控制寄存器
ldr r2, [r1, #oNFCONT]
ldr r2, =(0x6) //RnB Clear
str r2, [r1, #oNFSTAT]
ldr r2, [r1, #oNFSTAT]
mov r2, #0xff //复位command
strb r2, [r1, #oNFCMD]
mov r3, #0 //等待
nand1:
add r3, r3, #0x1
cmp r3, #0xa
blt nand1
nand2:
ldr r2, [r1, #oNFSTAT] //等待就绪
tst r2, #0x4
beq nand2
ldr r2, [r1, #oNFCONT]
orr r2, r2, #0x2 //取消片选
str r2, [r1, #oNFCONT]
//get read to call C functions (for nand_read())
ldr sp, DW_STACK_START //C代码准备堆栈,DW_STACK_START定义在下面
mov fp, #0
//copy U-Boot to RAM
ldr r0, =TEXT_BASE
mov r1, #0x0
mov r2, #0x30000
bl nand_read_ll
tst r0, #0x0
beq ok_nand_read
bad_nand_read:
loop2: b loop2 //infinite loop
ok_nand_read:
//检查搬移后的数据,如果前4k完全相同,表示搬移成功
mov r0, #0
ldr r1, =TEXT_BASE
mov r2, #0x400 //4 bytes * 1024 = 4K-bytes
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne notmatch
subs r2, r2, #4
beq stack_setup
bne go_next
notmatch:
loop3: b loop3 //infinite loop
#endif //CONFIG_S3C2440_NAND_BOOT
上面那段代码,如果你的开发板只有nand flash而没有nor flash, 而且亲自移植过u-boot的朋友,那么一定不会陌生,它就是开发板上电后把nand flash里面的u-boot搬移到SDRAM的代码(该代码基本上全世界都是这样写的)。
从代码上看,该段代码主要是从nand flash的0地址把u-boot搬移到SDRAM的TEXT_BASE开始的地方,然后把S3C2440从0到0x1000的4K SRAM的内容与TEXT_BASE开始的4K内容相比,如果完全一样,代码加载成功,否则失败。
根据上面分析,我们只需要修改几个地址,即可在不烧写nand flash的情况下实现调试上面代码。
二. 修改以后的代码
//下面添加2440中u-boot从Nand Flash启动
#ifdef CONFIG_S3C2440_NAND_BOOT
mov r1, #NAND_CTL_BASE //复位Nand Flash
ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
str r2, [r1, #oNFCONF] //设置配置寄存器的初始值,参考s3c2440手册
ldr r2, [r1, #oNFCONF]
ldr r2, =( (1<<4)|(0<<1)|(1<<0) )
str r2, [r1, #oNFCONT] //设置控制寄存器
ldr r2, [r1, #oNFCONT]
ldr r2, =(0x6) //RnB Clear
str r2, [r1, #oNFSTAT]
ldr r2, [r1, #oNFSTAT]
mov r2, #0xff //复位command
strb r2, [r1, #oNFCMD]
mov r3, #0 //等待
nand1:
add r3, r3, #0x1
cmp r3, #0xa
blt nand1
nand2:
ldr r2, [r1, #oNFSTAT] //等待就绪
tst r2, #0x4
beq nand2
ldr r2, [r1, #oNFCONT]
orr r2, r2, #0x2 //取消片选
str r2, [r1, #oNFCONT]
//get read to call C functions (for nand_read())
ldr sp, DW_STACK_START //C代码准备堆栈,DW_STACK_START定义在下面
mov fp, #0
//copy U-Boot to RAM
ldr r0, =0x32000000
mov r1, #0x0
mov r2, #0x30000
bl nand_read_ll
tst r0, #0x0
beq ok_nand_read
bad_nand_read:
loop2: b loop2 //infinite loop
ok_nand_read:
//检查搬移后的数据,如果前4k完全相同,表示搬移成功
ldr r0, = 0x33f80000
ldr r1, =0x32000000
mov r2, #0x400 //4 bytes * 1024 = 4K-bytes
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne notmatch
subs r2, r2, #4
beq stack_setup
bne go_next
notmatch:
loop3: b loop3 //infinite loop
#endif //CONFIG_S3C2440_NAND_BOOT
修改成上面代码以后,就相当于把nand flash里的u-boot搬移到SDRAM 0x32000000开始的地方,然后用SDRAM 0x33f80000开始前4K与0x3200000开始前4K内存相比,如果完全一样说明代码加载成功了,调试完成。