Chinaunix首页 | 论坛 | 博客
  • 博客访问: 707920
  • 博文数量: 255
  • 博客积分: 5000
  • 博客等级: 大校
  • 技术积分: 2811
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-09 13:29
个人简介

IT业行者,行者无疆

文章分类

全部博文(255)

文章存档

2011年(121)

2010年(134)

我的朋友

分类: 嵌入式

2010-10-29 15:07:24

 

嵌入式Linux应用开发完全手册 韦东山 编著

 

6 存储控制器

    使用存储控制器访问外设

    每个Bank的地址空间为128MB,总共1GB(8Banks)

S3C2440对外引出27根线Addr0—addr26CPU对外引出8根片选nGCS0~ nGCS7

227次方=128MB,128MB*8=1GB

 

S3C2440作为32CPU,可以使用的地址范围理论上达到4GB

4GB地址空间:

11GB连接外设(0x0000 0000-0x4000 0000)

   1GB=4*2^28=0x4000 0000

2、一部分是CPU内部寄存器地址(0x4800 0000-0x5FFF FFFF)

   Cpu内部寄存器包括:存储控制器、Nand Flash控制器、......、

3、余下地址空间没有使用。

 

存储控制器用来连接外设。

 

存储访问:

1、  访问外设通过存储控制器

        :SDRAM。速度比内存慢,直接读写。掉电丢失。

       存储控制器。

2、  内部寄存器、内部SRAM,不用通过任何控制器;

如内部寄存器、SteppingStone (内部SRAM4KB) , 内存访问速度最快。直接读写。

掉电丢失。

3、  NorFlash

NorFlash接口与RAM相同,可以随意访问任意地址的数据。随机访问。

       掉电不丢失,擦写麻烦。

       NorFlash控制器?

4、  NandFlash

NandFlash接口仅包含几个I/O引脚,需要串行地访问。顺序访问。

       掉电不丢失,擦写麻烦。

       NandFlash控制器。

5、  SD

串行访问。顺序访问?

SD协议,SPI协议。

       掉电不丢失,擦写麻烦。

       SDIO控制器。

= = = = = = = = = = = = = = = = = == = = = = = = = == = = = = = = = == = = = = = = = =

1.  内存直接访问;

2.  访问外设通过存储控制器;

3.  接口与RAM不一致,还需专门的特殊寄存器

4.  NorFlashNandFlashSD掉电不丢失擦写特性

= = = = = = = = = = = = = = = = = == = = = = = = = == = = = = = = = == = = = = = = = =

 

NorFlash启动,nGCS0NorFlash,起始地址为0x00x0000 0000 –0x0800 0000NorFlash

   NorFlash(0x0000 0000)  ==== >> SDRAM(0x3000 0000)

NandFlash启动,nGCS0不接任何外设。从内部RAMSteppingStone)运行。

SteppingStone0x0000 0000开始,大小为4KB

NandFlash ==== >> SteppingStone(0x0000 0000)  ==== >> SDRAM(0x3000 0000)

 

设置存储控制器,以使用SDRAM

程序标号在连接程序时被确定。

位置无关相对跳转。

=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~NorFlash=~=~=~=~=~=~=~=~=~=~=~=~=~=~=






norflash的读操作比较简单,系统上电后会自动进入读模式,而且也不需要额外的命令来实现读操作。下面的函数实现了读操作 

U16 read_en29lv160ab(U32 addr)

{

       return *((volatile U16 *)(addr));

}

read_en29lv160ab(0xf0000+(i<<1))

norflash的擦除操作和写操作要稍微复杂一些,它们需要4个或6个周期来完成,每一个周期都要把相应的命令写入norflash的某一命令寄存器中。写操作的过程为第一个周期是把命令0xAA写入地址为0x555的命令寄存器中,第二个周期是把命令0x55写入地址为0x2AA命令寄存器中,第三个周期是把命令0xA0再写入地址为0x555命令寄存器中,第四个周期为真正地把要写入的数据写入到norflash的地址中。下面的函数实现了写操作,其中该函数的两个输入参数分别为要写入的数据和地址,为了方便,我们事先定义好命令寄存器: 

