麻烦从用户空间C调用ioctl

Stu*_*art 3 c ioctl linux-kernel

我正在尝试实现一个程序来访问嵌入式系统上的内存.我需要访问一些控制寄存器,所以我认为ioctl是最好的方法.我已将ioctl添加到fops中:

struct file_operations aes_fops = {
  read: aes_read,
  write: aes_write,
  unlocked_ioctl: aes_ioctl,
  open: aes_open,
  release: aes_release
};
Run Code Online (Sandbox Code Playgroud)

并设置了功能:

int aes_ioctl(struct inode *inode,  
     struct file *file, 
     unsigned int ioctl_num,    
     unsigned long ioctl_param){

     printk(KERN_INFO "in ioctl\n");
....
}
Run Code Online (Sandbox Code Playgroud)

但我没有进入这个功能.这是我的用户空间代码.如果我这样做完全错了,请帮助我理解.

int main(int argc, char* argv[]){
    int fd = fopen("/dev/aes", "r+");
    ioctl(fd, 0, 1);
    fclose(fd);
}
Run Code Online (Sandbox Code Playgroud)

有些代码显然适用于较旧的内核,因为我正在编译一个已修改旧版Linux的嵌入式系统.

Dan*_*oni 7

您的代码的问题是您正在使用的请求编号 - 0.内核有一些保留供内部使用的请求编号.内核将请求编号视为结构,将其分隔为字段并为其调用正确的子系统.

请参阅Documentation/ioctl/ioctl-number.txt(来自Linux 3.4.6):

Code  Seq#(hex) Include File            Comments
========================================================
0x00    00-1F   linux/fs.h              conflict!
0x00    00-1F   scsi/scsi_ioctl.h       conflict!
0x00    00-1F   linux/fb.h              conflict!
0x00    00-1F   linux/wavefront.h       conflict!
0x02    all     linux/fd.h
0x03    all     linux/hdreg.h
...
Run Code Online (Sandbox Code Playgroud)

根据您的使用情况,您必须遵循内核指南添加新的ioctls():

If you are adding new ioctl's to the kernel, you should use the _IO
macros defined in <linux/ioctl.h>:

    _IO    an ioctl with no parameters
    _IOW   an ioctl with write parameters (copy_from_user)
    _IOR   an ioctl with read parameters  (copy_to_user)
    _IOWR  an ioctl with both write and read parameters.
Run Code Online (Sandbox Code Playgroud)

有关Documentation/ioctl/ioctl-decoding.txt如何构造这些数字的更多详细信息,请参阅内核自己的文档.

在实践中,如果你选择代码1,这意味着从开始0x100直到0x1ff,你会被罚款.