Linux驱动程序中的I/O

在第一篇文章中只是介绍了下Linux驱动的整体结构,并没有对具体实现进行说明。

这篇文将简单介绍一下在实现Linux驱动程序中I/O操作的实现。

I/O操作最基本需要实现的函数有三个: read(), write(), ioctl().

read(), write()
一个是从硬件读数据,一个是向硬件写数据。

来看怎么与硬件交互数据:


1. I/O port读写函数:
inb, inw, inl, outb, outw, outl;

2. I/O memory读写函数:
readb, readw, readl;
writeb, writew, writel;

还是在I/O memory中的函数,这三个是一点小福利
memset_io, memcpy_fromio, memcpy_toio;
这三个东西和memset,memcpy的用法基本完全一样。

ioctl()
略,将会有一篇小文章专门说它~

User Space 与 Kernel Space的交互

请注意一下,我们写的这些函数的参数其实都是由用户程序给传过来的。

而我们现在是在内核态,内核态不能使用用户态的内存。

所以我们在写驱动程序的时候不能直接读写用户态的资源。

怎么办呢?

copy_from_user() 与 copy_to_user()

第一个函数多用于write()的实现中,它可以把用户态数据拷贝到内核态去:

ssize_t xxx_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)

用户通过给驱动程序传送const char *buf这个参数来表示要写给硬件的数据。

一般在驱动程序使用这样的用法:

copy_from_user(kernel_memory, buf, count);

这样来把buf中的数据给拷贝到kernel_memory这块内核态的内存空间中。

然后驱动程序就可以通过读出kernel_memory的数据并写入硬件就好了。

第二个函数用法和第一个差不多,多用于read()中,可以把内核态数据拷贝到用户态去

回头写一个简单的示例程序来演示一下,这样直观一些。