由于Linux驱动编程的本质属于Linux内核编程,因此我们非常有必要熟悉Linux内核以及Linux内核的特点。 这篇文章将会帮助读者打下Linux驱动编程的基础知识。

本篇文章分为如下三个小节进行讲解:

1、Linux内核的组成(进程调度、内存管理、虚拟文件系统、网络接口和进程间通信);

2、Linux的用户空间和内核空间;

3、Linux内核的引导过程。

1、Linux内核的组成

1.1、Linux内核源代码的目录结构

读者朋友千万不要觉得了解目录结构对我们进行Linux开发没什么帮助,实际上目录体现了Linux的整体架构和思想,对于我们理解Linux是大有裨益的。Linux内核源代码包含如下目录:

  • arch:包含和硬件体系结构相关的代码,每种平台占一个相应的目录,如:ARM、PowerPC、MIPS等,在arch目录下,存放了各个不同的平台芯片对Linux内核进程调度、内存管理和中断等的支持;
  • block:块设备驱动程序调度(块设备不是我们学习的重点,前期学习中可忽略);
  • crypto:常用加密算法、一些压缩算法和CRC校验算法;
  • documentation:内核各部分的注释;
  • drivers:设备驱动程序,每个不同的驱动占用一个子目录,如char、net、i2c、spi等(重点来了,划重点了:高工资,设备驱动程序就是我们学习的重点而开发过单片机程序的读者对驱动程序应该有更深刻的理解);
  • fs:所支持的各种文件系统,如EXT、FAT、NTFS等;
  • include:头文件,与系统相关的头文件放在include/linux的目录下;
  • init:内核初始化代码;
  • ipc:进程间通信的代码;
  • kernel:内核最核心的部分,包括进程调度和定时器等;
  • lib:库文件代码;
  • mm:内存管理代码:
  • net:网络相关代码,实现常见的网络协议;
  • scripts:用于配置内核的文件;
  • security:主要是一个SELinux模块;
  • sound:音频设备的驱动核心代码;
  • usr:实现用于打包和压缩等。

Linux的目录结构

1.2、进程调度

进程调度控制系统中的多个进程对CPU的访问,使得多个进程能够在CPU中“宏观并行、微观串行”地执行。进程调度处于系统的中心位置,内核其他的功能都依赖于它,因为每个子系统都需要挂起或者恢复进程。Linux进程会在几个状态之间进行切换,在设备驱动编程中,当请求的资源不能得到满足时,驱动一般或调度其他进程执行并使本进程进入睡眠状态,直到它请求的资源被释放,才会被系统唤醒从而进入就绪状态等待调度。绝大多数的进程是由我们的应用程序创建的,当它们存在硬件访问的需求时,会通过系统调用进入内核空间(文章的后面会讲到用户空间和内核空间的区别)。

1.3、内存管理

内存管理的主要作用是控制多个进程安全的共享内存区域。当CPU提供内存管理单元MMU时,Linux内存管理对于每个进程完成从虚拟内存到物理内存的转换。现在常用的处理器都是32位的,那么每个进程也就享有4GB(2的32次方)的内存空间,0~3GB属于用户空间,3~4GB属于内核空间。当然,这个界限是可以调整的,但是我们一般使用这个默认配置即可。

1.4、虚拟文件系统

Linux虚拟文件系统隐藏了各种硬件的具体细节,为所有设备提供了统一的接口。而且,虚拟文件系统独立于各个具体的文件系统,是对各种文件系统的一个抽象。它为上层的应用程序提供了统一的vfs_read()、vfs_write()等接口,然后它在调用具体的底层文件系统或者设备驱动中实现的file_operations结构体的成员函数(这个结构体将是我们后面学习Linux设备驱动的关键数据结构)。

1.5、网络接口

网络接口提供了对各种网络标准的存取和网络硬件的支持。在Linux中网络接口可分为网络协议和网络驱动程序,网络协议负责实现每一种可能的网络传输协议,网络设备驱动程序负责与硬件设备通信。Linux内核支持的协议栈很多,例如:Internet、NFC、Bluetooth等,在上层的应用程序中统一使用接口。看到这里,我想你也大概明白了吧,都是套路,我们需要学会这些调用API的套路。

1.6、进程间通信

Linux支持进程间的多种通信机制,包含信号量、共享内存、消息队列、管道等,这些机制可以协调多个进程、多个资源的互斥访问,进程间的同步和消息传递。这一部分也是我们后续学习的重点。

2、Linux内核的用户空间和内核空间

在Linux中分为用户空间和内核空间,我们开发时写的程序就是运行在用户空间,那我在这一节为什么又要说驱动的编程实质上就是内核的编程呢?这是因为我们完成驱动程序的开发之后,它是被编译进内核的,那它也就属于内核空间。在这种情况下,上层的程序是不能直接访问底层功能的,这就意味着应用程序是被禁止直接访问硬件和内存的,在应用程序中操作硬件的时候,其实发生了这样一个转换的过程:应用程序(用户空间)--->系统调用(文件系统)--->内核空间(驱动程序)。这样做有很多优点,最重要的一点是保证了系统的安全运行。

内核空间和用户空间这两个名词还用来区别程序执行的两种不同状态,也就是用户态和内核态,他们使用的是不同的地址空间。看到这里的读者还记不记得他们分别使用的地址空间呢?上文已经说过了哦。

用户和内核使用的地址空间

3、Linux内核的引导过程

SoC上电时,CPU0会先引导bootloader,而其他的CPU则判断自己是不是CPU0,进入等待状态等待CPU0来唤醒它。CPU0引导bootloader,bootloader引导Linux内核,在内核启动阶段,CPU0会发中断唤醒CPU1,之后CPU0和CPU1都投入运行。CPU0导致了用户空间的init初始化程序被调用,init程序再派生出其他进程,然后这些进程再派生出其他的进程 (看到这里你有没有想起单片机开发时的启动文件stm32f10x_startup.s,正因为有它帮我们把代码运行的环境都准备好了,所以我们才直接从main函数进入)

