求助优龙BIOS,nand_boot_beg段分析!
我对汇编不是很熟悉,看论坛里面有几个DX搞过这个,所以想请教下:
情况是:用AXD调试,bios可以起来!烧写到nandflash中后,就不可以了,所以就是nand_boot_beg段有问题了,
没有将nandflash中的代码搬到ram中去!
nand_boot_beg代码如下
- nand_boot_beg
-
- mov r5, #NFCONF
- bl ReadNandID
- mov r6, #0
- ldr r0, =0xecda ;我要改的flash的ID是0xecda
- cmp r5, r0 ;
- beq %F1;
- ldr r0, =0xec73 ;这里很不解,之前的是K9F1208,ID是0xec76, 但是原来的代码里面 判断的是0xec73和0xec75!
- cmp r5, r0
- beq %F1
- mov r6, #1
- 1
- bl ReadNandStatus
- mov r8, #0
- ldr r9, =ResetEntry ;ro base addr
- 2
- ands r0, r8, #0x3f ;原来是0x1f ,应该是0~31吧,现改为0x3f=61,
- ;ands作用:r0=r8&0x3f,并设置相应寄存器
- bne %F3
- [color=#FF0000];bne 是不相等测跳到3, 这里是在判断 什么和什么 不相等?[/color]
-
- mov r0, r8
- bl CheckBadBlk
- cmp r0, #0
- addne r8, r8,#64 ;原来是#32
- bne %F4
- 3
- ;no entry
- mov r0, r8
- mov r1, r9
- bl ReadNandPage
- add r9, r9, #2048 ; 原来是512 ;每页的大小
- add r8, r8, #1 ;指向下一页
- 4
-
- cmp r8, #64 ;默认读的大小 64*2K
- bcc %B2 ;
-
- mov r5, #NFCONF ;DsNandFlash
- ldr r0, [r5,#4]
- orr r0, r0, #0x2
- str r0, [r5,#4]
- ;到了这里
- ldr pc, =copy_proc_beg ;这里肯定是进步到了,
-
- ;标号2、3、4代码段的执行逻辑是什么:
- ;我的分析:先读一块(ands r0, r8, #0x3f |bne %F3 和3段代码应该是实现读一块的代码),在判断是否是坏块 (mov r0, r8 | bl CheckBadBlk)
- ;如果是则跳过这一块( cmp r0, #0 | addne r8, r8,#64 ),然后,跳到4块判断是否读完规定量数据,如果没有,再跳转到2块,循环.....
-
- ;【问题是:】现在从未进入3段代码,不知道是怎么回事
平台:2440 K9F2G08 flash
上一周 弄KEIL ,一直没搞少,现在转到ADS了 ,果然好多了
ands r0, r8, #0x3f
bne %F3
是什么意思?
bne 是不相等测跳到3, 这里是在判断 什么和什么 不相等?
ands r0, r8, #0x3f
bne %F3
这个的意思是看 r8 是不是一个block的第一个扇区的地址
如果是的话,后多少位会是0
如果是一个block的第一个扇区就执行CheckBadBlk
如果不是的话就直接读数据
ReadNandPage
这个函数也要相应修改的,LZ看一下.
引用: 引用 4 楼 reallyu 的回复:
ands r0, r8, #0x3f
bne %F3
这个的意思是看 r8 是不是一个block的第一个扇区的地址
就看作为页计数的r8是不是64的整数倍,如果是整数倍那么就是block的第一个扇区了,那么在3段代码执行后下一步执行什么,3段是读一页的操作吧!
如果是的话,后多少位会是0
如果是一个block的第一个扇区就执行CheckBadBlk
如果不是的话就直接读数据
ReadNandPage
这个函数也要相应修改的,LZ看一下.
ReadNandPage 如下
- ReadNandPage
- mov r7,lr
- mov r4,r1
- mov r5,#NFCONF
- ldr r1,[r5,#4] ;NFChipEn()
- ldr r2, =0xfffc
- and r1, r1, r2
- orr r1, r1, #1
- str r1,[r5,#4]
- mov r1,#0 ;WrNFCmd(READCMD0)
- strb r1,[r5,#8] ;
-
- ;-->原数据
- ;strb r1,[r5,#0xc] ;WrNFAddr(0)
- ;strb r0,[r5,#0xc] ;WrNFAddr(addr)
- ;mov r1,r0,lsr #8 ;WrNFAddr(addr>>8)
- ;strb r1,[r5,#0xc]
- ;cmp r6,#0 ;if(NandAddr)
- ;movne r0,r0,lsr #16 ;WrNFAddr(addr>>16)
- ;strneb r0,[r5,#0xc]
- ;<----
-
-
- strb r1,[r5,#0xc] ;0
- strb r1,[r5,#0xc] ;0
- strb r0,[r5,#0xc] ;WrNFAddr(addr)
- mov r1,r0,lsr #8 ;
- strb r1,[r5,#0xc] ;WrNFAddr(addr>>8)
-
- mov r0,r0,lsr #16 ;WrNFAddr(addr>>16)
- strb r0,[r5,#0xc]
-
- mov r1,#0x30
- strb r1,[r5,#8] ;WrNFCmd(READCMD0)
-
-
- ; ldr r0,[r5,#4] ;InitEcc()
- ; orr r0,r0,#0x10
- ; str r0,[r5,#4]
-
- wait
- ldr r0,[r5,#0x20]
- and r0,r0,#1
- cmp r0,#1
- bne wait
-
-
- ; bl WaitNandBusy ;WaitNFBusy()
-
- mov r0,#0 ;for(i=0; i<2048 i++) r0为通用寄存器,这里做循环计数
- 1
- ldrb r1,[r5,#0x10] ;buf[i] = RdNFDat()
- strb r1,[r4,r0]
-
- add r0,r0,#1
- bic r0,r0,#0x10000
- cmp r0,#0x800 ;cmp r0,#0x200.....0x800=2048Bytes
- bcc %B1 ;bcc 小于,则跳转
-
- ldr r0,[r5,#4] ;NFChipDs()
- orr r0,r0,#0x2
- str r0,[r5,#4]
-
- mov pc,r7
我的这个问题跟这个贴很像,但这个贴也没说明是什么问题,自己汇编有残像 所以高秋不来
[url=http://topic.eeworld.net/u/20081120/23/42e41867-46d5-4f39-89e5-67d8053c3feb.html][/url]
引用: 引用 3 楼 trueman_onlyme 的回复:
ands r0, r8, #0x3f?
bne %F3
是什么意思?
bne 是不相等测跳到3,? ? ? 这里是在判断? 什么和什么 不相等?
这部分其实没有必要,因为前面的block不需要检测坏块的。
从来都没有进入代码段3
说明检测坏块的函数有问题,把所有的块都当成坏块了.
检测坏块还是有必要的,nandflash一般只保证第一个block不是坏块,后面的就难讲了.
你的boot肯定不止占了第一个block.
我还得仔细看看! 谢谢gooogleman 和Reallyu!
回gooogleman 和Reallyu:
我的boot共40K,只占第一个blokc的前20个page,
ands r0, r8, #0x3f
bne %F3
在刚开始r8为0,跟0x3f相与,结果为0,是不是eq有效,ne无效,所以先检查坏块?,还是刚开始就跳到3段了,
bne %F3 在和什么比较 ? 标志位?
我得研究一下CheckBadBlk了,
判断 ands r0, r8, #0x3f 这个运算造成的标志位改变
一上来就先检查坏块,如果你的boot比一个block小,这一段是可以不要.
我终于懂了都乖自己的汇编功底不够,在这里再分析一下,请各位帮忙指正:
- nand_boot_beg
-
- mov r5, #NFCONF
- bl ReadNandID
- mov r6, #0
- ldr r0, =0xecda
- cmp r5, r0 ;
- beq %F1;
- ldr r0, =0xec73
- cmp r5, r0
- beq %F1
- mov r6, #1
- 1
- bl ReadNandStatus
- mov r8, #0
- ldr r9, =ResetEntry ;ro base addr
- 2
- ands r0, r8, #0x3f
- bne %F3
- [b]最先执行这里,bne %F3 判断标志位是否改变,如果改变说明已经是当前块的首页了,那么就执行后面的 CheckBadBlk,反之,则跳到3段代码中,直接读取数据 因为我的bios远小于一个block得大小,所以,不用检测坏块,我把下面的代码屏蔽了,就可以直接进入3段,读代码,一直到规定的页数。就跳到 copy_proc_beg 中去[/b]
- ;mov r0, r8
- ; bl CheckBadBlk
- ;cmp r0, #0
- ;addne r8, r8,#64 ;原来是#32
- ; bne %F4
- 3
- ;no entry
- mov r0, r8
- mov r1, r9
- bl ReadNandPage
- add r9, r9, #2048 ; 原来是512 ;每页的大小
- add r8, r8, #1 ;指向下一页
- 4
-
- cmp r8, #64 ;默认读的大小 64*2K
- bcc %B2 ;
-
- mov r5, #NFCONF ;DsNandFlash
- ldr r0, [r5,#4]
- orr r0, r0, #0x2
- str r0, [r5,#4]
- ;到了这里
- ldr pc, =copy_proc_beg ;这里肯定是进步到了,
这个事我滴判断是否是坏块的函数,贴上来帮分析下
static int CheckBadBlk(U32 addr)
{
U8 dat;
addr &= ~0x3f;
NFChipEn();
WrNFCmd(0x00);
WrNFAddr(2048); //第2049字节存放 标记信息
WrNFAddr(2048>>8);
WrNFAddr(addr);
WrNFAddr(addr>>8);
WrNFAddr(addr>>16);
WaitNFBusy();
WrNFCmd(0x30);
dat = RdNFDat();
dat=0xff;
if(dat!=0xff)
{
return TRUE; //是坏块
}
NFChipDs();
//return (dat!=0xff);
return (FALSE);
}