mycdev.c:
#include<linux/init.h>
#include<linux/module.h>#include<linux/types.h>
#include<linux/fs.h>
#include<linux/mm.h>
#include<linux/sched.h>
#include<linux/cdev.h>
#include<linux/kernel.h>
#include<asm/io.h>
#include<asm/uaccess.h>
MODULE_LICENSE("GPL");
#define MYCDEV_MAJOR 231 //cat /proc/devices查看系统中未使用的字符设备主设备号
#define MYCDEV_SIZE 1024
static int mycdev_open(struct inode *inode, struct file *fp)
{
return 0;
}
static int mycdev_release(struct inode *inode, struct file *fp)
{
return 0;
}
static ssize_t mycdev_read(struct file *fp, char __user *buf, size_t size, loff_t *pos)
{
unsigned long p = *pos;
unsigned int count = size;
char kernel_buf[MYCDEV_SIZE] = "This is mycdev!";
if(p >= MYCDEV_SIZE)
return -1;
if(count > MYCDEV_SIZE)
count = MYCDEV_SIZE - p;
if (copy_to_user(buf, kernel_buf, count) != 0) {
printk("read error!\n");
return -1;
}
printk("reader: %d bytes was read...\n",count);
return count;
}
static ssize_t mycdev_write(struct file *fp, const char __user *buf, size_t size, loff_t *pos)
{
return size;
}
static const struct file_operations mycdev_fops =
{
.owner = THIS_MODULE,
.read = mycdev_read,
.write = mycdev_write,
.open = mycdev_open,
.release = mycdev_release,
};
static int __init mycdev_init(void)
{
int ret;
printk("mycdev module is staring..\n");
ret =register_chrdev(MYCDEV_MAJOR, "my_cdev", &mycdev_fops);
if (ret < 0) {
printk("register failed..\n");
return 0;
} else {
printk("register sucess..\n");
}
return 0;
}
static void __exit mycdev_exit(void)
{
printk("mycdev module is leaving..\n");
unregister_chrdev(MYCDEV_MAJOR, "my_cdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
先编译mycdev.c模块,并把mycdev.ko插入内核。
然后创建设备文件结点sudo mknod /dev/mycdev c 231 0;(231的来源看代码中的注释)
修改设备文件权限:sudo chmod 777 /dev/mycdev.
编写用户态测试程序:test.c
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
int main()
{
int testdev;
int i, ret;
char buf[10];
testdev = open("/dev/mycdev", O_RDWR);
if(testdev == -1) {
printf("cannot open file.\n");
exit(1);
}
if(ret = read(testdev, buf, 10) < 10) {
printf("read error!\n");
exit(1);
}
for (i=0; i<10; i++) {
printf("%c", buf[i]);
}
printf("\n");
close(testdev);
return 0;
}
用户态测试程序结果:
dmesg结果:
mycdev.ko卸载后用户态测试程序: