Linux内核模块/ IOCTL:设备的ioctl不合适
发布时间:2020-05-23 08:34:31 所属栏目:Linux 来源:互联网
导读:我正在编写一个 Linux内核模块(LKM)作为伪驱动程序 – 我无法弄清楚如何在LKM(wait.c)和用户级程序(user.c)之间进行IOCTL调用). 设备驱动程序的幻数是0xBF – LKM不与物理块/字符设备通信,它只是一个练习.据我所知,对KERN_IOCTL_CREATE_EVENT的IOCTL调用格式
|
我正在编写一个 Linux内核模块(LKM)作为伪驱动程序 – 我无法弄清楚如何在LKM(wait.c)和用户级程序(user.c)之间进行IOCTL调用). 设备驱动程序的幻数是0xBF – LKM不与物理块/字符设备通信,它只是一个练习.据我所知,对KERN_IOCTL_CREATE_EVENT的IOCTL调用格式不正确&幻数不正确. 我试图使用的IOCTL调用是: #include <sys/ioctl.h>
#define KERN_IOCTL_CREATE_EVENT _IOWR(WAIT_DEVICE_MAGIC,1,int)
int main(){
int ret;
int fd;
fd = open("/dev/wait",0);
if(fd < 0){
return -1;
}
ret = ioctl(fd,KERN_IOCTL_CREATE_EVENT,0);
错误: [fail]: KERN_IOCTL_CREATE_EVENT: Inappropriate ioctl for device 用户模式应用程序可以打开/关闭指向设备的文件描述符:/ dev / wait但是case / switch语句不接受IOCTL调用.有什么建议? 这是#uname -a的输出 Linux vagrant-ubuntu-trusty-64 3.13.11.11+ #1 SMP Mon Dec 1 20:50:23 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux wait.c #include <linux/miscdevice.h>
#include <linux/moduleparam.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <asm/uaccess.h>
#include <linux/sched.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/fs.h>
#include "wait.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Tyler Fisher <tyler@tylerfisher.org>");
MODULE_DESCRIPTION("In-kernel wait queue");
static unsigned long event_table_size = 50;
module_param(event_table_size,ulong,(S_IRUSR | S_IRGRP | S_IROTH));
MODULE_PARM_DESC(event_table_size,"Size of event table (i.e. how many processes can be blocking)");
/* IOCTL function headers */
static int wait_open(struct inode *,struct file *);
static int wait_close(struct inode *,struct file *);
static long wait_ioctl(struct inode *,struct file *,unsigned int,unsigned long);
/* other function headers */
static long event_open(int event_id);
/* file operations */
static struct file_operations wait_fops = {
.owner = THIS_MODULE,.open = wait_open,.release = wait_close,.llseek = noop_llseek,.unlocked_ioctl = wait_ioctl
};
/* device handler */
static struct miscdevice wait_misc_device = {
.minor = MISC_DYNAMIC_MINOR,.name = WAIT_DEVICE_NAME,.fops = &wait_fops
};
/* open wait device */
static int wait_open(struct inode *inode,struct file *file){
dev_t node = iminor(inode);
if(MINOR(node) != WAIT_DEVICE_MINOR){
return -ENODEV;
}
return 0;
}
static int wait_close(struct inode *inode,struct file *file){
return 0;
}
static long wait_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long sub_cmd){
switch(cmd){
case KERN_IOCTL_CREATE_EVENT:
printk(KERN_INFO "[wait device]: create event %lun",sub_cmd);
return event_open(sub_cmd);
default:
return -ENOENT;
}
}
static long event_open(int id){
return 0;
}
static long __init wait_init(void){
if(misc_register(&wait_misc_device) < 0){
printk(KERN_ERR "[wait device] failed to register devicen");
return -1;
}
printk(KERN_INFO "[wait device] has been registeredn");
return 0;
}
static void __exit wait_exit(void){
misc_deregister(&wait_misc_device);
printk(KERN_INFO "[wait device] has been unregisteredn");
}
module_init(wait_init);
module_exit(wait_exit);
wait.h #include <linux/ioctl.h> #define WAIT_DEVICE_NAME "wait" #define WAIT_DEVICE_MAGIC 0xBF #define WAIT_DEVICE_MAJOR 200 #define WAIT_DEVICE_MINOR 0 #define KERN_IOCTL_CREATE_EVENT _IOWR(WAIT_DEVICE_MAGIC,0x01,int) #define MAX_WAITING 5 IOCTL调用的测试程序: user.c的 #include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#define WAIT_DEVICE_MAGIC 0xBF
#define KERN_IOCTL_CREATE_EVENT _IOWR(WAIT_DEVICE_MAGIC,int)
#define KERN_IOCTL_DESTROY_EVENT _IOWR(WAIT_DEVICE_MAGIC,0x02,int)
#define KERN_IOCTL_LOCK_EVENT _IOWR(WAIT_DEVICE_MAGIC,0x03,int)
#define KERN_IOCTL_UNLOCK_EVENT _IOWR(WAIT_DEVICE_MAGIC,0x04,int)
int main(){
int fd;
if(fd = open("/dev/wait",O_RDWR) < 0){
perror("failed to open /dev/wait");
return -1;
}
/* test IOCTL: event creation */
if(ioctl(fd,0) < 0){
perror("[fail]: KERN_IOCTL_CREATE_EVENT");
return -1;
}
return 0;
}
Makefile文件 obj-m += wait.o CFLAGS_wait.o += -DDEBUG all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 为了测试LKM – 清除dmesg,编译&执行user.c w / GCC: # dmesg -c > /dev/null 2>&1 # make # rmmod wait.ko # insmod wait.ko # gcc user.c -o user && ./user 调试错误的数量令人尴尬.我感到很难分享这一点 – 并且意识到这可能会导致问题被关闭/失去遗忘. # sh test.sh
[+] cleared dmesg
make -C /lib/modules/3.13.11.11+/build M=/home/vagrant/PROG40000-kernel-synchronization modules
make[1]: Entering directory `/home/vagrant/ubuntu-trusty'
CC [M] /home/vagrant/PROG40000-kernel-synchronization/wait.o
/home/vagrant/PROG40000-kernel-synchronization/wait.c:61:1: warning: initialization from incompatible pointer type [enabled by default]
};
^
/home/vagrant/PROG40000-kernel-synchronization/wait.c:61:1: warning: (near initialization for ‘wait_fops.unlocked_ioctl’) [enabled by default]
In file included from include/linux/moduleparam.h:4:0,from /home/vagrant/PROG40000-kernel-synchronization/wait.c:11:
/home/vagrant/PROG40000-kernel-synchronization/wait.c: In function ‘__inittest’:
include/linux/init.h:297:4: warning: return from incompatible pointer type [enabled by default]
{ return initfn; }
^
/home/vagrant/PROG40000-kernel-synchronization/wait.c:167:1: note: in expansion of macro ‘module_init’
module_init(wait_init);
^
Building modules,stage 2.
MODPOST 1 modules
CC /home/vagrant/PROG40000-kernel-synchronization/wait.mod.o
LD [M] /home/vagrant/PROG40000-kernel-synchronization/wait.ko
make[1]: Leaving directory `/home/vagrant/ubuntu-trusty'
[--dmesg--]
[13112.810008] [wait device] has been unregistered
[13112.819049] [wait device] has been registered
[-/dmesg--]
[+] compiled user-mode program
-----
[fail]: KERN_IOCTL_CREATE_EVENT: Inappropriate ioctl for device
[fail]: KERN_IOCTL_CREATE_EVENT: Inappropriate ioctl for device
[+] executed user-mode program
-----
[--dmesg--]
[13112.810008] [wait device] has been unregistered
[13112.819049] [wait device] has been registered
[13112.893049] SOMEONE DARE READ FROM ME!?
[13112.893057] [wait device] invalid magic number: 0:0:191
[13112.893535] [wait device] invalid magic number: 0:0:191
[-/dmesg--]
解决方法好的.所以.这是解决方案.在Linux内核2.6.x中,_ioctl调用的声明已更改 static long wait_ioctl(struct inode *,unsigned long); 至: static long wait_ioctl(struct file *,unsigned long); 因此修复: ...
static long wait_ioctl(struct file *,unsigned long);
...
static long wait_ioctl(struct file *file,unsigned long sub_cmd){
if(_IOC_TYPE(cmd) != WAIT_DEVICE_MAGIC){
printk(KERN_INFO "[wait device] invalid magic number: %u:%u:%u",_IOC_TYPE(cmd),cmd,WAIT_DEVICE_MAGIC);
return -ENOTTY;
}
.... (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