#define    flash_base              0x00000000

#define    CMD_ADDR0              *((volatile U16 *)(0x555<<1+flash_base))

#define    CMD_ADDR1              *((volatile U16 *)(0x2aa<<1+flash_base))

 U8 en29lv160ab_program(U32 addr, U16 dat)

{

       CMD_ADDR0 = 0xaa;

       CMD_ADDR1 = 0x55;

       CMD_ADDR0 = 0xa0;

       *((volatile U16 *)(addr)) = dat;

        return check_toggle();

}

sta = en29lv160ab_program(0xf0000+(i<<1),buffer[i]);

写操作只能使“1”变为“0”,而只有擦除才能使“0”变为“1”。因此在写之前一定要先擦除。擦除分为块擦除和整片擦除。块擦除的过程为第一个周期是把命令0xAA写入地址为0x555的命令寄存器中,第二个周期是把命令0x55写入地址为0x2AA命令寄存器中,第三个周期是把命令0x80再写入地址为0x555命令寄存器中,第四个周期是把命令0xAA写入地址为0x555的命令寄存器中,第五个周期是把命令0x55再写入地址为0x2AA命令寄存器中,第六个周期是把命令0x30写入要擦除块的首地址内。下面的函数为块擦除,其中输入参数为要擦除块的首地址:

 U8 en29lv160ab_sector_erase(U32 section_addr)

{

       CMD_ADDR0 = 0xaa;

       CMD_ADDR1 = 0x55;

       CMD_ADDR0 = 0x80;

       CMD_ADDR0 = 0xaa;

       CMD_ADDR1 = 0x55;

       *((volatile U16 *)(section_addr)) = 0x30;

       return check_toggle();

}

sta=en29lv160ab_sector_erase(0xf0000);

虽然NorFlash擦除和写之前要写相应的命令NorFlash的相应命令寄存器,注意是NorFlash的命令寄存器,但真正写入数据时是直接写入的

即是说,NorFlashRam有相同的接口,都通过存储控制器访问直接对相应地址读写,但对NorFlash写入前应写相应命令到NorFlash的命令寄存器。

访问NorFlash不需要特殊控制器,只需存储控制器。擦写命令写入到NorFlash的命令寄存器。存储控制器非专用于SDRAM,存储控制器用于由存储控制器连接的各种外设,SDRAMNorFlash等。

 

=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~NorFlash=~=~=~=~=~=~=~=~=~=~=~=~=~=~=

 

= = = = = = = = = = = = = = = = = = = = = = NandFlash = = = = = = = = = = = = = = = = = =

 

nandflash没有地址或数据总线,如果是8nandflash,那么它只有8IO口,8IO口用于传输命令、地址和数据。nandflash主要以page(页)为单位进行读写,以block(块)为单位进行擦除

NandFlash  >>    >>    >>  字节

要实现用8IO口来要访问这么大的容量K9F2G08U0A规定了用5个周期来实现。第一个周期访问的地址为A0~A7;第二个周期访问的地址为A8~A11,它作用在IO0~IO3上,而此时IO4~IO7必须为低电平;第三个周期访问的地址为A12~A19;第四个周期访问的地址为A20~A27;第五个周期访问的地址为A28,它作用在IO0上,而此时IO1~IO7必须为低电平。前两个周期传输的是列地址,后三个周期传输的是行地址。通过分析可知,列地址是用于寻址页内空间,行地址用于寻址页如果要直接访问块,则需要从地址A18开始

由于所有的命令、地址和数据全部从8IO口传输,所以nandflash定义了一个命令集来完成各种操作有的操作只需要一个命令(即一个周期)即可,而有的操作则需要两个命令(即两个周期)来实现。

NFCMMDNFADDRNFDATA分别用于传输命令地址数据

 

