HardBirch

外设IO地址空间中的地址怎么转换到内核态的虚拟地址空间(一个ioremap函数真的解释清楚了么)

时间:10-04-05 栏目:系统技术篇 作者:鲁智森也有文化 评论:1 点击: 2,871 次

LZ发问:

在看到i/o memory i/o region,以及ioremap,mmap时,被这些概念弄糊涂了,看到zhanrk的《Linux对IO端口资源的管理》后,对memory-mapped的i/o还是有些疑问,

 

我们都知道,采用I/O映射方式的X86处理器为外设实现了一个单独的地址空间,也即“I/O空间”(I/O Space)或称为“I/O端口空间”,其大小是64KB(0x0000-0xffff)。Linux在其所支持的所有平台上都实现了“I/O端口空间”这一概念。
由于I/O空间非常小,因此即使外设总线有一个单独的I/O端口空间,却也不是所有的外设都将其I/O端口(指寄存器)映射到“I/O端口空间”中。比如,大多数PCI卡都通过内存映射方式来将其I/O端口或外设内存映射到CPU的RAM物理地址空间中。而老式的ISA卡通常将其I/O端口映射到I/O端口空间中。

Linux是基于“I/O Region”这一概念来实现对I/O端口资源(I/O-mapped 或 Memory-mapped)的管理的。 文中提到通过内存映射(memory-mapped)的i/o端口(寄存器),这里的内存映射是用ioremap实现的吗? 这里的映射是指直接用ioremap将i/o 端口(register)映射到核心虚地址空间(3GB-4GB)中吗?

 

那这句话 “比如,大多数PCI卡都通过内存映射方式来将其I/O端口或外设内存映射到CPU的RAM物理地址空间中” 里面提到的将i/o映射到cpu的RAM物理地址空间又是什么意思? 搞不明白内存映射(memory-mapped)的i/o 端口到底和系统的RAM是个什么关系? 对memory-mapped的i/o端口操作过程中,和系统的RAM 是个什么关系呢,还是根本就没关系?

 
  Re: 弱弱的问个i/o memory的问题,高手帮个忙 
 
分成两步你就理解了:

第一步:

硬件级:cpu怎样访问外设存储空间?
一种方式,cpu用单独的指令访问,这个单独的指令需要一个要操作的外设存储空间的地址,这就是I/O端口(I/O port)。
另一种方式,cpu不用单独的指令访问外设存储空间,用通常的访问存储器的方式访问外设存储空间,这就是I/O存储器(memory-mapped)。
memory比port好在它不是固定大小的,只受系统配置的常规存储器大小和系统地址空间大小的限制。port的空间是固定的,现在有些外设的存储空间要求很大,port的局限性就显现出来了,因此,现在的观点是用memory-mapped的外设存储空间。
外设存储空间不能固定,否则,如果某台机器有两个外设都使用相同存储空间(port和memory一样,这里不区分了),那么cpu发出的访问外设存储空间是那个外设的呢?就冲突了。
因此,这里存在一个映射关系,在“远古”的时候,通过调整外设上的跳线来调整(映射),确保在一台机器上的外设存储空间不发生冲突。在“现代”(例如:pci总线规范中),在机器启动时,在bios中有个程序来分配资源(这里用资源因为还包括中断号的映射),完成外设存储空间的映射。

第二步:
虚拟存储空间到物理存储空间的映射,这个映射就不多说了吧。

  Re: 弱弱的问个i/o memory的问题,高手帮个忙 
 
先谢谢你的答复,我还想问一下,你所说的通过bios来完成外设存贮空间的映射,是说将外设i/o存贮器映射到系统的或者cpu的RAM上来吗?还是说外设的存贮空间和系统的RAM是属于同一个级别,cpu同等对待的?

  
  Re: 弱弱的问个i/o memory的问题,高手帮个忙 
 
