Linux驱动

字符设备驱动模型

Linux驱动_第1张图片
在字符设备中使用struct cdev这种结构来描述设备。
Linux驱动_第2张图片
应用程序:读写文件,点灯;获取按键。用一些接口调用驱动程序去实现一些引用。

open这些函数,是C库实现的。从而进入内核,C库怎么进入内核?本质上,这些函数对应的汇编指令会引发一个异常,类似于中断一样,发生了就会进入相应的异常处理函数(进入到了内核空间)。根据发生异常的原因,调用不同的处理函数,比如sys_open,sys_read函数等 (内核的接口处就是系统调用的接口)。

最简单的莫过于led:
Linux驱动_第3张图片
中间就依赖于驱动程序框架。

过程:

  1. 应用程序是有设备号的。应用程序会经过C库进入内核,内核最后会去调用驱动。
  2. 具体怎么通过内核找到驱动中的具体实现,就是框架中实现的。
  3. 在chrdev这个数组中找到file_operation这个 结构。这个结构是从驱动程序实现的。(驱动程序中就实现了这些led_open ,led_read ,led_write函数,以及file_operation结构体,这个结构体就有.open,指向我们写的led_open。)
  4. 然后入口函数这边,用register_chrdev函数,将结构体放到主设备号中。
    Linux驱动_第4张图片
    file_operations 的结构体,此结构体就是 Linux 内核驱动操作函数集合。

驱动运行的方式有两种,其中有一种就是将驱动编译为模块,启动内核的时候,就使用命令加载驱动模块。这里就涉及到两个函数:

module_init(xxx_init); //注册模块加载函数  入口函数
module_exit(xxx_exit); //注册模块卸载函数 出口函数

字符设备注册和注销:

static inline int register_chrdev(unsigned int major, const char *name,const struct file_operations *fops)
static inline void unregister_chrdev(unsigned int major, const char *name)

一般字符设备的注册在入口函数中进行,字符设备的注销在出口函数中进行。

现在,我们可以看到已经定义了file_operations结构体,这个结构体就是设备的具体操作函数。现在就需要对用到的函数尽心初始化。比如open /realease/read/write。

附上面试题:

  1. TCP和UDP的区别?
  2. I2C驱动的框架
  3. 双链表怎么删除节点
  4. 编译的条件
  5. makefile的作用?gcc的作用?
  6. 代码生成可执行程序的过程?
  7. 中断切换的过程?
  8. 中断前的进程上下文保存在栈里,保存在哪个栈?
  9. 为什么有MMU,MMU有什么作用?
  10. 用过哪些系统调用,切换到内核态的接口API?
  11. 编译过程
  12. 链接分为哪些种类(动,静,装载时链接)
  13. 栈的大小由什么决定
  14. 栈的增长方式socket三种类型
  15. 内核中如何查找优先级
  16. MMU的简单介绍,具体实现
  17. new和malloc的区别
  18. 内核分配内存的方法
  19. 智能指针的底层实现
  20. 如何避免内存泄漏
  21. I2C和SPI 的区别
  22. 线程池和进程池的区别
  23. 同步与竞争
  24. 自旋锁和互旋锁的区别
  25. 数据结构中队列和栈的区别
  26. SD与EMMC。(汇川)
  27. PWM设置的流程
  28. SPI是全双吗?怎么判断
  29. CPU主频是多少
  30. 面向对象和面向过程的区别
  31. RTOS的实时性是如何保的
  32. CAN通信了解吗
  33. 内核管理硬件的方式
  34. 对缓存的理解
  35. SPI通信过程
  36. 对中断的理解。优先级反转用抢占不会乱掉吗
  37. ARM有多少个寄存器
  38. 字符设备有哪些?和块设备的区别

你可能感兴趣的:(嵌入式八股面试,linux,运维,服务器)