当体系以Nand方法发动时,硬件将Nand Flash的前8KB复制到Steppingstone,然后从0地址开端运转程序,在这8KB以内代码中,咱们需求完结必要的硬件初始化,假如代码超越8K,咱们还需求将剩下代码的搬移到链接地址处,一般在SDRAM/DDR中。其间,硬件部分需求初始化体系时钟、DDR和NAND Flash三部分。这便是S3C6410以Nand方法发动时的大致流程,看上去跟ARM9(S3C2440)没有不同,可是假如您亲自动手写一下这个发动进程,你会发现ARM9跟ARM11仍是存在若干不同的,这儿我要说的是Nand裸机驱动的问题。述了S3C6410的Nand方法发动流程,看上去跟ARM9(S3C2440)没有太大不同,可是假如您亲自动手写一下这个发动进程,你会发现ARM9跟ARM11仍是存在若干不同的,这儿我要说的是Nand裸机驱动的问题。
我的开发板式Tiny6410,装备的Nand flash是K9GAG08U0E,块空间1M,页空间8K。所以能够完结nand_read函数:
- intnand_read(unsignedintnand_start,unsignedintddr_start,unsignedintlen)
- {
- unsignedlongrest=len;
- unsignedlongaddr=nand_start;
- unsignedlongpage;
- unsignedchar*dest=(unsignedchar*)ddr_start;
- inti;
- nand_select();
- while(rest>0){
- nand_cmd(0x00);
- nand_addr(addr);
- nand_cmd(0x30);
- nand_ready();
- page=rest>PAGE_SIZE?PAGE_SIZE:rest;
- for(i=0;i!=page;++i){
- *dest++=NFDATA;
- }
- rest-=page;
- addr+=page;
- }
- nand_deselect();
- return0;
- }
如上,咱们能够完结必要的硬件初始化后用nand_read(0, 0x50000000, __bss_start-_start)来将完好的代码从Nand搬移到DDR中,开端我也是这样想的,可是发现代码底子无法运转,后来调试了一下发现,这样只将代码的前2K复制到DDR中,接下来的6K代码丢掉了,而再接下来的代码是正确的!这很古怪啊,手册中明却指出,该Nand的页巨细为8KB,但为何我实践读取时却只能读取到2KB呢?本来S3C6410发动时复制的8K代码不是存储在Nand flash的第一页上,而是存储在Nand flash的前4页上,每页2K,一共8K,这是S3C6410芯片的硬件结构决议的!也便是说,尽管咱们的Nand flash的页巨细是8K,可是S3C6410为了习惯各种类型的Nand flash并确保硬件能正确的复制Nand flash中的前8K到SRAM中,硬性的加上这一规则。因而,nand2ddr函数应该这样写:
- voidcopy2ddr(unsignedlonglength){
- unsignedlongrest=length;
- unsignedlongsize;
- unsignedlongi;
- for(i=0;i!=4;++i){
- size=rest>2048?2048:rest;
- nand_read(PAGE_SIZE*i,0x50000000+i*2048,size);
- rest-=size;
- if(rest==0)
- return;
- }
- nand_read(PAGE_SIZE*4,0×50000000+PAGE_SIZE,rest);
- }
对应还有写操作,原理相同,逆着写回去,这儿就不剖析原理了,nand_write函数:
- voidnand_write(unsignedintnand_start,unsignedchar*buf,unsignedintlen)
- {
- unsignedlongcount=0;
- unsignedlongaddr=nand_start;
- inti=nand_start%PAGE_SIZE;
- nand_select();
- while(count
- {
- nand_cmd(0x80);
- nand_addr(addr);
- for(;i
- {
- NFDATA=buf[count++];
- addr++;
- }
- nand_cmd(0x10);
- nand_ready();
- i=0;
- }
- nand_deselect();
- }
store2nand函数应该这样写:
- voidstore2nand(unsignedlongddr_start,unsignedlonglength){
- unsignedchar*src=(unsignedchar*)ddr_start;
- unsignedlongrest=length;
- unsignedlongsize;
- unsignedlongi;
- for(i=0;i!=4;++i){
- size=rest>2048?2048:rest;
- nand_write(PAGE_SIZE*i,src+2048*i,size);
- rest-=size;
- if(rest==0)
- return;
- }
- nand_write(PAGE_SIZE*4,src+2048*4,rest);
- }
store2nand函数能够用来下载程序时写nand用,假如不依照这种方法将程序写入nand,硬件就无法正确加载Nand flash的前8K代码,程序也就无法正常运转。
下面是我自己写的Tiny6410裸机程序,arm-linux-gcc环境,假如需求能够下载了看看,代码完结了体系时钟、DDR、Nand flash还有串口的初始化,下面是链接地址,今后还会持续完善:
下载地址:(前段时间忘了改了)
http://download.csdn.net/detail/girlkoo/4690705