Android系统中, 驱动程序因商业需求分为运行在用户空间的hardware层以及运行在内核空间的驱动程序, 大多情况下内核驱动都需要提供用户空间访问的接口。

Linux内核空间到用户空间的接口有主要有以下几种类型
1.系统调用
   系统调用是指系统实现的所有系统调用所构成的集合,即程序接口。
   linux系统调用分为:进程控制,文件系统控制,系统控制,内存管理,网络管理,用户管理,进程管理等类型
   linux操作系统中,系统调用的ID通常在arch/{体系结构}/include/asm/目录的unistd.h文件中.
   可增加系统调用为用户空间提供访问接口,用于系统调用是UNIX标准的内容,所以一般情况下不这样做。

2.字符设备节点
   字符设备进行I/O操作不经过操作系统的缓冲区,每次操作只传输一个字符,可以通过字符设备文件来访问
   文件操作file_operations表示对一个文件的操作,其定义在/kernel/include/linux/fs.h
   ........
   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 (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
      ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, 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 *);
      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 (*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);
      int (*show_fdinfo)(struct seq_file *m, struct file *f);
   };
   ........
   // 字符设备的注册函数

static inline int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops) 
   {
      return __register_chrdev(major, 0, 256, name, fops);
   }
   // 字符设备的销毁函数
   static inline void unregister_chrdev(unsigned int major, const char *name)
   {
      __unregister_chrdev(major, 0, 256, name);
   }
   ........
   对于一般的文件,可以通过通用的文件操作,如open,read,write,ioctl,mmap,release等,
   对于简单的字符设备,也是驱动的设备节点,它的文件操作与一般的文件不一样,需要单独实现。
   字符设备的驱动程序,可以基于字符设备的驱动程序框架来构建,也可基于特定的字符设备架构来构建.
   基于字符设备的驱动程序架构来建设:
   直接实现对字符设备的注册函数进行注册,此时定义的字符设备一般具有一个唯一的主设备号.
   在注册具体的字符设备时,构建file_operations中的各个成员函数指针
   基于特定的字符设备驱动程序架构来构建:(Misc驱动程序,帧缓存驱动程序,TTY驱动程序等)
   这些驱动程序的架构通常对字符设备驱动架构进行封装,实现自己的架构,并且具有了自己的注册机制。
   在具体的驱动程序的实现中,通过这种驱动程序架构的注册函数进行注册,实现相关的函数。
   此时,驱动程序的架构一般已经实现了主设备号,具体的驱动程序实现的是次设备号。
   在用户空间通过/dev/中设备节点调用驱动程序顺序:用户空间-->字符设备驱动程序的架构-->该类驱动程序的框架-->具体驱动程序的实现。

3.块设备节点(光盘,硬盘,软盘)
   块设备采用随机访问的方式传输数据,并且数据总是具有固定大小的快,为了提高数据传输效率,块设备驱动程序内部采用块缓冲技术.
   块设备的操作在/kernel/include/linux/blkdev.h中定义
   struct block_device_operations {
      int (*open) (struct block_device *, fmode_t);
      void (*release) (struct gendisk *, fmode_t);
      int (*rw_page)(struct block_device *, sector_t, struct page *, int rw);
      int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
      int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
      int (*direct_access) (struct block_device *, sector_t,
      void **, unsigned long *);
      unsigned int (*check_events) (struct gendisk *disk,
      unsigned int clearing);
      /* ->media_changed() is DEPRECATED, use ->check_events() instead */
      int (*media_changed) (struct gendisk *);
      void (*unlock_native_capacity) (struct gendisk *);
      int (*revalidate_disk) (struct gendisk *);
      int (*getgeo)(struct block_device *, struct hd_geometry *);
      /* this callback is with swap_lock and sometimes page table lock held */
      void (*swap_slot_free_notify) (struct block_device *, unsigned long);
      struct module *owner;
   };

注册与注销/kernel/include/linux/fs.h
   extern int register_blkdev(unsigned int, const char *);
   extern void unregister_blkdev(unsigned int, const char *);

对于块设备,由于也是设备节点,也可以使用文件接口来访问,一般不直接访问块设备节点,而是使用文件系统来访问。可用df或mount来查看挂载情况
   Android块设备在/dev/block/目录中

4.网络设备
   网络设备没有文件系统的节点,使用socket机制,通过专有的数据结构进行访问,系统内部支持数据的收发。
   网络设备与字符设备和块设备最大的区别在于网络设备没有文件系统的节点。
   一般网络驱动程序不会由应用程序调用,而是由linux内核的网络模块调用,用户空间程序通过socket等通用网络接口,间接调用网络驱动程序。
   访问网络设备时,需要用到socket相关的几个函数:socket(),bind(),listen(),accept(),connect()等
   socket()和open一样,返回类型也是一个文件描述符,表示一个在进程中打开的文件。可以用通常的文件操作来对这个文件描述符进行操作。
   网络设备的核心定义在/kernel/include/linux/netdevice.h
   ........
   struct net_device {
      char name[IFNAMSIZ];
      struct hlist_node name_hlist;
      char *ifalias;
      ........
   };
   ........
   int register_netdev(struct net_device *dev); // 注册函数
   void unregister_netdev(struct net_device *dev);// 撤销函数
   ........

