块设备驱动实战基础篇四 (逐渐成型,加入ioctl通信机制)

本文介绍了Linux内核中,通过misc设备的ioctl机制实现内核驱动与用户空间程序之间的通信。讲解了如何定义ioctl命令、用户态代码如何调用ioctl,以及内核驱动如何接收并处理ioctl请求。通过示例代码展示了创建和删除块设备的操作流程。
摘要由CSDN通过智能技术生成

1.6介绍一种内核与用户空间通信的方法-misc设备ioctl机制

块设备驱动开发中往往需要配合用户态的管理程序工具,管理我们的块设备,此时我们需要涉及用户空间程序与块设备通信的方法,ioctl机制就是接下来需要学习和实战的,通过ioctl机制,用户态负责发送各种命令给内核驱动;内核态接收用户态发送的命令,并根据命令执行相应的动作,如下图所示。

 

ioctl提供用户态程序使用内核态函数的通道,此时需要注册一个字符设备来实现,我们使用misc这个字符设备来实现。

 

Ioctl.h

  1 #ifndef _IOCTL_H

  2 #define _IOCTL_H

  3

  4 /* misc device name*/

  5 #define MISC_NAME "ioctl_test"

  6

  7 /**

  8  *define ioctl codes for interfacing between kernel_module and user program

  9  */

 10 #define IOCTL_CODE      0xcc /* major type code - adjusted for target system */

 11

 12 #define TEST_CMD        _IOWR (IOCTL_CODE,  0x09, unsigned long)

 13

 14 #endif

user.c

 

  1 #include <sys/ioctl.h>

  2 #include <unistd.h>

  3 #include <fcntl.h>

  4 #include <stdio.h>

  5 #include "ioctl.h"

  6

  7 int main(void)

  8 {

  9        unsigned long arg = 2013;

 10        int fd;

 11

 12        fd = open("/dev/"MISC_NAME, O_RDWR, 0);

 13        if (fd < 0) {

 14                 printf("Failed to open/dev/%s\n", MISC_NAME);

 15                 goto out;

 16        }

 17

 18        if (ioctl(fd, TEST_CMD, &arg) < 0) {

 19                 printf("Failed to executeioctl!\n");

 20        }

 21

 22        close(fd);

 23 out:

 24        return 0;

 25 }

kernel.c

  1 /*

  2  * IOCTL

  3  *Author: talk@studio

  4  */

  5

  6 #include <linux/fs.h>

  7 #include <linux/uaccess.h>

  8 #include <linux/module.h>

  9 #include <linux/miscdevice.h>

 10

 11 #include "ioctl.h"

 12

 13 static int ioctl(struct inode *inode,struct file *file,

 14                      unsigned int cmd,unsigned long user)

 15 {

 16        unsigned long arg;

 17        int ret = 0;

 18

 19        if (_IOC_TYPE(cmd) != IOCTL_CODE) {

 20                 printk("Unknown ioctlcommand 0x%x\n", cmd);

 21                 ret = -ENOTTY;

 22                 goto out;

 23        }

 24

 25        switch (cmd) {

 26                 case TEST_CMD:

 27                         ret =copy_from_user(&arg, (unsigned long *)user, sizeof(unsigned lon    g));

 28                        if (ret) {

 29                                printk("copy from user failed!\n");

 30                         } else {

 31                                printk("received IOctl[arg=%lu] from user!\n", arg);

 32                         }

 33                         break;

 34                 default:

 35                         printk("Unknownioctl command[0x%x].\n", cmd);

36                         ret = -ENOTTY;

 37                         break;

 38        }

 39 out:

 40        return ret;

 41 }

 42

 43 static struct file_operations_misc_ctl_fops = {

 44        .ioctl = ioctl,

 45        .owner = THIS_MODULE,

 46 };

 47

 48 static struct miscdevice _misc_dev = {

 49        .minor = MISC_DYNAMIC_MINOR,

 50        .name = MISC_NAME,

 51        .fops = &_misc_ctl_fops

 52 };

 53

 54 static int __init ioctl_init(void)

 55 {

 56        int ret;

 57

 58        ret = misc_register(&_misc_dev);

 59        if (ret) { <

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值