IT业行者,行者无疆
分类: 嵌入式
2010-10-29 15:07:24
嵌入式Linux应用开发完全手册 韦东山 编著
第6章 存储控制器
使用存储控制器访问外设
每个Bank的地址空间为128MB,总共1GB(8Banks)。
S3C2440对外引出27根线Addr0—addr26,CPU对外引出8根片选nGCS0~ nGCS7。
2的27次方=128MB,128MB*8=1GB。
S3C2440作为32位CPU,可以使用的地址范围理论上达到4GB。
4GB地址空间:
1、1GB连接外设(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 (内部SRAM、4KB) , 内存访问速度最快。直接读写。
掉电丢失。
3、 NorFlash
NorFlash接口与RAM相同,可以随意访问任意地址的数据。随机访问。
掉电不丢失,擦写麻烦。
NorFlash控制器?
4、 NandFlash
NandFlash接口仅包含几个I/O引脚,需要串行地访问。顺序访问。
掉电不丢失,擦写麻烦。
NandFlash控制器。
5、 SD
串行访问。顺序访问?
SD协议,SPI协议。
掉电不丢失,擦写麻烦。
SDIO控制器。
= = = = = = = = = = = = = = = = = == = = = = = = = == = = = = = = = == = = = = = = = =
1. 内存直接访问;
2. 访问外设通过存储控制器;
3. 接口与RAM不一致,还需专门的特殊寄存器;
4. NorFlash、NandFlash、SD掉电不丢失,擦写特性。
= = = = = = = = = = = = = = = = = == = = = = = = = == = = = = = = = == = = = = = = = =
NorFlash启动,nGCS0接NorFlash,起始地址为0x0。0x0000 0000 –0x0800 0000为NorFlash。
NorFlash(0x0000 0000) ==== >> SDRAM(0x3000 0000)
NandFlash启动,nGCS0不接任何外设。从内部RAM(SteppingStone)运行。
SteppingStone从0x0000 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的命令寄存器,但真正写入数据时是直接写入的。
即是说,NorFlash与Ram有相同的接口,都通过存储控制器访问,直接对相应地址读写,但对NorFlash写入前应写相应命令到NorFlash的命令寄存器。
访问NorFlash不需要特殊控制器,只需存储控制器。擦写命令写入到NorFlash的命令寄存器。存储控制器非专用于SDRAM,存储控制器用于由存储控制器连接的各种外设,如SDRAM、NorFlash等。
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~NorFlash=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
= = = = = = = = = = = = = = = = = = = = = = NandFlash = = = = = = = = = = = = = = = = = =
nandflash没有地址或数据总线,如果是8位nandflash,那么它只有8个IO口,这8个IO口用于传输命令、地址和数据。nandflash主要以page(页)为单位进行读写,以block(块)为单位进行擦除。
NandFlash >> 块 >> 页 >> 字节
要实现用8个IO口来要访问这么大的容量,K9F2G08U0A规定了用5个周期来实现。第一个周期访问的地址为A0~A7;第二个周期访问的地址为A8~A11,它作用在IO0~IO3上,而此时IO4~IO7必须为低电平;第三个周期访问的地址为A12~A19;第四个周期访问的地址为A20~A27;第五个周期访问的地址为A28,它作用在IO0上,而此时IO1~IO7必须为低电平。前两个周期传输的是列地址,后三个周期传输的是行地址。通过分析可知,列地址是用于寻址页内空间,行地址用于寻址页,如果要直接访问块,则需要从地址A18开始。
由于所有的命令、地址和数据全部从8位IO口传输,所以nandflash定义了一个命令集来完成各种操作。有的操作只需要一个命令(即一个周期)即可,而有的操作则需要两个命令(即两个周期)来实现。
NFCMMD,NFADDR和NFDATA分别用于传输命令,地址和数据
下面介绍读操作,读操作是以页为单位进行的。在写入读命令的两个周期之间写入要读取的页地址,然后读取数据即可。
下面就给出一段具体的页读操作程序:
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);。由于第128064页是第2001块中的第0页(128064=2001×64+0),所以为了更清楚地表示页与块之间的关系,也可以写为: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没有地址或数据总线,如果是8位nandflash,那么它只有8个IO口,这8个IO口用于传输命令、地址和数据。
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
存储VA与PA对应关系的表格是为页表,无关段式还是页式。页表存放的是映射关系。
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之间,用于提高程序运行速度。
TLB、Cache基于程序访问的局部性原理。
虚拟存储也应是基于程序访问的局部性原理。
本例SDRAM的开始16KB用来存放一级页表。4096个条目,每描述符4字节。
4096*4=16KB,一级页表占16KB。
设置页表,开启MMU。MMU根据页表自动将VA转换成PA。
页表即VA到PA的映射。
段内偏移不在页表中体现,只在MVA中体现。
加载地址 运行地址
编译后映像内地址 重定位地址
在连接程序时,第二部分代码的加载地址被指定为2048,重定位地址为0xB0004000。所以系统从NandFlash启动后,第二部分代码就存储在Steppingstone中地址2048之后,需要把他复制到0x30004000处(此时尚未开启MMU,虚拟地址0xB0004000对应的物理地址后面设为0x30004000)。