5.proc文件系统(ramconsole驱动)
   proc文件在/proc目录中,用于查看有关硬件,进程的状态,也可以通过操作proc文件系统进行控制工作
   proc文件系统的创建函数定义在/kernel/include/linux/proc_fs.h
   struct proc_dir_entry { // 表示一个目录项的入口
      unsigned int low_ino;
      umode_t mode;
      nlink_t nlink;
      kuid_t uid;
      kgid_t gid;
      loff_t size;
      const struct inode_operations *proc_iops; // 文件系统操作
      const struct file_operations *proc_fops; // 文件系统节点操作
      ........
   };

6.sys文件系统
    sys文件系统与proc有些类似,除了查看和设定内核参数功能之外,还有位linux统一设备模型作为管理之用
    sys文件系统只有读和写两个接口,不支持参数传递,大规模数据块操作等复杂的操作
    sys文件系统在linux文件系统的/sys/目录中,如/sys/bus/为总线目录结构,/sys/class为按功能分类设备模型
    通过cat与echo重定向来查看与设置/sys目录

7.无用户空间接口

转载于:https://www.cnblogs.com/ctyjqcq/p/5085572.html

AndroidM 内核空间到用户空间接口类型相关推荐

  1. linux内核空间和用户空间的是怎样区别的,如何交互,如何从用户空间进入内核空间

    linux驱动程序一般工作在内核空间,但也可以工作在用户空间.下面我们将详细解析,什么是内核空间,什么是用户空间,以及如何判断他们. Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,L ...

  2. linux 内核空间与用户空间 简介

    本文以 32 位系统为例介绍内核空间(kernel space)和用户空间(user space). 内核空间和用户空间 对 32 位操作系统而言,它的寻址空间(虚拟地址空间,或叫线性地址空间)为 4 ...

  3. 关于linux内核空间与用户空间的理解

    简介 现代计算机都有两种以上的运行模式(普通模式.特权模式),linux系统只有两层:高优先级模式(特权模式),低优先级模式(普通模式).linux系统在高优先级模式中运行系统内核代码以及与硬件密切相 ...

  4. Linux进程地址空间与进程内存布局详解,内核空间与用户空间

    Linux进程地址空间与进程内存布局详解 程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码. 初始化过的数据(Data):在程序运行初已经对变量进行初始化的数据. 未初始化过的数据( ...

  5. linux内核驱动之 用户空间和内核空间

    A module runs in kernel space, whereas applications run in user space. This concept is at the base o ...

  6. ion android 内核,Android Ion用户空间和内核空间

    为什么需要ION 回顾2011年末[2],LWN审查了android kernel patch[3],以期望将这些patch合并到kernel主线中.但是PMEM(android实现的 一个内存分配器 ...

  7. Linux内核空间和用户空间

    在Linux系统中存在进程的概念: 进程的分类: 用户进程:运行在用户空间的进程被称为用户进程 内核进程:运行在内核空间的进程被称为内核进程 进程的空间: 系统会为每一个进程分0-4G的虚拟寻址空间, ...

  8. Windows内核--内核空间和用户空间(3.6)

    内核喜欢抽象出句柄给用户空间 句柄, Handle, 表达处理.控制之意.内核不会直接暴露指针给用户空间,这样会增大内核风险.相反,内核抽象出Handle给用户态,不管是文件.进程.线程等对象,通过H ...

  9. linux内核futex快速用户空间互斥体简介

    futex内核同步 futex快速用户空间互斥体,用来给上层应用构建更高级别的同步机制,是实现信号量和锁的基础. 进程间通信,管道.消息队列.信号量.共享内存.套接字.信号. 使用信号量(semget ...

最新文章

  1. 5 个越早知道越好的 Python 特性
  2. 基于eclipse创建android的helloworld工程
  3. layui根据name获取对象_JavaScript对象 - 初识
  4. dtm文件生成等高线 lisp_南方cass如何用图面高程点生成等高线
  5. 三个月可更改用户昵称两次
  6. Linux:Vim的安装与配置
  7. [USACO13NOV]Crowded Cows【暴力枚举】
  8. 8uftp,什么是8uftp
  9. iOS进阶:【1、 使用文件路径获取自定义字体名称2、添加资源包到工程→在info.plist文件中注册字体→在工程Bundle Resource中复制字体资源包→代码检测查询加入的字体并使用。】
  10. 一文掌握字符串之正则表达式,值得收藏!
  11. launch参数JAVA_javafx主要方法launch(args)如何工作? - java
  12. 根据GFF3文件统计外显子大小和数量以及内含子大小
  13. 台式计算机读不到u盘怎么回事,u盘读不出来怎么办?Win7电脑无法识别设备如何解决?...
  14. 王者荣耀KPL秋季赛总决赛预测(AG VS DYG)
  15. 一款自制calendar插件
  16. 机器人波波熊_【菠菠智能悦读机器人绘本更新篇】新技能get!BoBo本周新增绘本103本!...
  17. 在EXCEL中VBA编程检验身份证号码有效性
  18. 奇点临近:人类文明延续
  19. 【离散数学】数理逻辑 第一章 命题逻辑(3) 逻辑等价与蕴含
  20. 【Codeforces Round #540 (Div. 3)】 A B C D1 D2 E F1

热门文章

  1. 临时禁用自增列插入数据
  2. Flash翻书效果研究
  3. 20种小技巧,玩转Google Colab
  4. 这可能是目前最好的图像超分辨率算法,刚刚开源了
  5. 计算机视觉研究入门全指南
  6. 【python教程入门学习】五、Python中的列表(list)
  7. php内支持sqlite,PHP能不能和sqlite搭配
  8. java osgi web开发_在Tomcat中使用Java Web应用程序的OSGi软件包
  9. 超干货 | 2019秋招CV算法面经
  10. 热传导/物质扩散算法应用于推荐