2. Linux - 设备驱动 — 概念

一、概述

       u-boot的任务是启动内核,内核的任务是启动应用程序,应用程序会涉及很多文件和硬件操作,但不会直接操作硬件,由设备驱动来完成硬件的具体操作;比如读写文件,点灯、获取按键值。

Linux系统将设备分为3类:

  • 字符设备:

       指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后顺序。字符设备是面向流的设备,常见的字符设备有鼠标、键盘、串口、控制台和LED设备等。

  • 块设备:

       指可以从设备的任意位置读取一定长度数据的设备。块设备包括硬盘、磁盘、U盘和SD卡等。
【每一个字符设备或块设备都在/dev目录下对应一个设备文件。linux用户程序通过设备文件(或称设备节点)来使用驱动程序操作字符设备和块设备。】

  • 网络设备:

       网络设备可以是一个硬件设备,如网卡; 但也可以是一个纯粹的软件设备, 比如回环接口(lo).一个网络接口负责发送和接收数据报文。


设备分类

二、应用程序与设备、驱动之间的关系

以led操作为例,进行描述。
       应用程序中需要打开led灯,就需要open函数,在内核中的驱动程序中也有对应的led_open函数,这个led_open函数就是用来负责初始化led的引脚功能,应用程序中要调用read函数读取led灯的状态,内核中的驱动程序也有led_read函数。这是应用程序与内核中驱动程序一种最简单(不是唯一)的对应方式。

       那么应用程序中的open、read函数最终怎样调用到驱动程序中的led_open、led_read呢,中间有哪些东西?

  • 应用程序: 就是被调用的那些库函数,例如open、read、write... ...
  • C库(系统调用):其中的其实就是实现open、read这些函数来调用swi val 指令进入内核(函数不同val值都会不同)
  • 内核:内核根据swi后面不同的值去调用VFS中的system_open/system_read/ system_write等异常处理函数 找到相应的驱动程序(VFS:virtual file system 虚拟文件系统)
int main()
{
     int fd1  fd2;
     int   val=1;

     fd1 = open(“/dev/led”,O_RDWR);    //打开led
     write(fd1, &val, 4);

      fd2 = open(“hello.txt”,O_RDWR);  //打开文本
      write(fd2, &val, 4);
}

上面的应用程序主要实现点灯与打开文本文件,都是用的同样的函数。但是点灯与打开文本文件的行为显然不一样。那么谁来实现这些不一样的行为呢?

对于LED灯,有led_open驱动程序。对于文本文件存在于flash设备上,也有对于的驱动程序。system_open、system_read最终会根据打开的不同文件,找到底层的不同驱动程序,然后调用驱动程序中的硬件操作函数,比如led_open来实现对具体硬件设备的操作。
至于system_open又是如何找到led_open的,可参考:详解应用层open函数如何调用到底层驱动中xxx_open函数。

open 系统调用流程

你可能感兴趣的:(2. Linux - 设备驱动 — 概念)