小论嵌入设备开发中可能用到内存映射方法

小论嵌入设备开发中可能用到内存映射方法

康华 :主要从事 Linux 操作系统内核、虚拟机、Linux 技术标准、计算机安全、软件测试等领域的研究与开发工作,曾就职 MII-HP 软件实验室 瞬联软件公司/MOTOROLA,现就职于Lenovo研究院 。其所合写的Linux专栏见http://www.csdn.net/subject/linux/。 如果需要可以联系通过 kanghua151@msn.com (MSN)联系我.  

本文将以我前期开发的项目为蓝本,就开发中遇到的有关内存映射的问题进行一些总结。希望能帮助新接触Linux内存映射的朋友梳理一下思路。

      首先我大致描述一下我们所设计的板卡特性。我们使用的板卡之一是MPC8560,它是一个POWERPC系列的双核(E500 和 CPM)板卡,我们用它来做通讯系统。该板卡的物理地址空间布局如下所示:
 
Processor Memory Map of MPC8560
0000_0000  7FFF_FFFF   <2G      System Memory (onboard DRAM)
8000_0000  A000_0000   512M    PCI Memory Space 
A000_0000  A100_0000   16M     PCI I/O Space
E000_0000  E400_0000   64M      Solider FLASH        
E800 0000  E800 1000   4k       Framer register
E800 1000  E810 0000   512K     CPLD register
E880 0000  E900 0000   512K     Socket
FDF0 0000  FE00 0000   1M       Mpc8560 Register
FFF0 0000  FFFF FFFF   1M       Book Bank 
   从上图可以看到,系统物理物理范围不得大于2G,默认空间从0000_0000开始;系统的PCI内存空间大小为512M,默认空间从8000_0000到A000_0000;系统另外还有Framer register,CPLD register和Mpc8560 Register三块寄存器空间(其它空间我们这里不用考虑)。 实际上我们板卡的物理内存为512M。
   我们的应用对系统有如下要求(为了能更集中说明问题,所列需求和实际系统配置有所出入):
1.    系统需要有保留208M的PCI内存空间用于导入其它板卡的内存映射(因为要导入13块其它板卡的各16M内存,也就是它需要能访问到其它13个板卡)。
2.    系统本身需要留出16M的连续内存用于导出到其它系统中。
3.    为了和已有系统兼容,新系统需要留出虚拟地址C8000000-C8800000存储配置信息,我们这里称为CDB(configure database)。CBD需要能被应用进程访问。
4.    系统要能操作各种寄存器。
好了,在这些束缚下我们该如何布置我们的内存映射呢?首先我们知道Linux系统中默认情况下内核空间占据高1G(POWERPC中有时占据高2G)的逻辑空间,用户空间占据剩下的逻辑空间(0000_00000到C000_0000 或D000_0000)。而上面第2点需要却要求我们必须预留出空间C8000000-C8800000给用户程序访问,因此最直接有效的方法是,我们需要将内核空间上移动到D0000000处(POWERPC体系映射采用段寄存器,系统共分16个段,每段映射256M,因此映射边界只能依10000000跨度划分)。
然而新问题又出现了。当内核空间缩小到512M后,我们发现要想满足第1个条件,既留出208M的空间,以及剩下的几个小块寄存器地址空间,那么就无法将512M的物理内存全部映射到内核空间中。怎么办了? 解决办法就是将一半物理内存(256M)作为高端内存(而传统上系统只把高于896M以上的内存作为高端内存的),避免启动时便静态映射于内核逻辑空间。这是因为高端内存只能被动态分配且现场映射,不会启动时不经分配就直接映射到内核空间。不过这并不是说我们系统一半的内存不可用,因为系统在需要时仍然可以指明在高端内存分配可用内存,然后建立内存映射,从而使用它(如: _ _get_free_pages(GFP_HIGHMEM,X) kmap( )
 
注释:修改内核地址空间和高端内存空间需要修改 TASK_SIZE, KERNEL_START, LOWMEM_SIZE 等值。
 
另外,我们为了满足第2个条件,即将16M连续物理内存空间保留下来导出。若要分配连续物理内存空间尽可以使用 kmalloc来分配,不过现在的内核还无法分配大到16M的连续空间,因此我们需要采用预留内存的方法——留出一段内存不让Linux内核看到(也就是说内核不管理这段区间,不过可要搞清楚,这段内存和高端内存不同,它并未处于高端内存),具体做法是在启动时
通过启动参数“ mem=240M”来通知内核其只管理240M的物理内存。然后在使用前再将这部分内存映射到内核空间(如,ioremap (0xF000000 /* 240M */, 0x1000000 /* 16M */);
          最后为了能在内核空间访问Framer register、CPLD register和Mpc8560 Register寄存器 我们必须也将其映射到内核空间,方法很简单就是用下面语句:
 request_mem_region(CPLD_ADDRESS, CPLD_SIZE, "CPLD");
 CPLD_MAPPED_ADDR = (UBYTE *)ioremap(CPLD_ADDRESS,CPLD_SIZE);         
 
记住上面所的要求和解释,我们下面给出系统的物理内存布局和虚拟地址空间布局。
 
MPC8560 物理内存布局  
Kernel (include drivers)    00000000~000480000     <4M   粗略估计值
Initrd Image                00480000~00780000      <3M   粗略估计值
-------------------------------------------- 0x00780000
可给应用程序动态分配的物理内存  
――――――――――――――――――――――
Pci buffer                  0F000000-10000000             16M
-------------------------------------------- 0x10000000   256M  以上为高端内存
只能现场分配且映射才可被使用
-------------------------------------------- 0x20000000   512M   
 
Linux系统运行后,其虚拟地址空间布局如下:
-------------------------------------------------- 0x00000000
Application     Space
Libraries map      Space
---------------------------------------------------0xC8000000
CDB Map Space      0xC8000000-0xC8800000                       8M
Stack                        0xCE000000~0xCFFFFFFF                   16M
 
---------------------------------------------------0xD0000000        Kernel Space Begin
Physical memory maps(Kernel logical space)         256M
---------------------------------------------------0xE0000000
Kernel virtual space      256M
                
---------------------------------------------------0xFFFFFFFF
注意,上图中的内核虚拟空间(非对应连续物理地址的内核空间,详解请看内核驱动开发一书)存在打散的部分,这些部分中会容纳我们的208M 的PCI 内存空间  ,16M 的导出地址空间,以及各种寄存器空间 等等。但具体的映射地址则由内核在运行时确定。
 
上面的例子初读可能并非显而易见,不明白的地方请多参考资料下载中给出的内核教材,并结合内核源代码进行分析。搞清各种内存映射关系是开发嵌入系统必不可少的功课,希望本文能帮助大家学习。
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值