这个驱动设计了一个内存设备,这个设备完成对物理内存的映射,会生成/dev/iomap* 设备节点,供用户空间去访问, 从来间接实现了用户空间访问物理内存的方法。
其实只需要mmap /dev/mem 方法去实现的,目前我也不知道这种驱动映射方法的优点。
映射物理内存的设备结构体定义如下:
/* define to use readb and writeb to read/write data */
/* the device structure */
typedef struct Iomap
{
unsigned long base;
unsigned long size;
unsigned long busBitSize;
char* ptr;
} Iomap;
base : 是起始物理地址
size : 是大小
busBitSize : 是访问总线宽, 有8,16供选
*ptr : 表示物理内存的映射地址,用来保存ioremap()返回的地址。
这里定义了好几个iomap设备,主设备号一次,多了几个次设备号:
Iomap *iomap_dev[IOMAP_MAX_DEVS];
#define IOMAP_MAX_DEVS 16
devmmap_init()/devmmap_exit():
static int __init devmmap_init(void)
{
int res, i;
/* register device with kernel */
res = register_chrdev(IOMAP_MAJOR, "iomap", &iomap_fops);
if (res) {
MSG("can't register device with kernel\n");
return res;
}
for (i = 0; i < IOMAP_MAX_DEVS; i++) {
iomap_dev[i] = (Iomap *) kmalloc(sizeof(Iomap), GFP_KERNEL);
iomap_dev[i]->base = 0;
}
MSG("module loaded\n");
return 0;
}
static void __exit devmmap_exit(void)
{
int i = 0;
Iomap *tmp;
/* delete the devices */
for (tmp = iomap_dev[i]; i < IOMAP_MAX_DEVS; tmp = iomap_dev[++i]) {
if (tmp->base)
iomap_remove(tmp);
kfree(tmp);
}
unregister_chrdev(IOMAP_MAJOR, "iomap");
MSG("unloaded\n");
return;
}
init中注册完字符设备iomap后,申请了几个次设备的空间,
exit中 先解除设备的映射,再释放次设备空间,最后再注销字符设备。
int iomap_remove(Iomap *idev)
{
iounmap(idev->ptr);
MSG("buffer at 0x%lx removed\n", idev->