Linux内核开发示例

[TOC]

内核驱动

结构体

  • inode结构体

    inode结构体是用来在内核中表示一个设备的,用户层看不到这个结构体,我们需要初始化它内部的一个结构体cdev:

    struct cdev *pcdev_reversion;
    pcdev_reversion = cdev_alloc(); //inode 结构的一个结构体,在内核内部表示设备
    pcdev_reversion->owner = THIS_MODULE;
    pcdev_reversion->ops = &file_ops;
    cdev_add(pcdev_reversion, dev, number_reversion);

    如果我们没有用动态创建的方式来创建这个结构体,那么就需要使用cdev_init来初始化它,这里cdev_alloc在分配后就立即初始化了设备,所以我们就不用再次初始化了。

    注销此设备:

    cdev_del(pcdev_reversion);
  • file结构体

    文件结构体是内核暴露给用户层的,用户层通过这个文件结构体来访问内核里的cdev设备:

    static struct file_operations file_ops = {
      .owner                 = THIS_MODULE,
      .open                 = open_reversion,
      .write                 = write_reversion,
      .read                 = read_reversion,
      .unlocked_ioctl     = ioctl_reversion
    };
  • 设备号结构体dev_t

    这个结构体是一个32位的整数,里面存放了设备的设备号,设备号是所有设备在内核中的标识,是唯一键,为了避免冲突,我们使用动态分配的方式来注册设备号:

          if(major_reversion){
          dev = MKDEV(major_reversion, minor_reversion);
          ret = register_chrdev_region(dev, number_reversion, REVERSION_NAME);
      } else {
          ret = alloc_chrdev_region(&dev, minor_reversion, number_reversion, REVERSION_NAME);
          major_reversion = MAJOR(dev);
      }
      if(ret < 0){
          printk(KERN_WARNING "reversion:can't get major %d\n", major_reversion);
          return ret;
      }

    释放设备号:

    unregister_chrdev_region(MKDEV(major_reversion, minor_reversion), number_reversion);//unregion device

文件操作

读操作

写操作

控制操作

用户层代码

创建设备

我们在将驱动加载后,就可以在/proc/devices中看到设备的设备号了:

然后我们根据这个设备号创建设备:

首先获取设备号,用awk命令可获取到

我们动态分配得到的是设备的主设备号,次设备号是我们代码里写的0,然后创建设备:

创建成功。 代码如下:

读取设备

读取设备的操作就和读取文件一样:

返回值是我们在内核中写入的东西。

最后更新于

这有帮助吗?