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>
#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;
}
驱动程序中动态分配设备号,通过cat /proc/devices 查看系统为memdev分配的设备号。
使用命令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