1. I/O Port
和硬件 打交道离不开I/O Port ,老的 ISA 设备经常是占用实际的 I/O 端口,在 linux 下,操作 系统没有对 I/O 口屏蔽,也就是说,任何驱动程序都可对任意的 I/O 口操作,这样 就很容易引起混乱。每个驱动程序应该自己避免误用端口。
有两个 重要的kernel 函数可以保证驱动程序做到这一点。
1 ) check_region(int io_port , int off_set)
这个函 数察看系统的I/O 表,看是否有别的驱动程序占用某一段 I/O 口。
参数1 : I/O 端口的基地 址,
参数2 : I/O 端口占用的 范围。
返回 值:0 没 有占用, 非 0 ,已经被占用。
2 ) request_region(int io_port , int off_set , char *devname)
如果这 段I/O 端 口没有被占用,在我们的驱动程序中就可以使用它。在使用之前,必须向系统登记,以防止被其他程序占用。登记后,在 /proc/ioports 文件中可以看到你登记的 I/O 口。
参数1 : io 端口的基地 址。
参数2 : io 端口占用的范 围。
参数3 :使用这段 io 地址的设备 名。
在对I/O 口登记后, 就可以放心地用 inb() , outb() 之类的函来访问了。
在一些pci 设备中, I/O 端口被映射到一段内存中去,要访问这些端口就相当于访问一段内存。经常性的,我们要获得一块内存的 物理地址。
2 .内存操作
在设备驱动程序中动态开 辟内存,不是用malloc ,而是 kmalloc ,或者用 get_free_pages 直接申请页。释放内存用的是 kfree ,或 free_pages 。 请 注意, kmalloc 等函数返回的是物理地址!
注 意,kmalloc最大只能开辟 128k-16 , 16 个字节是被页 描述符结构占用了。
内存映 射的I/O 口,寄存器或者是硬件设备的 RAM( 如显存 ) 一般占用 F0000000 以上的地址空间。在驱动程序中不能直接访问,要通过 kernel 函数 vremap 获得 重新映射以后的地址。
另外, 很多硬件需要一块比较大的连续内存用作DMA 传送。这块 程序需要一直驻留在内存,不能被交换到文件中去。但是kmalloc 最多 只能开辟 128k 的内存。
这可以 通过牺牲一些系统内存的方法来解决。
http://huxiongwei.spaces.eepw.com.cn/articles/article/item/74756