一个虚拟的字符驱动程序实验报告
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
rm $(obj-m) *.o *.ko Module* module* *.mod.c endif
{ return (ssize_t)-EINVAL;
}
static int Major; struct file_operations Fops = { .owner=THIS_MODULE, .open=device_open, .release=device_release, .read=device_read, .write=device_write };
printk("Device: %d.%d\n", inode->i_rdev >> 8, inode->i_rdev & 0xFF);
//MOD_INC_USE_COUNT; return 0; }
static int device_release(struct inode *inode, struct file *file)
printf("read----success!\nThe readings: "); for(i = 0; i < sizeof(buffer); i++)printf("%c", buffer[i]);
printf("\n\n");
}
if(write(fd, buffer, sizeof(buffer)) < 0) { printf("写文件失败:\n");
5. 用命令 insmod char_dev.ko 加载
6. 用命令 lsmod 察看是否成功加载 7. 使用 dmesg 察看主设备号
8. 使用 mknod /dev/char_dev c 249 1 在/dev 目录下创建设备文件 9. 运行 testchardev.c 测试
实验总结:
通过 1. 自定义驱动程序描述符 2. 预订主设备号 3. 初始化自定义描述符 4. 初始化 gendisk 描述符 5. 初始化块设备操作表 6. 分配和初始化请求队列 7. 设置中断处理程序 8. 注册磁盘
static int chardev_init() {
Major = register_chrdev(0, DEVICE_NAME, &Fops);
if (Major < 0) {
printk ("device failed with %d\n", Major); return Major; } printk ("mknod %s c %d <minor>\n", DEVICE_NAME, Major); return 0; } static void chardev_exit() { printk("<1>""remove chardev module\n"); unregister_chrdev(Major, DEVICE_NAME); } module_init(chardev_init); module_exit(chardev_exit);
实验报告 实验名称:一个虚拟的字符驱动程序 实验目的:
通过对一个虚拟设备驱动的编写熟悉,驱动程序的编写过程和注意 事项。加深对课程的理解
实验环境:
Ubuntu 11.04
实验步骤:
1. 编写 char_dev.c(见附录 1) 2. 编写测试文件 testchardev.c(见附录 2) 3. 编写 Makefile 文件(见附录 3) 4. make
int fd; int i; char buffer[20];
fd = open("/dev/char_dev", O_RDWR); if(fd < 0) {
printf("打开文件失败:\n"); printf("open error: %s\n\n", strerror(errno)); return 1; } else{ printf("打开文件成功:\n"); printf("open----success!\nThe fd:%d\n\n", fd); } if(read(fd, buffer, sizeof(buffer)) < 0){ printf("读文件失败:\n"); printf("read file error: %s\n", strerror(errno)); } else { printf("读文件成功:\n");
在 char_dev.c 中达到了注册和初始化驱动程序;通过动态分配的方式 确定了主次设备号。然后通过加载将 char_dev 加载到了/dev 下。最 后编写测试用例。
附录: 1. char_dev.c
//#include <linux/kernel.h> /* We're doing kernel work */ #include <linux/init.h> #include <linux/module.h> /* Specifically, a module */ MODULE_LICENSE("GPL");
{ int i; printk("<0>""read char_dev\n"); for(i = 0; i < length; i++) { put_user('a',buffer++); } return (ssize_t)length;
}
static ssize_t device_write(struct file *file, const char *buffer, /* The buffer */ size_t length, /* The length of the buffer */ loff_t *offset) /* Our offset in the file */
///* Deal with CONFIG_MODVERSIONS */
//#if CONFIG_MODVERSIONS==1 //#define MODVERSIONS //#include <linux/modversions.h> //#endif /* For character devices */ #include <linux/fs.h> /* The character device definitions are here */ #include <asm/uaccess.h> /* for put_user */
}
3.Makefile
ifneq ($(KERNELRELEASE),) obj-m:=char_dev.o else KD ?=/lib/modules/$(shell uname -r)/build PWD :=$(shell pwd) default:
$(MAKE) -C $(KD) M=$(PWD) modules clean:
2.testchardev.c
#include <stdio.h> #include <sys/errno.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h>
int main() {
#define DEVICE_NAME "char_dev"
static int device_open(struct inode *inode, struct file *file) { // static int counter = 0; #ifdef DEBUG
printk ("device_open(%p,%p)\n", inode, file); #endif
printf("write----failed!\nthe error: %s\n\n", strerror(errno)); } else {printf("写文件成功:\n");printf("write---success!\n\n");}
if(close(fd) < 0){printf("关闭文件失败:\n"); printf("close file error!\n");} else {printf("关闭文件成功:\n");printf("close----success!\n\n");} return 0;
{ #ifdef DEBUG
printk ("device_release(%p,%p)\n", inode, file); #endif
//MOD_DEC_USE_COUNT; return 0; }
static ssize_t device_read(struct file *file, char *buffer, /* The buffer to fill源自文库with data */ int length, /* The length of the buffer */ loff_t *offset) /* Our offset in the file */
{ return (ssize_t)-EINVAL;
}
static int Major; struct file_operations Fops = { .owner=THIS_MODULE, .open=device_open, .release=device_release, .read=device_read, .write=device_write };
printk("Device: %d.%d\n", inode->i_rdev >> 8, inode->i_rdev & 0xFF);
//MOD_INC_USE_COUNT; return 0; }
static int device_release(struct inode *inode, struct file *file)
printf("read----success!\nThe readings: "); for(i = 0; i < sizeof(buffer); i++)printf("%c", buffer[i]);
printf("\n\n");
}
if(write(fd, buffer, sizeof(buffer)) < 0) { printf("写文件失败:\n");
5. 用命令 insmod char_dev.ko 加载
6. 用命令 lsmod 察看是否成功加载 7. 使用 dmesg 察看主设备号
8. 使用 mknod /dev/char_dev c 249 1 在/dev 目录下创建设备文件 9. 运行 testchardev.c 测试
实验总结:
通过 1. 自定义驱动程序描述符 2. 预订主设备号 3. 初始化自定义描述符 4. 初始化 gendisk 描述符 5. 初始化块设备操作表 6. 分配和初始化请求队列 7. 设置中断处理程序 8. 注册磁盘
static int chardev_init() {
Major = register_chrdev(0, DEVICE_NAME, &Fops);
if (Major < 0) {
printk ("device failed with %d\n", Major); return Major; } printk ("mknod %s c %d <minor>\n", DEVICE_NAME, Major); return 0; } static void chardev_exit() { printk("<1>""remove chardev module\n"); unregister_chrdev(Major, DEVICE_NAME); } module_init(chardev_init); module_exit(chardev_exit);
实验报告 实验名称:一个虚拟的字符驱动程序 实验目的:
通过对一个虚拟设备驱动的编写熟悉,驱动程序的编写过程和注意 事项。加深对课程的理解
实验环境:
Ubuntu 11.04
实验步骤:
1. 编写 char_dev.c(见附录 1) 2. 编写测试文件 testchardev.c(见附录 2) 3. 编写 Makefile 文件(见附录 3) 4. make
int fd; int i; char buffer[20];
fd = open("/dev/char_dev", O_RDWR); if(fd < 0) {
printf("打开文件失败:\n"); printf("open error: %s\n\n", strerror(errno)); return 1; } else{ printf("打开文件成功:\n"); printf("open----success!\nThe fd:%d\n\n", fd); } if(read(fd, buffer, sizeof(buffer)) < 0){ printf("读文件失败:\n"); printf("read file error: %s\n", strerror(errno)); } else { printf("读文件成功:\n");
在 char_dev.c 中达到了注册和初始化驱动程序;通过动态分配的方式 确定了主次设备号。然后通过加载将 char_dev 加载到了/dev 下。最 后编写测试用例。
附录: 1. char_dev.c
//#include <linux/kernel.h> /* We're doing kernel work */ #include <linux/init.h> #include <linux/module.h> /* Specifically, a module */ MODULE_LICENSE("GPL");
{ int i; printk("<0>""read char_dev\n"); for(i = 0; i < length; i++) { put_user('a',buffer++); } return (ssize_t)length;
}
static ssize_t device_write(struct file *file, const char *buffer, /* The buffer */ size_t length, /* The length of the buffer */ loff_t *offset) /* Our offset in the file */
///* Deal with CONFIG_MODVERSIONS */
//#if CONFIG_MODVERSIONS==1 //#define MODVERSIONS //#include <linux/modversions.h> //#endif /* For character devices */ #include <linux/fs.h> /* The character device definitions are here */ #include <asm/uaccess.h> /* for put_user */
}
3.Makefile
ifneq ($(KERNELRELEASE),) obj-m:=char_dev.o else KD ?=/lib/modules/$(shell uname -r)/build PWD :=$(shell pwd) default:
$(MAKE) -C $(KD) M=$(PWD) modules clean:
2.testchardev.c
#include <stdio.h> #include <sys/errno.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h>
int main() {
#define DEVICE_NAME "char_dev"
static int device_open(struct inode *inode, struct file *file) { // static int counter = 0; #ifdef DEBUG
printk ("device_open(%p,%p)\n", inode, file); #endif
printf("write----failed!\nthe error: %s\n\n", strerror(errno)); } else {printf("写文件成功:\n");printf("write---success!\n\n");}
if(close(fd) < 0){printf("关闭文件失败:\n"); printf("close file error!\n");} else {printf("关闭文件成功:\n");printf("close----success!\n\n");} return 0;
{ #ifdef DEBUG
printk ("device_release(%p,%p)\n", inode, file); #endif
//MOD_DEC_USE_COUNT; return 0; }
static ssize_t device_read(struct file *file, char *buffer, /* The buffer to fill源自文库with data */ int length, /* The length of the buffer */ loff_t *offset) /* Our offset in the file */