arm地址空间分配与启动时地址的映射.docx
《arm地址空间分配与启动时地址的映射.docx》由会员分享,可在线阅读,更多相关《arm地址空间分配与启动时地址的映射.docx(29页珍藏版)》请在冰豆网上搜索。
![arm地址空间分配与启动时地址的映射.docx](https://file1.bdocx.com/fileroot1/2023-2/22/e9a65dfd-d9ac-49dd-91cd-1e9837e0696e/e9a65dfd-d9ac-49dd-91cd-1e9837e0696e1.gif)
arm地址空间分配与启动时地址的映射
s3c2440地址空间的分配
s3c2440启动过程详解
一:
地址空间的分配
1:
s3c2440是32位的,所以可以寻址4GB空间,内存(SDRAM)和端口(特殊寄存器),还有ROM都映射到同一个4G空间里.
2:
开发板上一般都用SDRAM做内存flash(nor、nand)来当做ROM。
其中nandflash没有地址线,一次至少要读一页(512B).其他两个有地址线
3:
norflash不用来运行代码,只用来存储代码,NORflash,SDRAM可以直接运行代码)
4:
s3c2440总共有8个内存banks
6个内存bank可以当作ROM或者SRAM来使用
留下的2个bank除了当作ROM 或者SRAM,还可以用SDRAM(各种内存的读写方式不一样)
7个bank的起始地址是固定的
还有一个灵活的bank的内存地址,并且bank大小也可以改变
5:
s3c2440支持两种启动模式:
NAND和非NAND(这里是norflash)。
具体采用的方式取决于OM0、OM1两个引脚
OM[1:
0所决定的启动方式
OM[1:
0]=00时,处理器从NANDFlash启动
OM[1:
0]=01时,处理器从16位宽度的ROM启动
OM[1:
0]=10时,处理器从32位宽度的ROM启动。
OM[1:
0]=11时,处理器从TestMode启动。
当从NAND启动时
cpu会自动从NANDflash中读取前4KB的数据放置在片内SRAM里(s3c2440是soc),同时把这段片内SRAM映射到nGCS0片选的空间(即0x00000000)。
cpu是从0x00000000开始执行,也就是NANDflash里的前4KB内容。
因为NANDFLASH连地址线都没有,不能直接把NAND映射到0x00000000,只好使用片内SRAM做一个载体。
通过这个载体把nandflash中大代码复制到RAM(一般是SDRAM)中去执行
当从非NANDflash启动时
norflash被映射到0x00000000地址(就是nGCS0,这里就不需要片内SRAM来辅助了,所以片内SRAM的起始地址还是0x40000000). 然后cpu从0x00000000开始执行(也就是在Norfalsh中执行)。
总结:
Arm的启动都是从0地址开始,所不同的是地址的映射不一样。
在arm开电的时候,要想让arm知道以某种方式(地址映射方式)运行,不可能通过你写的某段程序控制,因为这时候你的程序还没启动,这时候arm会通过引脚的电平来判断。
1当引脚OM0跟OM1有一个是高电平时,这时地址0会映射到外部nGCS0片选的空间,也就是Norflash,程序就会从Norflash中启动,arm直接取Norflash中的指令运行。
2当OM0跟OM1都为低电平,则0地址内部bootbuf(一段4k的SRAM)开始。
系统上电,arm会自动把NANDflash中的前4K内容考到bootbuf(也就是0地址),然后从0地址运行。
这时NANDFlash中的前4K就是启动代码(他的功能就是初始化硬件然后在把NANDFlash中的代码复制到RAM中,再把相应的指针指向该运行的地方)
为什么会有这两种启动方式,关键还是两种flash的不同特点造成,NOR FLASH容量小,速度快,稳定性好,输入地址,然后给出读写信号即可从数据口得到数据,适合做程序存储器。
NAND FLASH 总容量大,但是读写都需要复杂的时序,更适合做数据存储器。
这种不同就造成了NORflash可以直接连接到arm的总线并且可以运行程序,而NANDflash必须搬移到内存(SDRAM)中运行。
在实际的开发中,一般可以把bootloader烧入到Norflash,程序运行可以通过串口交互,进行一定的操作,比如下载,调试。
这样就很可以很方便的调试你的一些代码。
Norflash中的Bootloader还可以烧录内核到Norflash等等功能。
转:
sdram,nandflash,norflash,地址分配
前三篇文章里,我分析了S3C2440与SDRAM,NORFLASH,NANDFLASH的连线。
在S3C2440开发板这个系统中,这三种存储芯片的地址是如何分配的呢?
首先看下图:
这是S3C2440的存储器地址分配图,SDARM只能接在BANK6或BANK7.从分析SDRAM接线的文章里的SDRAM接线图可以看到,SDRAM接的是ngcs6,也就是接在BANK6,因为选择的SDRAM是2片32Mbyte,总容量是64Mbyte,所以SDRAM的地址范围是
0x30000000---0x33ffffff。
S3C2440的OM0,OM1脚决定系统启动模式:
TQ2440开发板的NORFLASH是16bit数据位宽,选择从NORFLASH启动,所以OM0接VDD,OM1接VSS,从分析NORFLASH接线的文章里的接线图可以看到,NORFLASH接的是ngcs0,也就是接在BANK0.因为选择的NORFLASH是2Mbyte,所以NORFLASH的地址范围是0x00000000---0x001fffff。
上电时,程序会从Norflash中启动,ARM直接取Norflash中的指令运行。
最后来看NANDFLASH,NANDFLASH以页为单位读写,要先命令,再给地址,才能读到NAND的数据。
NANDFLASH是接在NANDFLASH控制器上而不是系统总线上,所以没有在8个BANK中分配地址。
如果S3C2440被配置成从NandFlash启动,S3C2440的NandFlash控制器有一个特殊的功能,在S3C2440上电后,NandFlash控制器会自动的把NandFlash上的前4K数据搬移到4K内部SRAM中,系统会从起始地址是0x00000000的内部SRAM启动。
程序员需要完成的工作,是把最核心的启动程序放在NandFlash的前4K中,也就是说,你需要编写一个长度小于4K的引导程序,作用是将主程序拷贝到SDRAM中运行。
由于NandFlash控制器从NandFlash中搬移到内部RAM的代码是有限的,所以在启动代码的前4K里,我们必须完成S3C2440的核心配置以及把启动代码(U-BOOT)剩余部分搬到RAM中运行,至于将2440当做单片机玩裸跑程序的时候,就不要做这样的事情,当代码小于4K的时候,只要下到nandflash中就会被搬运到内部RAM中执行了。
不管是从NORFLASH启动还是从NANDFLASH启动,ARM都是从0x00000000地址开始执行的。
s3c2440存储控制器和地址以及启动的理解
s3c2440存储控制器和地址以及启动的理解收藏
1.首先应该先了解FlashROM的种类
NORFLASH地址线和数据线分开,来了地址和控制信号,数据就出来。
NANDFlash地址线和数据线在一起,需要用程序来控制,才能出数据。
通俗的说,只给地址不行,要先命令,再给地址,才能读到NAND的数据,在一个总线完成的。
结论是:
ARM无法从NAND直接启动。
除非装载完程序,才能使用NANDFlash.
2.NandFlash的命令、地址、数据都通过I/O口发送,管脚复用,这样做做的好处是,可以明显减少NANDFLASH的管脚数目,将来如果设计者想将NANDFLASH更换为更高密度、更大容量的,也不必改动电路板。
在S3C2440中NANDFLASH的控制依靠NANDFLASH控制器。
不能够执行程序,本人总结其原因如下:
a.NANDFLASH本身是连接到了控制器上而不是系统总线上。
CPU启动后是要取指令执行的,如果是SROM、NORFLASH等之类的,CPU发个地址就可以取得指令并执行,NANDFLASH不行,因为NANDFLASH是管脚复用,它有自己的一套时序,这样CPU无法取得可以执行的代码,也就不能初始化系统了。
b.NANDFLASH是顺序存取设备,不能够被随机访问,程序就不能够分支或跳转,这样你如何去设计程序。
3.在2440中为什么可以配置成从NandFlash中启动程序?
如果S3C2440被配置成从NandFlash启动,S3C2440的NandFlash控制器有一个特殊的功能,在S3C2440上电后,NandFlash控制器会自动的把NandFlash上的前4K数据搬移到4K内部SRAM中,(此内部RAM被称为Steppingstone)并把0x00000000设置内部RAM的起始地址,CPU从内部RAM的0x00000000位置开始启动。
这个过程不需要程序干涉。
程序员需要完成的工作,是把最核心的启动程序放在NandFlash的前4K中,也就是说,你需要编写一个长度小于4K的引导程序,作用是将主程序拷贝到SDRAM中运行(NF地址不是线性的,程序不能直接运行,必须拷贝到线性RAM中?
)。
4.SamsungS3C2440支持NorFlash和NandFlash启动,在TQ2440上可以通过跳线设置启动方式。
主要由OM[1:
0]这两位来决定从何处启动。
具体含义如下:
OM[1:
0]所决定的启动方式
OM[1:
0]=00时,处理器从NANDFlash启动
OM[1:
0]=01时,处理器从16位宽度的ROM启动
OM[1:
0]=10时,处理器从32位宽度的ROM启动。
OM[1:
0]=11时,处理器从TestMode启动。
Arm的启动都是从0地址开始,所不同的是地址的映射不一样。
在arm开电的时候,要想让arm知道以某种方式(地址映射方式)运行,不可能通过你写的某段程序控制,因为这时候你的程序还没启动,这时候arm会通过引脚的电平来判断。
a.当引脚OM0跟OM1有一个是高电平时,这时地址0会映射到外部nGCS0片选的空间(Bank0),也就是Norflash,程序就会从Norflash中启动,arm直接取Norflash中的指令运行,不需要将Norflash中的内容拷贝到SDRAM中来。
b.当OM0跟OM1都为低电平,则0地址内部bootbuf(一段4k的SRAM)开始。
系统上电,arm会自动把NANDflash中的前4K内容拷贝到bootbuf(也就是0地址),然后从0地址运行。
这时NANDFlash中的前4K就是启动代码(他的功能就是初始化硬件然后在把NANDFlash中的代码复制到RAM中,再把相应的指针指向该运行的地方)
5.启动代码应该做什么?
由于NandFlash控制器从NandFlash中搬移到内部RAM的代码是有限的,所以在启动代码的前4K里,我们必须完成S3C2440的核心配置以及把启动代码(U-BOOT)剩余部分搬到RAM中运行,至于将2440当做单片机玩裸跑程序的时候,就不要做这样的事情,当代码小于4K的时候,只要下到nandflash中就会被搬运到内部RAM中执行了。
bootloader在某种意义上来说即是一个启动代码,种类有很多(viviuboot等),但是功能上无非就是完成一些初始化。
bootloader是芯片复位后进入操作系统之前执行的一段代码,完成由硬件启动到操作系统启动的过渡,为运行操作系统提供基本的运行环境,如初始化CPU、堆栈、初始化存储器系统等,其功能类似于PC机的BIOS.
在实际的开发中,一般可以把bootloader烧入到Norflash,程序运行可以通过串口交互,进行一定的操作,比如下载,调试。
这样就很可以很方便的调试你的一些代码。
Norflash中的Bootloader还可以烧录内核到Norflash等等功能。
6.存储控制器的作用
在2440中分了8个bank,每个bank的基地址由nCGSx来选择,每个bank都接外设之后,就可以通过存储控制器来进行地址上的选择了。
每个bank与外设的连接方式不一样,主要看外设是每次进行多少位的数据传输,如果是8位,这样CPU的地址线A0就可以直接接外设的A0,如果是16位,那么CPU的A1就该接到外设的A0,一次类推往后移位,具体原因见错位原因。
norflash接在bank0,数据线为16位。
存储控制器的特性如下:
1.大小端设置;
2.地址空间:
每个bank为128MB(总共1GB);
3.除了bank0其余所有banks的数据位宽是可编程的(8/16/32-bit);(bank0是16/32位)
4.总共8个memorybanks,其中6个bank是接ROM,SRAM等,其余2个bank是接ROM,SRAM,SDRAM等;
5.7个memorybank的起始地址是固定的;(发现size也是固定的,128MB)
6.1个memorybank的起始地址和大小是可灵活可变的;
7.所有banks的访问周期数是可编程的;
8.支持片外等待信号以扩充总线周期;
9.SDRAM在Powerdown模式下支持自动刷新
s3c2440对nandflash的操作
(一)
ARM9之TQ24402010-08-2811:
41:
18阅读110评论1 字号:
大中小订阅
nandflash在对大容量的数据存储中发挥着重要的作用。
相对于norflash,它具有一些优势,但它的一个劣势是很容易产生坏块,因此在使用nandflash时,往往要利用校验算法发现坏块并标注出来,以便以后不再使用该坏块。
nandflash没有地址或数据总线,如果是8位nandflash,那么它只有8个IO口,这8个IO口用于传输命令、地址和数据。
nandflash主要以page(页)为单位进行读写,以block(块)为单位进行擦除。
每一页中又分为main区和spare区,main区用于正常数据的存储,spare区用于存储一些附加信息,如块好坏的标记、块的逻辑地址、页内数据的ECC校验和等。
三星公司是最主要的nandflash供应商,因此在它所开发的各类处理器中,实现对nandflash的支持就不足为奇了。
s3c2440不仅具有nandflash的接口,而且还可以利用某些机制实现直接从nandflash启动并运行程序。
本文只介绍如何对nandflash实现读、写、擦除等基本操作,不涉及nandflash启动程序的问题。
在这里,我们使用的nandflash为K9F2G08U0A,它是8位的nandflash。
不同型号的nandflash的操作会有所不同,但硬件引脚基本相同,这给产品的开发带来了便利。
因为不同型号的PCB板是一样的,只要更新一下软件就可以使用不同容量大小的nandflash。
K9F2G08U0A的一页为(2K+64)字节(加号前面的2K表示的是main区容量,加号后面的64表示的是spare区容量),它的一块为64页,而整个设备包括了2048个块。
这样算下来一共有2112M位容量,如果只算main区容量则有256M字节(即256M×8位)。
要实现用8个IO口来要访问这么大的容量,K9F2G08U0A规定了用5个周期来实现。
第一个周期访问的地址为A0~A7;第二个周期访问的地址为A8~A11,它作用在IO0~IO3上,而此时IO4~IO7必须为低电平;第三个周期访问的地址为A12~A19;第四个周期访问的地址为A20~A27;第五个周期访问的地址为A28,它作用在IO0上,而此时IO1~IO7必须为低电平。
前两个周期传输的是列地址,后三个周期传输的是行地址。
通过分析可知,列地址是用于寻址页内空间,行地址用于寻址页,如果要直接访问块,则需要从地址A18开始。
由于所有的命令、地址和数据全部从8位IO口传输,所以nandflash定义了一个命令集来完成各种操作。
有的操作只需要一个命令(即一个周期)即可,而有的操作则需要两个命令(即两个周期)来实现。
下面的宏定义为K9F2G08U0A的常用命令:
#defineCMD_READ1 0x00 //页读命令周期1
#defineCMD_READ2 0x30 //页读命令周期2
#defineCMD_READID 0x90 //读ID命令
#defineCMD_WRITE1 0x80 //页写命令周期1
#defineCMD_WRITE2 0x10 //页写命令周期2
#defineCMD_ERASE1 0x60 //块擦除命令周期1
#defineCMD_ERASE2 0xd0 //块擦除命令周期2
#defineCMD_STATUS 0x70 //读状态命令
#defineCMD_RESET 0xff //复位
#defineCMD_RANDOMREAD1 0x05 //随意读命令周期1
#defineCMD_RANDOMREAD2 0xE0 //随意读命令周期2
#defineCMD_RANDOMWRITE 0x85 //随意写命令
在这里,随意读命令和随意写命令可以实现在一页内任意地址地读写。
读状态命令可以实现读取设备内的状态寄存器,通过该命令可以获知写操作或擦除操作是否完成(判断第6位),以及是否成功完成(判断第0位)。
下面介绍s3c2440的nandflash控制器。
s3c2440支持8位或16位的每页大小为256字,512字节,1K字和2K字节的nandflash,这些配置是通过系统上电后相应引脚的高低电平来实现的。
s3c2440还可以硬件产生ECC校验码,这为准确及时发现nandflash的坏块带来了方便。
nandflash控制器的主要寄存器有NFCONF(nandflash配置寄存器),NFCONT(nandflash控制寄存器),NFCMMD(nandflash命令集寄存器),NFADDR(nandflash地址集寄存器),NFDATA(nandflash数据寄存器),NFMECCD0/1(nandflash的main区ECC寄存器),NFSECCD(nandflash的spare区ECC寄存器),NFSTAT(nandflash操作状态寄存器),NFESTAT0/1(nandflash的ECC状态寄存器),NFMECC0/1(nandflash用于数据的ECC寄存器),以及NFSECC(nandflash用于IO的ECC寄存器)。
NFCMMD,NFADDR和NFDATA分别用于传输命令,地址和数据,为了方便起见,我们可以定义一些宏定义用于完成上述操作:
#defineNF_CMD(data) {rNFCMD =(data);} //传输命令
#defineNF_ADDR(addr) {rNFADDR=(addr);} //传输地址
#defineNF_RDDATA() (rNFDATA) //读32位数据
#defineNF_RDDATA8() (rNFDATA8) //读8位数据
#defineNF_WRDATA(data) {rNFDATA=(data);} //写32位数据
#defineNF_WRDATA8(data) {rNFDATA8=(data);} //写8位数据
其中rNFDATA8的定义为(*(volatileunsignedchar*)0x4E000010) //0x4E000010此地址是NFDATA寄存器的地址
NFCONF主要用到了TACLS、TWRPH0、TWRPH1,这三个变量用于配置nandflash的时序。
s3c2440的数据手册没有详细说明这三个变量的具体含义,但通过它所给出的时序图,我们可以看出,TACLS为CLE/ALE有效到nWE有效之间的持续时间,TWRPH0为nWE的有效持续时间,TWRPH1为nWE无效到CLE/ALE无效之间的持续时间,这些时间都是以HCLK为单位的(本文程序中的HCLK=100MHz)。
通过查阅K9F2G08U0A的数据手册,我们可以找到并计算该nandflash与s3c2440相对应的时序:
K9F2G08U0A中的tWP与TWRPH0相对应,tCLH与TWRPH1相对应,(tCLS-tWP)与TACLS相对应。
K9F2G08U0A给出的都是最小时间,s3c2440只要满足它的最小时间即可,因此TACLS、TWRPH0、TWRPH1这三个变量取值大一些会更保险。
在这里,这三个值分别取1,2和0。
NFCONF的第0位表示的是外接的nandflash是8位IO还是16位IO,这里当然要选择8位的IO。
NFCONT寄存器是另一个需要事先初始化的寄存器。
它的第13位和第12位用于锁定配置,第8位到第10位用于nandflash的中断,第4位到第6位用于ECC的配置,第1位用于nandflash芯片的选取,第0位用于nandflash控制器的使能。
另外,为了初始化nandflash,还需要配置GPACON寄存器,使它的第17位到第22位与nandflash芯片的控制引脚相对应。
下面的程序实现了初始化nandflash控制器:
voidNF_Init(void)
{
rGPACON=(rGPACON&~(0x3f<<17))|(0x3f<<17); //配置芯片引脚
//TACLS=1、TWRPH0=2、TWRPH1=0,8位IO
rNFCONF=(TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
//非锁定,屏蔽nandflash中断,初始化ECC及锁定main区和spare区ECC,使能nandflash片选及控制器
rNFCONT=(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
}
为了更好地应用ECC和使能nandflash片选,我们还需要一些宏定义:
#defineNF_nFCE_L() {rNFCONT&=~(1<<1);}
#defineNF_CE_L() NF_nFCE_L() //打开nandflash片选
#defineNF_nFCE_H()