您的位置:首页 > 其它

【存储管理】外部设备存储空间的地址映射

2014-05-05 19:54 495 查看
对外部设备的访问有两种不同的形式,分别是内存映射式和I/O映射式;

(1)在内存映射式的CPU中,外部设备的存储单元,如控制寄存器,状态寄存器,数据寄存器等,都是作为内存的一部分出现在系统中的;CPU可以像访问一个内存单元一样访问外部设备的存储单元,因此不需要专门设立用于访问外设的I/O指令;

(2)在I/O映射式的CPU中,CPU不可以像访问一个内存单元一样访问外部设备的存储单元,因此需要专门设立用于访问外设的I/O指令,如IN,OUT;但是用于I/O指令的“地址空间”相对来说是很小的;

其实I/O映射式的方式是适合早期的计算机技术,那时外设通常只有几个寄存器,通过这几个寄存器就可以完成所有的操作了;现在,比如PC机上有一个图像卡,带2MB的内存以及一小块ROM(装有可执行的代码),所以不管采用上述的哪两种映射方式,linux内核都通过ioremap()将外设卡上的存储器映射到虚存空间;

对于内存页面的管理,通常我们都是现在虚存空间上分配一个虚存空间,然后为此区间分配相应的物理内存从而建立起映射,而这样的映射并不是一次性完成的;而在ioremap()中,我们先有一个物理存储空间,其地址就是外设卡上的存储器出现在总线上的地址,而这个地址未必是这个外设卡上存储器上的存储单元的地址,而是在总线上由CPU所看到的地址,这中间经历了地址映射,但是对CPU来是透明的,把上述地址称为“总线地址”,比如图形卡放到PCI的总线上;在linux系统中,CPU不是按物理地址访问内存的,而是建立起映射的虚存空间来找的;

(1)在ioremap()中首先是一些检查,检查的区间大小不能是0,也不能是超越了超过32位的地址空间,物理地址在0xA0000至0x10000已系统初始化时虚存空间映射好,可直接使用了;phys_addr小于high_memory时,要检查是否与原有的物理空间冲突,然后还要确保地址边界对齐;

(2)在get_vm_area()中,内核中有专用的一个续存空间队列vmlist,这是由一串vm_struct数据结构组成的一个单链队列;high_memory标志着具体物理内存上限所对应的虚拟地址;当内核需要一片虚存地址空间时,就从这个地址的8MB处来分配,主要是为了捕捉可能的越界访问;而后的每一个vmalloc()都用4KB来捕捉可能越界访问;找到vmlist中地址适合的vm_struct;



(3)在remap_area_pages()中,是使用内核专用的mm_struct(init_mm故不属于任何的task_struct,不接受kswapd的换出调度)的,根据起始地址从init_mm中找到所属的目录项,然后根据区间的大小走遍所有涉及的目录项,对所有的页面目录表和页面表建立映射;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: