0
点赞
收藏
分享

微信扫一扫

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型


目录

​​前言:​​

​​第1章 嵌入式系统概述​​

​​1.1 什么是嵌入式系统​​

​​1.2 嵌入式系统的架构​​

​​第2章 内核驱动程序架构 ​​

​​2.1 什么驱动程序​​

​​2.2 驱动程序的作用​​

​​2.3 Linux下的内核硬件设备驱动程序​​

​​第3章 Linux驱动工程师学习路径​​

​​3.1 成长之路与必备的知识​​

​​3.2 C语言基础​​

​​3.3 自底向上的构建Linux系统​​

​​3.4 字符设备的层次结构​​

​​3.5 网络驱动的层次结构​​

​​第4章 内核模块的动态加载​​

​​4.1 什么是内核模块​​

​​4.2 内核模块的动态加载与静态编译比较​​

​​4.3 内核模块的源代码示例​​

​​4.4 Linux内核模块程序结构​​

​​4.5 Makefile与内核模块的编译​​

​​5.6 内核模块的shell操作命令​​

​​第5章 一切皆文件,Linux虚拟文件系统与统一设备模型​​

​​5.1 什么是文件​​

​​5.2 文件的组织方式:树型结构与Linux虚拟文件系统​​

​​5.3 硬件设备的树型组织方式:设备树​​

​​5.4 设备也是文件​​

​​5.4 虚拟文件系统的用户空间接口​​

​​5.5 虚拟文件系统的内核程序​​

​​5.6 虚拟文件系统与Dev文件系统​​

​​5.7 虚拟文件系统与SYSFS/PROC​​

前言:

在实际嵌入式系统中,大多数时候并不需要修改和编写Linux操作系统的代码,而是需要为自己的嵌入式硬件系统编写Linux的设备驱动程序。这是因为,实际的不同应用的嵌入式系统,其硬件设备是不同的,Linux自带的设备驱动程序往往无法满足自身系统的需要。因此,会花几篇文章重点介绍一下Linux下的设备驱动程序。

第1章 嵌入式系统概述

1.1 什么是嵌入式系统

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_Linux

1.2 嵌入式系统的架构

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_驱动程序_02

第2章 内核驱动程序架构 

2.1 什么驱动程序

驱动程序一般指的是​​设备驱动程序​​​(Device Driver),是一种可以使​​计算机​​​和​​设备​​​进行相互通信的​​特殊程序​​​。相当于​​硬件​​​的接口,​​操作系统​​只有通过设备驱动程序这个接口,才能控制硬件设备的工作,假如某设备的驱动程序未能正确安装,便不能正常工作。

因此,驱动程序被比作“ 硬件的灵魂”、“硬件的主宰”、“硬件和系统之间的桥梁”等。

内存也是一种特殊的硬件设备,内存的驱动程序是Linux操作系统自带的,不需要设备厂家额外编写硬件驱动程序。内存的驱动程序包括:uboot、Linux对内存控制器的初始化、Linux内部的内存管理单元MMU。

应用程序只需要通过内存地址就可以直接访问普通的RAM内存。

对于FLASH内存,可以直接通过地址进行“读”访问,但必须要通过特定的驱动程序才能进行"写"访问。

2.2 驱动程序的作用

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_内核模块_03

 

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_linux_04

没有操作系统的单片机就是采用的上述架构。

 

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_驱动程序_05

Linux环境下,采用的就是上述架构。

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_Linux_06

2.3 Linux下的内核硬件设备驱动程序

(1)Linux设备驱动程序与Linux内核模块

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_Linux_07

 (2)Linux设备驱动程序在内核中的位置

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_内核模块_08

 (3)Linux设备驱动程序的特点

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_驱动程序_09

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_linux_10

第3章 Linux驱动工程师学习路径

3.1 成长之路与必备的知识

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_OS_11

(1)嵌入式系统的组成

