首页 > 代码库 > 操作系统——linux文件系统初实现——为fileSystem添加驱动,让linux可以识别。
操作系统——linux文件系统初实现——为fileSystem添加驱动,让linux可以识别。
0、我的理解,所为驱动,就是用户可以通过自己的应用程序访问你的文件系统。而我恰恰相反。
1、我是谢了字符驱动,让我的fileSystem去做应用程序,同样可以被linux系统识别。
2、其实我对驱动理解也不深,暂且贴代码。
3、驱动程序:
/*chardev.c 驱动程序*/#include <linux/kernel.h>#include <linux/fs.h>/*for file-f_op*/#include <linux/module.h>#include <asm/uaccess.h>/*for copy_to_user()*/#include <linux/cdev.h>/*for cdev ,cdev_init,cdev_add....*/MODULE_AUTHOR("MMC");MODULE_LICENSE("GPL");#define DP_MAJOR 250 /*the major number of the chardev*/#define DP_MINOR 0 /*the minor number of the chardev*/#define CHARDEV_SIZE 512*500static int chropen;/*the chardev open or not*/struct cdev *chardev;/*define a char device*/char char_dev_data[CHARDEV_SIZE];static int char_read(struct file *filp, char __user *buffer, size_t, loff_t *);/*read the data from kernel*/static int char_write(struct file *filp, const char __user *buffer, size_t, loff_t *);/*write data to kernel*/static int char_open(struct inode *,struct file *);/*open the chardev*/static int char_release(struct inode *, struct file *);/*release the chardev*/static loff_t char_llseek(struct file *filp, loff_t offset, int whence);/*文件操作结构体*/static const struct file_operations char_fops = {.owner = THIS_MODULE,.llseek = char_llseek,.read = char_read,.write = char_write,.open = char_open,.release = char_release,}; static int __init char_init(void){ dev_t devno; printk(KERN_ALERT"Initing......\n"); devno=MKDEV(DP_MAJOR,DP_MINOR); chardev=cdev_alloc( ); if(chardev==NULL) { return -1; } if(register_chrdev_region(devno,10,"chardev"))//注册设备号 { printk(KERN_ALERT"Register char dev error\n"); return -1; } chropen=0; cdev_init(chardev,&char_fops);//初始化cdev if(cdev_add(chardev,devno,1))//添加cdev到系统 { printk(KERN_ALERT"Add char dev error\n"); } memset(char_dev_data, 0, CHARDEV_SIZE);//set data return 0;}/*文件打开函数*/static int char_open(struct inode *inode, struct file *file){ if(chropen==0) { chropen++; } else { printk(KERN_ALERT"Another process open the char device\n"); return -1; } try_module_get(THIS_MODULE); return 0;}/*读函数*/static ssize_t char_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos){ unsigned long p = *ppos;/*记录文件指针偏移位置*/ unsigned int count = size;/*记录需要读取的字节数*/ int ret = 0;/*返回值*/ /*判断读位置是否有效*/ if (p >= CHARDEV_SIZE)/*要读取的偏移大于设备的内存空间*/ return -1; if (count > CHARDEV_SIZE - p)/*要读取的字节大于设备的内存空间*/ count = CHARDEV_SIZE - p; /*读数据到用户空间:内核空间->用户空间交换数据*/ if (copy_to_user(buf, char_dev_data + p, count)) { ret = -EFAULT; } else { *ppos += count; ret = count; printk(KERN_INFO "read %d bytes(s) from %d\n", count, p); } return ret;}/*写函数*/static ssize_t char_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos){ unsigned long p = *ppos; unsigned int count = size; int ret = 0; /*分析和获取有效的写长度*/ if (p >= CHARDEV_SIZE) return -1; if (count > CHARDEV_SIZE - p)/*要写入的字节大于设备的内存空间*/ count = CHARDEV_SIZE - p; /*从用户空间写入数据*/ if (copy_from_user(char_dev_data + p, buf, count)) ret = -EFAULT; else { *ppos += count; /*增加偏移位置*/ ret = count; /*返回实际的写入字节数*/ printk(KERN_INFO "written %d bytes(s) from %d\n", count, p); } return ret;}/* seek文件定位函数 */static loff_t char_llseek(struct file *filp, loff_t offset, int whence){ loff_t newpos; switch(whence) { case 0: /* SEEK_SET */ /*相对文件开始位置偏移*/ newpos = offset; /*更新文件指针位置*/ break; case 1: /* SEEK_CUR */ newpos = filp->f_pos + offset; break; case 2: /* SEEK_END */ newpos = CHARDEV_SIZE -1 + offset; break; default: /* can‘t happen */ return -EINVAL; } if ((newpos<0) || (newpos>CHARDEV_SIZE)) return -EINVAL; filp->f_pos = newpos; return newpos;}/*文件释放函数*/static int char_release(struct inode *inode, struct file *file){ chropen--; module_put(THIS_MODULE); return 0;}static void __exit char_exit(void){ printk(KERN_ALERT"Unloading..........\n"); unregister_chrdev_region(MKDEV(DP_MAJOR,DP_MINOR),10);//注销cdev设备号 cdev_del(chardev);//从系统删除设备cdev}module_init(char_init);module_exit(char_exit);
4、Makefile:
ifneq ($(KERNELRELEASE),)obj-m := chardev.oelseKERNELDIR ?= /lib/modules/$(shell uname -r)/buildPWD := $(shell pwd)default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modulesendif
5、配置命令:
1)创建Makefile文件:2)执行make命令:root@mmc-vm:/usr/mmc/dirPro/charDri# make3)将生成的驱动模块插入内核:root@mmc-vm:/usr/mmc/dirPro/charDri# insmod ./chardev.ko4)查看插入后的情况:root@mmc-vm:/usr/mmc/dirPro/charDri# lsmod5)设备节点的创建:root@mmc-vm:/usr/mmc/dirPro/charDri# mknod /dev/chardev0 c 250 06)编译用户程序gcc -o chardev_test main.croot@mmc-vm:/usr/mmc/dirPro/charDri# gcc -o test test.c -std=c997)运行chmod 666 /dev/chardev0 使其它用户也可以对这个设备进行读写操作,否则只有root用户可以对它进行读写。root@mmc-vm:/usr/mmc/dirPro/charDri# chmod 666 /dev/chardev08)运行testroot@mmc-vm:/usr/mmc/dirPro/charDri# ./test9)删除设备节点,就像删除普通文件一样:root@mmc-vm:/usr/mmc/dirPro/charDri# rm /dev/chardev010)卸载内核驱动模块root@mmc-vm:/usr/mmc/dirPro/charDri# rmmod chardev.ko11)重新运行test,观察结果12)重新插入内核驱动模块和设备节点,又可以正常显示结果
6、测试程序:
刚才说了,就是filesystem的程序,但是需要把之前的fopen、fclose、fwrite、fread、fseek改为系统调用函数open、close、write、read、lseek即可。
//fileSystemPointer=fopen(fileSystemName,"wb");//读写打开一个二进制文件
fileSystemPointer=open(fileSystemName, O_RDWR, S_IRUSR|S_IWUSR);
//fseek(fileSystemPointer,0,SEEK_SET);
lseek(fileSystemPointer,0,SEEK_SET);
//fwrite(&superBlock,sizeof(struct SuperBlock),1,fileSystemPointer);//4个BLOCK
write(fileSystemPointer,&superBlock,sizeof(struct SuperBlock));//4个BLOCK
7、参考资料:
LINUX设备驱动程序(第3版)(完整版).pdf
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。