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