Memory不只是RAM,从CPU Core角度来说,它通过Load/Store指令访问内存时,并不知道访问的是RAM,ROM,Flash还是PCI板载的RAM或寄存器,也不需要知道,CPU Core仅仅是按照协议把地址,数据,读写信号发送出去,等待结果就可以了,具体访问什么由地址译码模块决定。
 
  Re: 弱弱的问个i/o memory的问题,高手帮个忙  
 
我查了以前的帖子 看到这些关于pci memory 和pci i/o的文章 括号里是一些留言

http://www.lslnet.com/linux/showflat.php?Cat=&Board=linuxK&Number=253505&page=&view=&sb=&o=&fpart=all&vc=1
( 首先,在linux启动时,要扫描pci设备,然后为其分配中断号、端口号等必须的资源,如果此pci设备有自己的内存,必须将其映射到整个系统的物理内存空间中。然后,还要将这些这块物理内存映射到内核虚拟地址(通过函数__ioremap调用)。以后,访问pci的内存只需访问相应的虚拟地址就可以了。

系统要经过俩次映射:
1.设备上的ram映射到物理空间
2.在把该物理地址映射到虚拟空间去 )

http://www.lslnet.com/linux/showflat.php?Cat=&Board=linuxK&Number=402001&page=&view=&sb=&o=&vc=1

( the memory on pci device is mapped in memory space by hardware.
pci device has registers(base adress register) point out its on-chip memory's base address in system memory space . these register are set by OS(pci bus driver) at system init time. )

http://www.lslnet.com/linux/showflat.php?Cat=&Board=linuxK&Number=323326&page=&view=&sb=&o=&fpart=all&vc=1


设备可以根据需要把(设备上的)RAM和寄存器映射到(系统的)内存和I/O区间

PC总线上i/o操作和内存操作对应着不同的总线信号,所以是设备本身决定其资源(寄存器和RAM)是一种I/O资源,还是一种内存资源。
而智能的设备,如PCI设备,都允许系统(HOST CPU)配置设备上的资源(无论是内存还是I/O)在系统整个资源表中的位置,以简化硬件的管理工作。

归纳里面提到的是不是就是说
在系统初始化时,通过硬件完成设备上的RAM和寄存器到系统的物理内存空间的映射,这里提到的系统的物理内存空间是不是就是系统或cpu的RAM?简单的说是不是先通过硬件将设备的RAM和寄存器映射到系统或cpu的RAM上之后,之后才是到虚拟空间的映射?

 
  Re: 弱弱的问个i/o memory的问题,高手帮个忙 
 
准确地说,是设备上的RAM和寄存器映射到CPU的物理内存空间,所谓系统RAM(即常说的SDRAM或DDR)也要映射到CPU的物理内存空间。这些映射通常是软件做的,例如BIOS或boot,Linux内核也会做一部分。
 
  Re: 弱弱的问个i/o memory的问题,高手帮个忙 

 

把这些概念弄混了 那您的意思是不是说外设的RAM和寄存器是映射到cpu的物理地址空间,而这个过程和系统RAM(即常说的SDRAM或DDR)没有牵扯? 唉 快被弄晕了

 

  Re: 弱弱的问个i/o memory的问题,高手帮个忙 

 

我也来请教一下
设备的IO memory映射到虚拟空间的时候,是分页的
而页的属性,比如读、写、执行等怎么设置的?

 

  Re: 弱弱的问个i/o memory的问题,高手帮个忙 
 
页属性由MMU控制,如何设置要看MMU的手册,在linux中则简单,都给你封装好了。页属性完全是OS的事,不关其它的。

 

外设IO地址空间中的地址怎么转换到内核态的虚拟地址空间(一个ioremap函数真的解释清楚了么):目前有1 条留言

  1. 沙发
    ycd521:

    学习了,呵呵

    2011-07-08 20:32 [回复]

发表评论


QQ群互动

Linux系统与内核学习群:194051772

WP建站技术学习交流群:194062106

魔豆之路QR

魔豆的Linux内核之路

魔豆的Linux内核之路

优秀工程师当看优秀书籍

优秀程序员,要看优秀书!

赞助商广告

友荐云推荐