(2)硬件基础

  • 必须熟悉硬件电路的基本组成与原理
  • 熟悉SOC芯片的架构与工作原理
  • 熟悉特定硬件设备的硬件接口协议
  • 熟悉芯片手册

(3)内核编程与编程语言

  • Linux系统内核架构
  • Linux启动流程
  • 汇编语言基础
  • C语言基础
  • 数据结构基础

(4)Linux设备模型与设备树

(5)Linux驱动程序模型

(6)Linux驱动的主要思想

3.2 C语言基础

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_OS_12

 

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_内核模块_13

3.3 自底向上的构建Linux系统

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_Linux_14

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_内核模块_15

(1)自底向上构建驱动程序,为应用程序提供访问特定硬件设备的服务。

(2)设备驱动程序的根基是硬件

(3)设备驱动程序运行在内核空间,以两种方式存在:

  • 可以动态插入和去除的内核模块
  • 与Linux内核的基础代码编译在一起

3.4 字符设备的层次结构

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_驱动程序_16

字符设备是Linux内核驱动中,种类最多的一种硬件设备。

3.5 网络驱动的层次结构

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_OS_17

第4章 内核模块的动态加载

Linux的大部分的驱动程序是以内核模块的方式存在的。

4.1 什么是内核模块

Linux内核的整体架构本就非常庞大,其包含的组件也非常多,而我们怎样把需要的部分都包含在内核中呢?

如果把需要的所有功能都编译到Linux内核中。这会导致两个问题,一是生成的内核会很大,二是如果我们要在现有的内核中新增或删除功能,将不得不重新编译内核。

有没有另一种机制可使得编译出的内核本身并不需要包含所有功能,而这些功能需要被使用的时候,其对应的代码被动态地加载到内核中呢?

Linux提供了这样的机制,这种机制被称为模块(module)。

模块具有这样的特点:

  • 模块本身不被编译人内核映像,从而控制了内核的大小。
  • 模块一旦被加载,它就和内核中的其他部分完全一样。

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_Linux_18

4.2 内核模块的动态加载与静态编译比较

 

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_内核模块_19

4.3 内核模块的源代码示例

(1)案例1

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_linux_20

(2)案例2

/*
* a simple kernel module: hello world
*
* Copyright (C) 2022 liefyuan (liefyuan@qq.com)
*
* Licensed under GPL v2 or later
*/
#include <linux/init.h>
#include <linux/module.h>

static int __init hello_init(void)
{
printk(KERN_INFO "Hello World enter\n");
return 0;
}

module_init(hello_init);

static void __exit hello_exit(void)
{
printk(KERN_INRO "Hello World exit\n");
}
module_exit(hello_exit);

