上一个笔记中Uboot从SDRAM启动,已经正常驱动nand flash,这里主要描述uboot的nand启动,其实主要了解nand启动的原理,nand启动的移植也是比较简单,但是由于调试麻烦,nand启动以前一直没有正常,到目前为止才真正实现uboot的nand启动,以下主要说明s3c6410 nand启动的基本原理与移植的过程。
1.当设备选择nand启动,s3c6410 后设备会自动拷贝nand前8k的程序到sdram中运行,但是需要注意的是,如果是nand自动拷贝的时候nand读取的时候是按照最大2k一页的方式来读取。对于4K一页的nand,s3c6410 只能读取一页的前2k。具体参见下图。
2.由于以上原因,对于4k一页的nand在写入uboot的时候,对应的也需要对于nand的前面的8k进行特殊方式写于,如果是充内存写入,网上提供的指令为:
假设通过DNW把文件放在0X50008000这个位置上。
第一:把50008000写入NAND的0地址上,每次写入大小都是一个page(4K)。
nand write 50008000 0 1000
第二:把50008800写入NAND的1000地址上。
nand write 50008800 1000 1000
第三:把50009000写入NAND的2000地址上。
nand write 50009000 2000 1000
第四:把50009800写入NAND的3000地址上。
nand write 50009800 3000 1000
最后,把剩余的写完:nand erase 0 100000
nand write 5000a000 4000 fe000
3.如果是能确认uboot能够正确的写入nand,那剩下的事情就是启动与拷贝了。首先启动的前面4k的代码可以完全的正常运行的这个不要去怀疑,程序启动后会运行start.S,在这个程序中屏蔽掉内存跳转的代码具体参考
,在start.S中调用了low_init.S具体修改参考
,什么事情都不用做了直接调用nand_boot之后进行拷贝,拷贝完成后,直接跳转到sdram运行。
4.而nand_boot的可以直接参考ok6410官方的程序见附件。
5.制作用于烧录到nand的u-boot-nand.bin文件
。
如果我们编译的u-boot-spl-16k小于4k,那么我们需要自己把它补充到4K再放到u-boot.bin的开头,合成一个u-boot-nand.bin。嫌hex手工修改麻烦的话,也可以在建立一个文件create_nand_bin,内容如下:
#!/bin/sh
rm -f u-boot-nand.bin
n=16384; while (($$n>0)); do echo -e -n '\x0' >> $(obj)movi-env-zero-16k.bin; n=$$(($$n-1)); done;
cat nand_spl/u-boot-spl-16k.bin >> temp
cat movi-env-zero-16k.bin >> temp
split -b 4k temp
mv xaa u-boot-4k.bin
cat u-boot-4k.bin >> u-boot-nand.bin
cat u-boot.bin >> u-boot-nand.bin
mkdir splitfile
cat u-boot-nand.bin >> ./splitfile/temp
split -b 2k ./splitfile/temp ./splitfile/split
mv ./splitfile/splitaa u-boot-4knand.bin
cat ./splitfile/splitab >> u-boot-4knand.bin
cat ./splitfile/splitab >> u-boot-4knand.bin
cat ./splitfile/splitac >> u-boot-4knand.bin
cat ./splitfile/splitac >> u-boot-4knand.bin
cat ./splitfile/splitad >> u-boot-4knand.bin
cat ./splitfile/splitad >> u-boot-4knand.bin
cat ./splitfile/splitae >> u-boot-4knand.bin
cat ./splitfile/splitae >> u-boot-4knand.bin
rm ./splitfile/splitab
rm ./splitfile/splitac
rm ./splitfile/splitad
rm ./splitfile/splitae
cat ./splitfile/split* >> u-boot-4knand.bin
rm -f temp
rm -f u-boot-4k.bin
rm -f xa*
rm -f $(obj)movi-env-zero-16k.bin
rm -r -f splitfile
root@ubuntu:/home/my/u-boot-2012.10# ./create_nand_bin
这时在当前目录下就有一个可以烧录的u-boot-nand.bin和u-boot-4knand.bin.其中u-boot-nand.bin需要使用上面提及的5挑指令进行少些,而u-boot-4knand.bin直接使用nand write 50008000 0 100000一条指令进行烧写即可。
当然也可以直接修改Makefile文件,屏蔽之前的指令
# cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin
rm -f u-boot-nand.bin
cat $(obj)nand_spl/u-boot-spl-16k.bin >> $(obj)temp
cat $(obj)movi-env-zero-16k.bin >> $(obj)temp
split -b 4k $(obj)temp
mv $(obj)xaa $(obj)u-boot-4k.bin
cat $(obj)u-boot-4k.bin >> $(obj)u-boot-nand.bin
cat $(obj)u-boot.bin >> $(obj)u-boot-nand.bin
mkdir splitfile
cat $(obj)u-boot-nand.bin >> $(obj)splitfile/temp
split -b 2k $(obj)splitfile/temp $(obj)splitfile/split
mv $(obj)splitfile/splitaa $(obj)u-boot-4knand.bin
cat $(obj)splitfile/splitab >> $(obj)u-boot-4knand.bin
cat $(obj)splitfile/splitab >> $(obj)u-boot-4knand.bin
cat $(obj)splitfile/splitac >> $(obj)u-boot-4knand.bin
cat $(obj)splitfile/splitac >> $(obj)u-boot-4knand.bin
cat $(obj)splitfile/splitad >> $(obj)u-boot-4knand.bin
cat $(obj)splitfile/splitad >> $(obj)u-boot-4knand.bin
cat $(obj)splitfile/splitae >> $(obj)u-boot-4knand.bin
cat $(obj)splitfile/splitae >> $(obj)u-boot-4knand.bin
rm $(obj)splitfile/splitab
rm $(obj)splitfile/splitac
rm $(obj)splitfile/splitad
rm $(obj)splitfile/splitae
cat $(obj)splitfile/split* >> $(obj)u-boot-4knand.bin
rm -f $(obj)temp
rm -f $(obj)u-boot-4k.bin
rm -f $(obj)xa*
rm -r -f $(obj)splitfile
另外在make smdk_6410config的最后面添加
rm -f $(obj)movi-env-zero-16k.bin
n=16384; while (($$n>0)); do echo -e -n '\x0' >> $(obj)movi-env-zero-16k.bin; n=$$(($$n-1)); done;
意思是新建一个16k的空文件