Linux 驱动开发究竟在开发什么?

文章目录

  • [1 Linux 驱动开发架构图](#1 Linux 驱动开发架构图)

  • [2 更具体的例子:LED 驱动程序](#2 更具体的例子:LED 驱动程序)

    • [2.1 硬件层(Hardware Layer)](#2.1 硬件层(Hardware Layer))
    • [2.2 固件层(Firmware Layer)](#2.2 固件层(Firmware Layer))
    • [2.3 驱动程序层(Driver Layer)](#2.3 驱动程序层(Driver Layer))
    • [2.4 操作系统内核(Kernel Layer)](#2.4 操作系统内核(Kernel Layer))
    • [2.5 系统调用层(System Call Layer)](#2.5 系统调用层(System Call Layer))
    • [2.6 C 库(C Library)](#2.6 C 库(C Library))
    • [2.7 用户空间(User Space)](#2.7 用户空间(User Space))
  • [3 具体过程](#3 具体过程)

  • [4 从理解 `open()` 函数的层次到理解所有的架构层次](#4 从理解 open() 函数的层次到理解所有的架构层次)

    • [4.1 应用程序中的 `open()` 函数](#4.1 应用程序中的 open() 函数)
    • [4.2 C 库中的 `open()` 函数](#4.2 C 库中的 open() 函数)
    • [4.3 `open()` 系统调用](#4.3 open() 系统调用)
    • [4.4 驱动的 `open()` 函数](#4.4 驱动的 open() 函数)
  • [5 总结](#5 总结)

  • 参考链接

  • 封面

  • 本文将全面探讨 Linux 驱动开发在系统架构中的位置,包括应用程序、C 库、系统调用和内核之间的关系。

  • Linux 驱动开发着眼于硬件和操作系统内核之间的驱动程序层,当然,内核配置与编译、引导加载程序开发、根文件系统构建等内容也是必不可少的。

1 Linux 驱动开发架构图

在 Linux 系统中,驱动开发涉及多个层级的交互,以下是各层级的结构图示:
用户空间
应用程序和系统服务 C 库
标准库函数如 open, read, write 系统调用层
与内核交互的接口 操作系统内核
管理资源和硬件接口 驱动程序层
内核模块 .ko 文件 固件层
设备初始化和控制 硬件层
物理设备

2 更具体的例子:LED 驱动程序

以 LED 驱动程序为例,以下是各层级的具体作用:

2.1 硬件层(Hardware Layer)

  • 组成:物理 LED 灯。
  • 功能:发光和熄灭。
  • 例子:LED 硬件连接到计算机的 GPIO(通用输入输出)引脚。

2.2 固件层(Firmware Layer)

  • 组成:LED 控制芯片固件。
  • 功能:管理 LED 的基本操作。
  • 例子:初始化 LED 硬件并准备接收控制信号。

2.3 驱动程序层(Driver Layer)

  • 组成 :LED 驱动模块(如 led_driver.ko)。
  • 功能
    • 硬件抽象:将 LED 的物理信号转换为标准输入/输出操作。
    • 设备控制:处理 LED 的初始化和开/关控制。
    • 文件操作 :实现 openclosereadwrite 等函数。
  • 例子 :LED 驱动程序响应来自用户空间的 write 操作,控制 LED 的开关状态。

2.4 操作系统内核(Kernel Layer)

  • 组成:Linux 内核代码。
  • 功能:管理系统资源,提供对硬件的低级访问。
  • 例子:内核通过调用 LED 驱动程序中的函数来处理对 LED 的控制操作。

2.5 系统调用层(System Call Layer)

  • 组成 :如 open()read()write() 系统调用。
  • 功能:提供应用程序与内核交互的接口。
  • 例子 :当应用程序调用 write() 系统调用时,系统调用层将请求传递给内核。

2.6 C 库(C Library)

  • 组成:如 glibc 提供的标准库函数。
  • 功能:实现对系统调用的包装,使其易于使用。
  • 例子open()close()read()write() 函数在 C 库中实现,最终调用系统调用。

2.7 用户空间(User Space)

  • 组成:运行在操作系统上的应用程序,例如控制 LED 的程序。
  • 功能:通过文件操作与设备驱动交互。
  • 例子 :控制 LED 的应用程序通过 open("/dev/led") 打开设备文件,通过 write() 控制 LED 的开关状态。

3 具体过程

  1. LED 驱动开发 :编写 LED 驱动代码 led_driver.c,实现 LED 初始化、开/关控制和文件操作函数。
  2. 编译驱动模块 :将 led_driver.c 编译为内核模块 led_driver.ko
  3. 加载模块 :使用 insmod led_driver.ko 加载驱动模块到内核中。
  4. 创建设备文件 :在 /dev 目录下创建 led 设备文件。
  5. 用户程序交互 :应用程序使用 open("/dev/led") 打开设备文件,通过 write() 控制 LED 的开关状态。
  6. 库函数调用 :应用程序调用 C 库中的标准函数,如 openwrite,这些函数通过系统调用与内核交互。
  7. 系统调用:C 库函数调用相应的系统调用,系统调用层将请求传递给内核。
  8. 驱动响应:LED 驱动处理来自系统调用的请求,控制 LED 的硬件操作。

4 从理解 open() 函数的层次到理解所有的架构层次

4.1 应用程序中的 open() 函数

  • 功能:用于在应用程序中打开一个文件或者设备。
  • 示例代码
c 复制代码
int fd = open("/dev/led", O_WRONLY);

4.2 C 库中的 open() 函数

  • 功能:包装系统调用,提供一个易用的接口给用户空间程序。
  • 伪代码
c 复制代码
int open(const char *pathname, int flags) {
    return syscall(SYS_open, pathname, flags);
}

4.3 open() 系统调用

  • 功能:提供用户空间程序与内核交互的接口。
  • 伪代码
c 复制代码
int sys_open(const char *filename, int flags) {
    // 内核代码,处理打开文件的逻辑
    ...
    return file_descriptor;
}

4.4 驱动的 open() 函数

  • 功能:实现设备特定的打开操作逻辑。
  • 示例代码
c 复制代码
static int led_open(struct inode *inode, struct file *file) {
    // 设备特定的打开操作,如初始化硬件
    ...
    return 0; // 成功
}

5 总结

  • 通过本文的各个部分,可以清晰地看到 Linux 驱动开发在系统架构中的重要性。应用程序、C 库、系统调用和驱动程序之间的协作,使得用户能够方便地控制硬件设备,实现各种功能。
  • Linux 驱动开发着眼于硬件和操作系统内核之间的驱动程序层,当然,内核配置与编译、引导加载程序开发、根文件系统构建等内容也是必不可少的。

参考链接

封面

由 DALL-E-3 生成

相关推荐
花姐夫Jun8 分钟前
在 CentOS 8 系统上安装 Jenkins 的全过程
linux·centos·jenkins
是店小二呀24 分钟前
【Linux】Linux开发利器:make与Makefile自动化构建详解
linux·运维·自动化
BUG 4041 小时前
LINUX--shell
linux·运维·服务器
菜鸟小白:长岛icetea1 小时前
Linux零基础速成篇一(理论+实操)
linux·运维·服务器
深海的鲸同学 luvi1 小时前
【HarmonyOS NEXT】hdc环境变量配置
linux·windows·harmonyos
dowhileprogramming2 小时前
Python 中的迭代器
linux·数据库·python
过过过呀Glik2 小时前
在 Ubuntu 服务器上添加和删除用户
linux·服务器·ubuntu
Tesseract_95274 小时前
ioctl回顾
linux
Java小白中的菜鸟4 小时前
centos7的磁盘扩容
linux·运维·服务器
黑子哥呢?6 小时前
Linux---防火墙端口设置(firewalld)
linux·服务器·网络