MODULE_AUTHOR("Lief Yuan <liefyuan@qq.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("A simple Hello World Module");
MODULE_ALIAS("a simplest module");

4.4 Linux内核模块程序结构

一个Linux内核模块主要由如下几个部分组成:

(1)模块加载函数:module_init
当通过insmod或modprobe命令加载内核模块时,模块的加载函数会自动被内核执行,完成本模块的相关初始化工作。

(2)模块卸载函数:module_exit
当通过rmmod命令卸载某模块时,模块的卸载函数会自动被内核执行,完成与模块加载函数相关的功能。

(3)模块许可证声明:MODULE_LICENSE
许可证(LICENSE)声明描述内核模块的许可权限,如果不声明LICENSE,模块被加载时,将收到内核被污染(Kernel Tainted)的警告。

(4)模块参数(可选):module_param
模块参数是模块被加载的时候可以传递给它的值,它本身对应模块内部的全局变量。

(5)模块导出符号(可选):export symbol
内核模块可以导出的符号(symbol,对应于函数或变量),若导出,其他模块则可以使用本模块中的变量或函数。

(6)模块作者等信息声明(可选):MODULE_DESCRIPTION

4.5 Makefile与内核模块的编译

(1)案例1

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_内核模块_21

(2)案例2

KERNEL_DIR := "....."
CURRENT_PATH := $(shell pwd)
obj-m := led.o

build: kernel_modules

kernel_modules:
$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules

clean:
$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

  • 第1行,指定内核源码文件目录,使用绝对路径
  • 第2行,CURRENT_PATH 表示当前路径,直接通过运行“pwd”命令来获取当前所处路径
  • 第3行,obj-m 表示将 led.c 这个文件编译为 led.ko 模块
  • 第8行,具体的编译命令,后面的 modules 表示编译模块,-C 表示将当前的工作目录切换到指定目录中,也就是 KERNERLDIR 目录。M 表示模块源码目录,“make modules”命令
  • 中加入 M=dir 以后程序会自动到指定的 dir 目录中读取模块的源码并将其编译为.ko 文件。

>> make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16

5.6 内核模块的shell操作命令

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_linux_22

Linux的模块,以两种方式进入内核:

  • 静态编译、连接
  • 动态编译、动态插入

(1)查看当前加载的全部模块

>> lsmod

(2)检测模块是否加载

>>  ismod

(3)加载新模块

>>  insmod

(4)尝试性加载模块

>> modprobe

modprobe和insmod类似,都是用来动态加载驱动模块的,区别在于modprobe可以解决load module的依赖关系,它是通过 /lib/modules/`uname -r`/modules.dep和modules.deo.bb文件来查找依赖关系的;而insmod不能解决依赖关系。

(5)显示模块信息

>> modinfo

(6)卸载模块

>>  rmmod

第5章 一切皆文件,Linux虚拟文件系统与统一设备模型

5.1 什么是文件

狭义的文件是指:存储计算机硬盘设备上的信息的组织方式,狭义的文件可以是​​文本文档​​​、​​图片​​​、​​程序​​等等。

广义的文件是指:存储计算机系统上的信息的组织方式,包括存储在硬盘设备上的信息,存储设备在内存中的信息,甚至可以是存在所有硬件设备中的信息。

Linux中文件,最初是狭义的文件内涵,后来扩展成了广义的文件内涵。

因此,在Linux中,有一句话是这样的:“一切皆文件:everything is file”。

5.2 文件的组织方式:树型结构与Linux虚拟文件系统

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_OS_23

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_OS_24

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_驱动程序_25

5.3 硬件设备的树型组织方式:设备树

一个复杂的嵌入式系统,会支持大量的硬件设备,是按照偏平的方式管理所有的硬件设备,还是分层的方式组织和管理硬件设备呢?

在Linux系统中,采用的是后者,即分层的方式组织硬件设备,在Linux系统中,称为设备树。

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_驱动程序_26

5.4 设备也是文件

在Linux中,硬件系统总的总线、总线上的设备,也是以文件的方式来组织和呈现的。

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_Linux_27

 (1)mnt:被映射成硬盘驱动器硬件设备

(2)dev:被映射成文件的硬件设备

(3)sys:被映射成文件的系统信息

(4)proc:被映射成文件的内核信息

(5)temp:内存中的临时性文件,掉电消失

(6)var:经常变化的各种多用户共享文件

(7)bin、sbin:相对稳定不变的系统文件

5.5 虚拟文件系统的用户空间接口

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_Linux_28

5.6 虚拟文件系统的内核程序

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_OS_29

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_linux_30

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_Linux_31

5.7 虚拟文件系统与Dev文件系统

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_内核模块_32

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_linux_33

DevFS文件系统是挂接在虚拟文件系统之下的。

5.8 虚拟文件系统与SYSFS/PROC

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_Linux_34

SYSFS/PROC文件系统是挂接在虚拟文件系统之下的。 

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_linux_35

[架构之路-35]:目标系统 - 系统软件 - Linux OS内核模块与内核设备驱动程序,一切皆文件,Linux虚拟文件系统与统一设备模型_linux_36

举报

相关推荐

理解 Linux 虚拟文件系统

0 条评论