内核驱动mmap Handler利用技术

1. 内核驱动简介


在实现Linux内核驱动中,开发者可以注册一个设备驱动文件,该文件常常在/dev/目录下完成注册。该文件可以支持所有的常规文件方法,比如opening, reading, writing, mmaping, closing等等。设备驱动文件支持的操作由包含了一组函数指针的结构体file_operations描述,每个指针描述一个操作。在4.9版本内核中可以找到如下的定义。

struct file_operations {

  struct module *owner;

  loff_t(*llseek) (struct file *, loff_t, int);

  ssize_t(*read) (struct file *, char __user *, size_t, loff_t *);

  ssize_t(*write) (struct file *, const char __user *, size_t,     loff_t *);

  ssize_t(*read_iter) (struct kiocb *, struct iov_iter *);

  ssize_t(*write_iter) (struct kiocb *, struct iov_iter *);

  int(*iterate) (struct file *, struct dir_context *);

  int(*iterate_shared) (struct file *, struct dir_context *);

  unsigned int(*poll) (struct file *, struct poll_table_struct *);

  long(*unlocked_ioctl) (struct file *, unsigned int, unsigned long);

  long(*compat_ioctl) (struct file *, unsigned int, unsigned long);

  int(*mmap) (struct file *, struct vm_area_struct *);

  int(*open) (struct inode *, struct file *);

  int(*flush) (struct file *, fl_owner_t id);

  int(*release) (struct inode *, struct file *);

  int(*fsync) (struct file *, loff_t, loff_t, int datasync);

  int(*fasync) (int, struct file *, int);

  int(*lock) (struct file *, int, struct file_lock *);

  ssize_t(*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);

  unsigned long(*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);

  int(*check_flags)(int); int(*flock) (struct file *, int, struct file_lock *);

  ssize_t(*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);

  ssize_t(*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);

  int(*setlease)(struct file *, long, struct file_lock **, void **);

  long(*fallocate)(struct file *file, int mode, loff_t offset,loff_t len);

  void(*show_fdinfo)(struct seq_file *m, struct file *f);

#ifndef CONFIG_MMU

  unsigned(*mmap_capabilities)(struct file *);

#endif

  ssize_t(*copy_file_range)(struct file *, loff_t, struct file *, loff_t, size_t, unsigned int);

  int(*clone_file_range)(struct file *, loff_t, struct file *, loff_t,u64);

  ssize_t(*dedupe_file_range)(struct file *, u64, u64, struct file *, u64);

};

如同上面展示,可以实现非常多的文件操作,本文的主角是mmap handler的实现。

file_operations结构体的安装示例以及相关联的函数可以在下面看到

('/fs/proc/softirqs.c'):

static int show_softirqs(struct seq_file *p, void *v)

{

  int i, j;

  seq_puts(p, " ");

  for_each_possible_cpu(i)

    seq_printf(p, "CPU%-8d", i);

  seq_putc(p, '\n');

  for (i = 0; i < NR_SOFTIRQS; i++)

  {

    seq_printf(p, "%12s:", softirq_to_name[i]);

    for_each_possible_cpu(j)

      seq_printf(p, " %10u", kstat_softirqs_cpu(i, j));

    seq_putc(p, '\n');

  }

  return 0;

}

static int softirqs_open(struct inode *inode, struct file *file)

{

  return single_open(file, show_softirqs, NULL);

}

static const struct file_operations proc_softirqs_operations = {

  .open = softirqs_open,

  .read = seq_read,

  .llseek = seq_lseek,

  .release = single_release,

};

static int __init proc_softirqs_init(void)

{

  proc_create("softirqs", 0, NULL, &proc_softirqs_operations);

  return 0;

}

上述代码可以在'proc_softirqs_operations'结构体中看到,它允许调用open, read, llseek和close函数。当一个应用程序试图去打开一个'softirqs'文件时就会调用'open'系统调用,进而会调用到指向的'softirqs_open'函数。

2. 内核mmap Handler

2.1 简单的mmap Handler

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值