PIC32MX采用了两种地址空间:虚拟和物理地址。两者的区分在于由CPU执行的程序凡涉及到对存储空间的访问都是虚拟地址,包括程序运行PC。涉及到DMA控制器、FLASH控制器对内存或外设的访问,这些被访问的地址都是物理地址,因为这些控制器都是独立于CPU的,所以这也是物理与虚拟地址的区分点。
PIC32可以寻址的地址空间为4GB(虚拟地址)。根据访问权限的不同,高、低2GB空间被定义为两个区域:内核和用户空间。当然,处于内核模式的应用程序也可以放在低地址空间,所以,低2G空间也被称为useg/kuseg(用户区/内核用户区)。运行在用户模式下,总线矩阵必须配置为FLash和数据存储区的一部分。
在高2GB用户区,地址空间又被划分为4段,kseg0-kseg3(每段空间为512MB),kseg2用于EJTAG的调试,目前,PIC32仅应用kseg0和kseg1,二者的差别在于是否能够被缓存(be cached,kseg1不能够被cache)。引导flash存储与程序flash存储空间数据RAM存储,外设特殊功能寄存器都可通过两个段访问.
在物理地址与虚拟地址映射方式上,PIC32采用了简单的FMT(Fixed Mapping Translation,固定映射转换模式),如要将kseg0或者kseg1内的地址映射为物理地址,只需一个与操作即可,与操作过程为:
物理地址=(虚拟地址) 按位与 (0x1FFFFFFF)
如要将物理地址转化为虚拟地址,则有两种方法:
kseg0虚拟地址=(物理地址) 按位或 (0x80000000)
kseg1虚拟地址=(物理地址) 按位或 (0xA0000000)
即物理地址被搬运到基地址为0x80000000或0xA0000000处.
在具体的存储空间映射上,PIC32采用了关键的几个地址寄存器实现对有限区域的划分和映射.
一 BMXPUPBA---bus matrix program flash user program base address register
意指用户flash程序基地址,显然,除了kernal区外,剩下的就是用户useg/kuseg区.剩下的用户程序存储空间为PFMSIZE-BMXPUPBA.
二 BMXDKPBA---bus matrix data ram kernal program base address register
意指DATA RAM区内核程序存储空间的基地址,0x80000000至(该值-1)这段空间被用于DATA RAM内核数据区,该值至(DATA RAM用户数据基地址-1)为内核程序的ram空间.
三 BMXDUDBA---bus matrix data ram user data base address register
意指data ram用户数据区基地址,该值至(data ram用户程序基地址-1)为用户的ram数据区.
四 BMXDUPBA---bus matrix data ram user program base address register
意指data ram用户程序基地址,该值至(DRMSIZE-1)为用户的ram程序区.
通过修改以上四个寄存器,可以将flash存储空间与ram空间按照需要划分大小.
系统默认无用户程序与数据ram.具体可参见procdefs.ld,elf32pic32mx.x中对上述寄存器的初始化.
MPLAB集成开发环境中,链接器采用两种个接脚本,如上。第二个脚本内置在链接器中,用户能见到的是原版的copy。下面对第一个脚本文件:procdefs.ld做一个简单分析。
_ebase_address = 0x9FC01000;
_RESET_ADDR = 0xBFC00000;
_BEV_EXCPT_ADDR = 0xBFC00380;
_DBG_EXCPT_ADDR = 0xBFC00480;
_DBG_CODE_ADDR = 0xBFC02000;
_GEN_EXCPT_ADDR = _ebase_address + 0x180;
上述参量被定义后,为第二个脚本文件的执行提供一些绝对地址信息,用于产生exception时自动跳转到该位置。
从地址上看,除general exception放在kseg0段处。
MEMORY
{
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x80000
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970
exception_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000
kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490
debug_exec_mem : ORIGIN = 0xBFC02000, LENGTH = 0xFF0
config3 : ORIGIN = 0xBFC02FF0, LENGTH = 0x4
config2 : ORIGIN = 0xBFC02FF4, LENGTH = 0x4
config1 : ORIGIN = 0xBFC02FF8, LENGTH = 0x4
config0 : ORIGIN = 0xBFC02FFC, LENGTH = 0x4
kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x8000
sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000
}
这一段为第二脚本文件提供了虚拟存储空间的分配信息。用于链接定位。按照物理内存增长方向,空间分配地址如下:
kseg0_program_mem--内核程序代码区,此处起始地址定义为0x9D000000,代码段长为512K
kseg1_boot_mem-----内核启动代码去,此处起始地址定义为0xBFC00000(同_RESET_ADDR一样),代码长度为1K多,用于提供因复位而产生异常;
kseg0_boot_mem-----启动代码区,此处起始地址定义为0x9FC00490,代码段长为2k多,用于存放startup代码。
exception_mem------异常区,此处起始地址为0x9FC01000,代码长度为4K,用于存放异常向量。
debug_exec_mem-----调试异常区,此处起始地址为0xBFC02000,代码长度接近4k.
config地址区
kseg1_data_mem-----内核段1的数据区,起始地址为0xA0000000,空间长度为32k。
sfrs---------------特殊功能寄存器区。
在elf32pic32mx.x文件中可以看到,链接器将section放置到上述规划区域内。
文章评论(0条评论)
登录后参与讨论