Linux中内核与驱动程序

系列文章目录

第一章 Linux 中内核与驱动程序
第二章 Linux 设备驱动编写 (misc)
第三章 Linux 设备驱动编写及设备节点自动生成 (cdev)
第四章 Linux 平台总线platform与设备树
第五章 Linux 设备树中pinctrl与gpio(lichee nano pi)


文章目录

  • 系列文章目录
  • 前言
  • 一、Linux内核简述?
    • 1.内核开发与裸机开发的区别
    • 2.用户态和内核态
  • 二、Linux设备驱动程序
    • 1.具体思路
    • 2.小结
  • 总结


前言

Linux内核可以说是很神奇的一种东西(大家都这么说)抛开内核驱动程序就是耍流氓。下面我用一个问答来简单说一下:
:相信很多人和我一样,在刚学习或者接触驱动程序的时候会有点摸不到头脑。因为之前玩51单片机或者32单片机的时候根本就没接触过驱动程序,大都是有什么外设模块(比如,蜂鸣器、电机)直接用线连接GPIO口,通过控制GPIO口来驱动外设。那么,驱动程序到底它是什么呢?用在哪?为什么要用它?怎么用?
:驱动程序一般全称:设备驱动程序,一句话说就是要想使用硬件设备就要靠驱动程序驱动才可以。那么你可能疑惑,我直接用51或32单片机外接设备时没用驱动程序也可以使用啊?再答:51或者32等比较小的单片机(这里小不是指的尺寸,而是内存、处理器频率等达不到运行内核的标准),一般是没有内核的(主线Linux、rt-thread等内核),一般对其进行开发都称为裸机开发。一般小规模应用情况下使用裸机开发就可以达到期望效果,但是当项目复杂且时有操作系统/内核可以进行一些任务的调度,可以使得项目更好的达到要求。
以上问答给了我们一些概念,让我们对内核和驱动程序的关系有了最基本的了解。下面将详细介绍内核的一些知识,帮大家回忆起linux内核,而后再讲解驱动。


一、Linux内核简述?

首先声明一点内核不等于操作系统,内核是操作系统最基本、最核心的部分。操作系统一般包括内核、驱动程序、接口库、外围等组成部分。

1.内核开发与裸机开发的区别

如果只是单讲内核,学习内核的功能可能效果不好,可以将51、32单片机的裸机开发与其对比一下。

有内核开发 裸机开发
功能 进程管理、内存管理、文件管理、驱动管理 网络管理
开发模式 通过驱动程序+应用程序的模式操作硬件完成任务 烧入什么程序,只能跑这一个程序,直接通过烧入程序控制硬件
安全性 应用程序不直接操纵硬件更安全 应用程序直接访问硬件,不安全
开发难度 复杂 简单

上述有内核开发与裸机开发的区别也可以用以下的两张图片进行区别。如下图所示:有内核开发更加的复杂了。其中右边的图是裸机开发:应用可以直接去控制硬件(例如:你用51单片机去点灯,只需要去将对应引脚置0或者1就可以了)。左边的图是有内核开发而采用内核开发却需要应用程序调用API去在操作系统里对硬件进行操作。
Linux中内核与驱动程序_第1张图片
右图的开发模式很好去理解,故主要分析下有内核的开发模式。
这种模式下有了操作系统,你在想直接去通过置GPIO口1或者0去控制硬件,这让操作系统的脸往哪里搁呢?操作系统就是为了管理这一切。他将整个开发中分成了两个空间,一个是用户空间(上两层),一个是内核空间。下面详细介绍一下。

2.用户态和内核态

具体如下:
Linux中内核与驱动程序_第2张图片
内核态与用户态的几条公理:
1、用户态不能直接操作硬件
2、只有内核态才能对硬件进行操作管理
由这两条公理得出:用户要想操纵硬件必须要通过用户态去调用内核态,由内核去完成对硬件的操作。而内核怎么去操纵不同的硬件呢?就需要驱动程序了。这也就是驱动程序+应用程序的模式。这也就是嵌入式操作系统开发的最基本的原理和步骤。


二、Linux设备驱动程序

1.具体思路

再来看一遍上述问题:Q:内核怎么去操纵不同的硬件呢?
A:编写对应硬件的驱动程序,内核去操作驱动程序。当然内核是不会自个没事干去操纵硬件的,要先由用户态去调用内核。
以上是大概思路,但是具体实施起来还需要一些新概念。分成两个部分(请按顺序观看
1:驱动程序编写
设备号:在对某一个硬件设备编写驱动时,内核并不知道这个设备实际长什么样,一种情况是:它能控制的只是一个GPIO口(例如LED点灯),我们编写驱动程序就是对这个口进行操作,内核不用管硬件设备长啥样,你只要这个设备接在这个GPIO口就可以。驱动写好之后内核怎么知道这个驱动是那个设备呢?换个问题,板子上肯定不止一个驱动,那么怎么区分这些驱动呢?那就给这些驱动程序分配一个设备号,设备号也就代表了它的身份。
驱动编写好之后,加载进内核。通过下面命令可以查看已注册的设备号。

 cat /proc/devices

设备节点:上述也说了驱动要加载进内核,那么我们怎么用呢?怎么对硬件进行操作呢?Linux中一切皆文件,所以设备也是文件,但是到现在对设备的描述也就只有一个驱动,而我们要利用驱动对设备进行操作,那么对谁操作呢?设备在驱动写好编进内核之后,会在以下目录里产生设备节点,该设备节点代表了设备,或者叫设备文件。

 /dev

2:驱动程序调用
标准文件操作:对一般文件的操作我想都知道有open()、close()、write()、read()、ioctl()。这些都是标准文件操作,我们在应用层就可以使用,既然说了在应用层可以使用,那么肯定就不能直接对设备操作,因为硬件设备只有内核才有权限操作。但是我们想要在应用层对其进行操作任然需要用到标准文件操作,只不过需要下面的file_operation结构体。对了,这些标准文件操作其实就是API,或者说库。
file_operation结构体
直接上图;
Linux中内核与驱动程序_第3张图片
有这个图可以看出很多东西,应用层中通过标准接口函数通过file_operation结构体去调用驱动程序中的自定义的接口函数。由此就达到了:应用层调用内核,由内核去控制硬件。
当然之前一直没说咋写驱动,或者说驱动要写啥。这张图里面也可以看出,驱动就是写自定义的device_open()、device_close()、device_write()、device_read()、device_ioctl()函数这些名字随便起。

file_operations 结构体怎么链接 <标准接口函数> 与 <自定义函数> 代码如下:

static struct file_operations sha_dou_xing = {
	.owner   = THIS_MODULE,
	.open    = simple_open,
	.release = simple_release,
	.mmap    = simple_remap_mmap,
};

只需要这样一一对应就可以。very very very方便

2.小结

编写驱动好了之后,加载进内核会生成对应的设备号,该设备号对应了那个驱动。通过设备号可以生成对应的设备节点或称为设备文件,通过file_operations 结构体链接标准接口函数与自定义函数就可以实现在用户态打开设备节点,读写设备节点,间接操纵硬件设备的目的。


总结

讲解了设备驱动程序的一些概念,不免的说了些内核的知识,但不多,还是要看有些其他的文章和图书。
当然都是自己的见解,难免有错误的地方,各位有问题还请指出。

你可能感兴趣的:(Linux设备驱动,linux,单片机,运维)