I/O端口访问的一种途径是直接使用I/O端口操作函数;另一种途径是将I/O端口映射到内存进行访问。
I/O内存的访问步骤:首先调用request_mem_region()申请资源,接着将寄存器地址通过ioremap()映射到内核空间虚拟地址,之后可以通过linux设备访问编程接口访问这些设备的寄存器了。访问完成之后,应对ioremap()申请的虚拟地址使用iounmap()进行释放,并释放release_mem_region()申请的I/O内存资源。
mmap()实现这样一个映射过程:它将用户空间的一段内存和设备内存关联,当用户访问用户空间上的这段内存时,实际上会转化为对设备的访问,从而使得用户空间能访问设备的物理地址。mmap()必须以PAGE_SIZE为单位进行映射。
int (*mmap)(struct file * ,struct vm_area_struct *); //file_operations中的mmap()
VMA是用来描述进程用户空间的数据结构。进程的用户空间的虚拟内存空间可以不是连续的,即可以是一段一段的。每一段的虚拟内存空间都由一个VMA结构来描述。当一个程序被加载到内存中运行时,OS会为这个进程的代码段数据段以及Stack段都分配好一段虚拟内存空间,每一端空间都有一个VMA来表示。