【存储管理】外部设备存储空间的地址映射
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中找到所属的目录项,然后根据区间的大小走遍所有涉及的目录项,对所有的页面目录表和页面表建立映射;
(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中找到所属的目录项,然后根据区间的大小走遍所有涉及的目录项,对所有的页面目录表和页面表建立映射;
相关文章推荐
- 关于外部设备存储空间的地址映射--摘自情景分析
- Linux内核源代码情景分析-外部设备存储空间的地址映射
- 设备地址映射到用户空间(mmap)
- Linux内核情景分析读书笔记——存储管理之地址映射全过程
- [arm驱动]linux设备地址映射到用户空间 推荐
- 2.2 linux存储管理-地址映射全过程
- Linux 存储管理3——地址映射全过程
- 数据库设备与存储空间管理
- [arm驱动]linux设备地址映射到用户空间
- Linux 存储管理3——地址映射全过程
- 浅谈“设备物理地址与虚拟地址在kernel中的映射”
- Blog16@linux存储设备的管理(1)—挂载
- 2.1 存储空间管理 raid + lvm
- C语言存储空间管理和链表杂记
- Android监听外部存储设备的状态(SD卡、U盘等等)
- Linux 内核空间地址映射 高端内存 总结
- Android开发学习---如何写数据到外部存储设备(sd卡),Environment.getExternalStorageDirectory,怎么获取sd卡的大小?
- Service: 监听外部存储设备
- mmap将物理地址映射到用户空间
- ios设备获取存储空间