下面介绍读操作,读操作是以页为单位进行的。在写入读命令的两个周期之间写入要读取的页地址,然后读取数据即可。

 

下面就给出一段具体的页读操作程序:

 

U8 rNF_ReadPage(U32 page_number)

{

       U32 i, mecc0, secc;

 

NF_RSTECC();                   //复位ECC

       NF_nFCE_L();                           //打开nandflash片选

       NF_CLEAR_RB();                      //RnB信号

       NF_CMD(CMD_READ1);           //页读命令周期1

       //写入5个地址周期

       NF_ADDR(0x00);                                            //列地址A0~A7

       NF_ADDR(0x00);                                            //列地址A8~A11

       NF_ADDR((page_number) & 0xff);                  //行地址A12~A19

       NF_ADDR((page_number >> 8) & 0xff);           //行地址A20~A27

       NF_ADDR((page_number >> 16) & 0xff);         //行地址A28

       NF_CMD(CMD_READ2);           //页读命令周期2

       NF_DETECT_RB();                    //等待RnB信号变高,即不忙

       //读取一页数据内容

       for (i = 0; i < 2048; i++)

       {

              buffer[i] =  NF_RDDATA8();

       }

       NF_nFCE_H();             //关闭nandflash片选

}

 

这段程序是把某一页的内容读取到全局变量数组buffer中。该程序的输入参数直接就为K9F2G08U0A第几页,例如我们要读取第128064页中的内容,可以调用该程序为:rNF_ReadPage(128064);。由于1280642001中的01280642001×640),所以为了更清楚地表示页与块之间的关系,也可以写为:rNF_ReadPage(2001*64);

 

页写操作的大致流程为:在两个写命令周期之间分别写入页地址和数据。下面就给出一段具体的页写操作程序,其中输入参数也是要写入数据到第几页:

 

U8 rNF_WritePage(U32 page_number)

{

       U32 i, mecc0, secc;

       U8 stat, temp;

 

       NF_RSTECC();                   //复位ECC

       NF_nFCE_L();             //打开nandflash片选

       NF_CLEAR_RB();        //RnB信号

 

       NF_CMD(CMD_WRITE1);                //页写命令周期1

       //写入5个地址周期

       NF_ADDR(0x00);                                     //列地址A0~A7

       NF_ADDR(0x00);                                     //列地址A8~A11

       NF_ADDR((page_number) & 0xff);           //行地址A12~A19

       NF_ADDR((page_number >> 8) & 0xff);    //行地址A20~A27

       NF_ADDR((page_number >> 16) & 0xff);  //行地址A28

       //写入一页数据

       for (i = 0; i < 2048; i++)

       {

              NF_WRDATA8((char)(i+6));

       }

       NF_CMD(CMD_WRITE2);                //页写命令周期2

 

delay(1000);          //延时一段时间,以等待写操作完成

NF_CMD(CMD_STATUS);                 //读状态命令   

//判断状态值的第6位是否为1,即是否在忙,该语句的作用与NF_DETECT_RB();相同

do{

              stat = NF_RDDATA8();

}while(!(stat&0x40));

NF_nFCE_H();                    //关闭nandflash片选

}

 

擦除是以块为单位进行的,因此在写地址周期是,只需写三个行周期,并且要从A18开始写起。下面就给出一段具体的块擦除操作程序:

 U8 rNF_EraseBlock(U32 block_number)

{

       char stat, temp;

      

       NF_nFCE_L();             //打开片选

       NF_CLEAR_RB();        //RnB信号

 

       NF_CMD(CMD_ERASE1);         //擦除命令周期1

        //写入3个地址周期,从A18开始写起

       NF_ADDR((block_number << 6) & 0xff);         //行地址A18~A19

       NF_ADDR((block_number >> 2) & 0xff);         //行地址A20~A27

       NF_ADDR((block_number >> 10) & 0xff);        //行地址A28

       NF_CMD(CMD_ERASE2);         //擦除命令周期2

     delay(1000);          //延时一段时间

      NF_CMD(CMD_STATUS);          //读状态命令

       //判断状态值的第6位是否为1,即是否在忙,该语句的作用与NF_DETECT_RB();相同

do{

           stat = NF_RDDATA8();

}while(!(stat&0x40));

     NF_nFCE_H();             //关闭nandflash片选

}

nandflash没有地址或数据总线,如果是8nandflash,那么它只有8IO口,8IO口用于传输命令、地址和数据。

Nandflash不是通过存储控制器连接的外设,不能使用存储控制器访问NandFlash,需要专门的NandFlash控制器NandFlash的地址空间没有连接到CPU的地址空间,是独立的地址空间,只能串行顺序访问

nandflash没有地址或数据总线, IO口用于传输命令、地址和数据。

Nandflash没有连接到CPU的地址、控制、数据总线。只能通过IO口串行(8,或限于NandFlash位数)通信,传输命令、地址和数据。需要专用的NandFlash控制器。

操作周期,地址周期。

nandflash没有地址或数据总线, IO口用于传输命令、地址和数据。所以有操作周期、地址周期、多个操作周期、多个地址周期、方便操作的专用NandFlash寄存器。

= = = = = = = = = = = = = = = = = = = = = = NandFlash = = = = = = = = = = = = = = = = = =

存储器:

  寄存器、缓存、内存、硬盘、移动硬盘、闪存

 

第七章        内存管理单元 MMU

 

虚拟地址空间、物理地址空间划分为同样大小的一块块小空间(称为段或页),然后为这两类小空间建立映射关系。

虚拟地址空间远大于物理地址空间。

------ 页表 ------ 页框

     (VA)     (映射)     (PA)

 

CPU ----VA---- > 硬件自动转换 ----MVA---- > MMU ---- PA ----- > Device  

 

存储VAPA对应关系的表格是为页表,无关段式还是页式。页表存放的是映射关系。

TTB 一级页表地址。一级页表有4096条目,4096=4*1k=2^2*2^10=2^12,最小必须是4k对?

页表地址。页表存于SDRAM中,为提高速度部分存于TLB中。

MVA ----- 虚拟地址;TTB ----- 一级页表地址;一级页表描述符

MVA[31:20]在一级页表检索得一级页表描述符。

 

一级页表描述符:

无效、粗页表(4KB)、段(1MB)、细页表(1KB)

二级页表描述符:

无效、大页描述符(64KB)、小页描述符(4KB)、极小页描述符(1KB)

段、大页、小页、极小页

二级页表有:粗页表、细页表。

极小页描述符只能保存在细页表中。

大页描述符、小页描述符都可以保存在粗页表、细页表中。

如页表条目小于描述符,则n个连续条目都保存同一个描述符。

 n= 描述符大小/条目大小。

 

页表物理地址,页表也是存于内存之中。

访问页表,需要访问内存。

 

TLB—转译查找缓存,帮助快速的进行地址转换。

Cache介于主存和CPU之间,用于提高程序运行速度。

TLBCache基于程序访问的局部性原理。

虚拟存储也应是基于程序访问的局部性原理。

 

本例SDRAM的开始16KB用来存放一级页表。4096个条目,每描述符4字节。

4096*4=16KB,一级页表占16KB

 

设置页表,开启MMUMMU根据页表自动将VA转换成PA

页表即VAPA的映射。

 

段内偏移不在页表中体现,只在MVA中体现。

加载地址          运行地址

编译后映像内地址  重定位地址

 

在连接程序时,第二部分代码的加载地址被指定为2048,重定位地址为0xB0004000。所以系统从NandFlash启动后,第二部分代码就存储在Steppingstone中地址2048之后,需要把他复制到0x30004000(此时尚未开启MMU,虚拟地址0xB0004000对应的物理地址后面设为0x30004000)

 

 


 

阅读(1608) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~