void * _ http://www.Sina.com/(unsigned long phys _ addr,unsigned long size,unsigned long flags )
入口: phys_addr :要映射的第一个I/o地址;
size :要映射的空间大小;
flags :有关要映射的IO空间权限的标志;
功能:将单个I/o地址空间映射到内核虚拟地址空间,便于访问;
实现—确定要映射的IO地址空间,不需要重新映射低PCI/ISA地址,也不允许用户将IO地址空间映射到正在使用的RAM。 最后申请vm_area_struct结构,调用remap_area_pages填写页表,填写过程失败时释放申请的VM_
含义:
例如,isa和pci设备、fb、硬件跳线或物理连接方法决定了硬件上的内存反映在哪个cpu的物理地址中。
要通过内核访问这些地址,必须为此内存分配虚拟地址。 这正是__ ioremap的意思。 请注意,物理内存已经“存在”,因此不需要将锁定页传递到此地址。
文件中的注释也很详细,只有__ ioremap,iounmap这两个函数在其他模块中公开
块调用、函数remap_area_pte、remap_area_pmd和remap_area_pages仅用于__ ioremap。
————
为了让软件访问I/O内存,必须为设备分配虚拟地址。 这就是ioremap的工作。 此函数专门用于为I/O内存空间分配虚拟地址(空间)。 对直接映射的I/O地址ioremap不执行任何操作(? )
有了ioremap(和iounmap ),无论设备是否直接映射到虚拟地址空间,都可以访问任何I/O内存空间。 但是,不能直接使用这些地址。 使用名为readb的函数。
根据计算机平台和使用的总线,I/O内存可能通过页面表访问,也可能不是。 通过页面表访问的是统一地址(PowerPC ),否则为独立地址(Intel )。 如果访问是通过页面表进行的,则内核必须首先安排物理地址,以便设备驱动程序可以识别。 这通常意味着在进行I/O之前必须调用ioremap。 如果访问不需要页表,则I/O内存空间类似于I/O端口,可以使用适当格式的函数读写。
无论访问I/O内存时是否需要调用ioremap,都不建议直接使用指向I/O内存的指针。 正如I/O端口和I/O内存中所述,I/O内存在硬件级别的寻址方式与普通RAM相同,但如I/O寄存器和普通内存中所述,需要额外注意时不要使用普通指针相反,使用“包装”函数访问I/O内存在所有平台上是安全的,但如果可以直接对指针指向的内存区域执行操作,则进行了优化
————
我以为在给图形板上的存储空间分配总线地址a后,会确定与其对应的虚拟空间。 也就是说是A 3G。 但实际上,在 ioremap.c文件中的实现并非如此。 使用的函数为__3358www.Sina.com/
长标志) )是通过将虚拟地址分配给大小为size的物理地址实现的,该物理地址以phys_addr开始。 请注意,这里是分配,不是指定。 我认为分配是指从phys_addr中指定相应的虚拟地址为phys_addr 3G。
我合理的解释是,这种映射到:系统虚拟空间的非IO卡上的地址空间满足3G的差关系,IO卡上的
存储空间不足。 欢迎讨论
在X86体系下,CPU的物理地址和PCI总线地址共享一个空间。 linux内核将3G-4G虚拟地址固定映射到物理地址0-1G处。 但是,如果外围设备的地址超过1G,例如,如果某个PCI卡被分配给超过1G的地址,则调用ioremap,将物理地址(总线地址)与虚拟地址的映射此映射进程首先在ioremap.c文件的__ ioremap函数中检查将来映射的物理地址。 这意味着不能重新映射640K-1M地址。 (由于历史原因,物理地址为640K-1M的空间被显卡保留。 ) ) ) ) )然后,当调用get_vm_area获取可用的虚拟地址并基于与该虚拟地址映射的物理地址修改页面表时,内核将使用该虚拟地址进行映射