memdev.h
#ifndef _MEMDEV_H
#define _MEMDEV_H
#define MEM_MAGIC 'm'
#define MEM_RESTART _IO(MEM_MAGIC, 0)//使用内核提供的宏产生命令,
#define MEM_SET _IOW(MEM_MAGIC, 1, int)//改命令向内核传递一个整形的参数
#endif
驱动程序memdev.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include "memdev.h"
struct cdev mdev;
dev_t devno;
static long mem_ioctl(struct file* filp, unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
case MEM_RESTART:
printk("memdev restart.\n");
break;
case MEM_SET:
printk("arg is %ld\n", arg);//将用户传递下来的参数打印出来看是否一致
break;
default:
return -EINVAL;
break;
}
return 0;
}
struct file_operations memfops = {
.llseek = mem_lseek,
.unlocked_ioctl = mem_ioctl,//在2.6.36之前内核中为ioctl,2.6.36之后为unlocked_ioctl,函数参数也有变化
};
static __init int memdev_init(void)
{
cdev_init(&mdev, &memfops);
alloc_chrdev_region(&devno, 0, 2, "memdev");
cdev_add(&mdev, devno, 2);
printk("memdev_init success\n");
return 0;
}
static void __exit memdev_exit(void)
{
cdev_del(&mdev);
unregister_chrdev_region(devno, 2);
printk("memdev_exit success\n");
}
module_init(memdev_init);
module_exit(memdev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("liuwei");
MODULE_DESCRIPTION("char driver");
应用程序mem_read.c
#include <stdio.h>驱动程序中动态分配设备号,通过cat /proc/devices 查看系统为memdev分配的设备号。
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "memdev.h"
int main(int argc, char *argv[])
{
int fd = open("/dev/memdev", O_RDWR);
if (fd == -1)
{
perror("open");
return -1;
}
ioctl(fd, MEM_RESTART);//发送两个控制命令,一个不带参数,一个带一个整形的参数
ioctl(fd, MEM_SET, 10);
close(fd);
return 0;
}
使用命令mknod /dev/memdev c 252 0创建设备节点。其中252系统分配的设备号。
驱动简单的Makefile
ifeq ($(KERNELRELEASE),)
PWD := $(shell pwd)
KERNELDIR ?= /home/farsight/samba/linux-2.6.36
INSTALLDIR ?= /nfs/rootnfs/
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
install:
cp *.ko /nfs/rootnfs/
clean:
rm -rf *.o *.ko *.mod.c .*.cmd modules.order Module.symvers .tmp_versions
else
obj-m := memdev.o
endif