遇到的问题总结如下
1. memdev_init 主设备号的使用
static mem_major = MEMDEV_MAJOR;
module_param(mem_major, int, S_IRUGO);
传入数据到内核,很质疑为什么这样传入??
这里采用静态分配,一定主要不能跟现有设备号重复,否则加载之后,会出现卸载不掉模块的情况
rmmod: remove 'memdev': Device or resource busy
2.memdev_init分配设备号
dev_t devno = MKDEV(mem_major, 0);这里MKDEV??
定义如下#define MKDEV(major,minor) (((major) << MINORBITS) | (minor))
组装主次备好和此设备号
3.memdev_init分配内存采用了两次
/* 为设备描述结构分配内存,这里面设备结构就是设备*/
mem_devp = kmalloc(MEMDEV_NR_DEVS * sizeof(struct mem_dev), GFP_KERNEL);
if (!mem_devp) /*申请失败*/
{
result = - ENOMEM;
goto fail_malloc;
}
memset(mem_devp, 0, sizeof(struct mem_dev));
/*为设备分配内存*/
for (i=0; i < MEMDEV_NR_DEVS; i++)
{
mem_devp[i].size = MEMDEV_SIZE;
mem_devp[i].data = kmalloc(MEMDEV_SIZE, GFP_KERNEL);
memset(mem_devp[i].data, 0, MEMDEV_SIZE);
}
自己认为给虚拟设备分配内存空间(第一次本身就是虚拟内存这个设备需要空间,第二次操作这个虚拟设备的结构也需要分配空间)
4.注销模块memdev_exit
unregister_chrdev_region(MKDEV(mem_major, 0), 2); /*释放设备号*/
里面不是采用已定义好的devno,因为devno局部变量,无法在注销时使用
5.open操作函数
/*将设备描述结构指针赋值给文件私有数据指针*/
filp->private_data = dev;
这里面filep下面的成员 private_data 为void *private_data;
为了保存一个结构体变量,从当中介者
6.read操作函数
/*读数据到用户空间*/
if (copy_to_user(buf, (void*)(dev->data + p), count))
这里面注意参数的数据类型,void*也可以不用,第二个参数类型为const void* ,而dev->data为整型 p这里面为unsigned long p = *ppos;
这里面又牵涉到loff_t *ppos这个是个指针,erloff_t 本身就是long long ,所以ppos其实是指向长整型的指针
7. copy_to_user与cpoy_from_user 主要哪里是内核空间,哪里是用户空间,否则数据会传输错误,而且有些函数也会用错,用户程序不需要考虑这些