Linux设备驱动中的ioctl

时间:2021-03-24 17:55:00

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