Linux系统的启动流程(大概看一下)

关于内核启动,与我们关系比较大的部分是每个平台的设备回调函数和属性信息,这些回调函数会在内核启动过程中被调用,后续的文章会进一步介绍。

相信读者已经对Linux的内核有了一个初步的了解,当然这只是初步的而已,更多更难的还在后面等着你呢!我们一步一步来,循序渐进的学习才能达到最好的效果。下一篇文章将介绍在Linux中 C语言编程的特点。

我会定期更新嵌入式Linux开发和STM32开发的编程知识和经验总结。欢迎关注,也欢迎在评论区留言,我们共同交流。

linux内核_Linux驱动编程的本质就是Linux内核编程相关推荐

  1. linux下u盘网卡驱动,通过u盘给linux安装网卡驱动的做法——深圳培训linux

    简单方便使用,随手可得. 简洁快速,只需一个u盘即可为linux系统安装网卡驱动. 简便快捷的方法都是受大众喜欢的,这样可以快速的简单的解决问题. 通过u盘给linux系统安装网卡驱动的方法,这是一个 ...

  2. Linux网卡驱动适配各个内核,网卡驱动8 MII接口以及linux内核对MII的支持

    首先,向大家推荐一些文章. http://blog.chinaunix.net/uid-24148050-id-131084.html http://hi.baidu.com/lds102/item/ ...

  3. linux内核时钟驱动,4.9版本的linux内核中实时时钟芯片pcf85263的驱动源码在哪里

    SQL添加维护 计划失败 在sql要求数据库每天自动备份这个是大家都会遇到的问题,我遇到了这个问题如图: 是因为这个服务组件没有安装 CSS Hack汇总快查(CSS兼容代码演示) 文章出处和来源网址 ...

  4. linux平台设备驱动模型是什么意思,Linux设备驱动模型之我理解

    点击(此处)折叠或打开 /* my_bus.c   */ #include #include #include #include #include #include "my_bus.h&qu ...

  5. linux电容触摸屏驱动参数,基于FT5x06嵌入式Linux电容触摸屏驱动

    **************************************************************************************************** ...

  6. linux系统无线驱动在哪下载,在linux上怎么安装无线网卡驱动?

    在linux上怎么安装无线网卡驱动? 在linux上安装无线网卡驱动的方法: (1)先确定无线网卡型号,因驱动安装和型号是密切相关的,不同的型号,安装和下载驱动有所不同,但原理是一样的.图例为无线网卡 ...

  7. linux关机_LINUX快速入门第二章:Linux 系统启动过程

    linux启动时我们会看到许多启动信息. Linux系统的启动过程并不是大家想象中的那么复杂,其过程可以分为5个阶段: 内核的引导. 运行 init. 系统初始化. 建立终端 . 用户登录系统. 内核 ...

  8. linux iio 设备驱动,FS4412开发板使用Linux IIO驱动框架实现ADC驱动

    1.概述 FS4412开发板有一个4通道(0/1/2).10/12比特精度的 ADC ,其中: 1)ADCIN0: 在核心板中引出 2)ADCIN1: 在核心板中引出 3)ADCIN2: 在核心板中引 ...

  9. linux ati显卡驱动下载,教你在Linux中安装ATI显卡驱动(图)

    beforlinux 于 2011-01-04 17:18:36发表: 这个06年的帖子,不过正在为这个问题困扰呢 hlinuxer 于 2011-01-02 23:10:47发表: 学习了,打打预防 ...

最新文章

  1. 关于C语言中的malloc和free函数的用法
  2. 面试官:RabbitMQ本身不支持延迟队列,那你给我实现一个?
  3. pthread中如何追踪stack over flow
  4. const与#define的异同
  5. asp.net中的参数传递:Context.Handler 的用法
  6. python需要的基础_推荐收藏!小白不要怕!一周学全Python面试基础(2)
  7. ElasticSearch 5.5.3 Docker化部署
  8. python 注销一大段_Django框架用户注销功能实现方法分析
  9. (c语言)输入两个整数a和n,计算下面表达式的值。Sn=a+aa+aaa+aaaa+.....+aa..aa(n个a)
  10. Python的单链表实现
  11. ajax返回值demo
  12. 数据结构-栈操作-用链表实现栈基本操作
  13. 第二十五章 合作博弈论【相关策略与相关均衡】
  14. oracle直接生成xlsx,【玩转Excel】Oracle PLSQL处理生成XLSX文件
  15. android模拟鼠标键盘,有关通过Happy Android模拟器的鼠标和键盘操作进行手机游戏的详细设置的图形教程...
  16. 3G、3GPP、LTE、4G解释
  17. Google 安装印象笔记剪藏插件
  18. 代码静态检测——QAC
  19. 数字万用表短路时电阻不为0怎么办
  20. 黑马程序员_计算机编码技术

热门文章

  1. 使ALV控件中的内容可编辑
  2. 大数据独角兽TOP10榜单发布,“内永洪,外Tableau”领跑BI领域
  3. 平安智慧城市:与时代同行,坚定数字化之路
  4. 服务器ghost到虚拟机,无需U盘用Ghost还原vmware内虚拟机系统的方法
  5. 硬件安全(一) 概述
  6. 零基础学Python:自定义序列类的详细教程
  7. python 去除字符串两端字符串
  8. python:array和list转换以及数组切片
  9. Python中如何查看模块的源码内容
  10. php 通知客户端,PHP+SSE服务器向客户端推送消息