Linux驱动开发入门(内核态用户态)

1.Linux设备驱动程序

是一个允许计算机软件与硬件交互的程序。这种程序建立了一个硬件与软件沟通的界面。CPU经由主板上的总线(Bus)或其他沟通子系统(Subsystem)与硬件形成连接,这样的连接使得硬件设备之间的数据交换成为可能。
驱动程序是提供硬件到操作系统的一个接口,并且协调二者之间的关系。

1.2Linux开发下的两种状态

  • 用户态和内核态:
    用户态处理上层的软件工作。
    内核态用来管理用户态的程序,完成用户态请求的工作。
  • Linux下的开发一般有两种:一是应用程序开发,二是内核驱动程序开发,这两种开发分别对应用户态和内核态两种Linux状态。当我们在用户态的应用程序空间打印一个“Hello”程序的时候,在调用printf("Hello");之前的所有代码都运行在用户态。
  • 当库函数printf()开始往lcd显示屏打印“Hello”的时候,会调用write()函数系统调用实现打印“Hello”。这个操作就是让该进程从用户态跳转到内核态来执行。此时Linux内核的代码会调用lcd驱动提供的接口函数,把"Hello"输出到lcd显示屏上面。完成这些工作以后,write()函数系统调用会返回,该进程也更跟从内核态返回到用户态
    请添加图片描述
  • 所以我们知道:进程从用户态到内核态一般是系统调用实现。系统调用返回时,进程从内核态返回到用户态。

为什么分内核态和用户态?
如果没有内核态和用户态之分,程序就可以随意读写硬件资源了,比如随意读写和分配内存,这样如果程序员一不小心将不适当的内容写到了不该写的地方,很可能就会导致系统崩溃。

而有了用户态和内核态的区分之后,程序在执行某个操作时会进行一系列的验证和检验之后,确认没问题之后才可以正常的操作资源,这样就不会担心一不小心就把系统搞坏的情况了,也就是有了内核态和用户态的区分之后可以让程序更加安全的运行,但同时两种形态的切换会导致一定的性能开销。

1.3Linux内核有如下功能职责

  • Linux内核功能:Linux系统种,每个进程都要向操作系统请求系统资源,如内存资源,CPU等资源,都是通过系统调用来实现的。Linux内核可以看着是一个大的可执行文件,专门处理所有的这些进程的请求。
  • 进程调度:处于就绪态的一堆进/线程里,按照一定的调度算法,选出一个进/线程并给它分配CPU时间让它运行,从而实现多进程/多线程的并发执行。调度程序执行一项调度策略,确保进程能公平地访问CPU,同时保证内核能按时执行必要的硬件操作。
  • 内存管理:是一种应用于计算机内存的资源管理形式。内存管理的基本要求是提供根据程序请求动态分配内存部分的方法,并在不再需要时将其释放以供重用。这对于任何在任何时候都可能正在进行多个进程的高级计算机系统至关重要。使用文件系统(swap)将未使用的内存换出到非易失性存储器(硬盘,emmc),然后在需要时交换回来。
  • 文件系统:Linux一切皆文件,几乎所有的设备都可以看成文件,底层文件系统涵盖了真实的文件系统还有虚拟文件系统,形成了一个文件系统框架。具体地说,文件系统负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件。
  • 设备管理:利用设备驱动框架,对硬件设备进行控制管理,并通过虚拟文件系统对用户空间程序提供统一的系统操作接口集。
  • 网络功能:Linux内核的网络架构主要由以下几部分构成:协议栈、驱动、协议和应用。协议栈是一套包含了多个协议层的协议,其中包括了物理层、数据链路层、IPv4/IPv6/ARP 层、传输层、会话层、表示层和应用层。驱动部分为不同的数据链路设备提供了相应的驱动,以便能够将数据从Linux内核发送出去或者将数据从外部传入到Linux内核中。而协议部分就是由不同的协议实例来实施具体的通信过程;应用部分则是通过相应的API来实施对协议实例的控制精通linux内核网络,从而实施具体的通信过程。
    图片.png

1.4Linux设备驱动分类

  • 根据Linux系统的设备特点,设备驱动程序分为三大类:字符设备驱动,块设备驱动,网络设备驱动。
  1. 字符设备驱动:这类设备指在进行数据读取时能一个字节一个字节以字节为单位读取数据的设备,叫做字符设备。比如LED、蜂鸣器、OLED、串口等。字符设备一般需要在驱动层实现open()、close()、read()、write()、ioctl()等函数。Linux系统种大部分的驱动程序都是字符设备驱动。

2.块设备驱动:块设备驱动是相对字符设备驱动定义的,因为块设备被操作时,都是以块(block)或者扇区(sector)为单位操作的(块是多个字节组成)。块设备多是存储设备,如硬盘、SD卡、U盘等。这类块设备在Linux下使用,一般需要进行分区,格式化(文件系统),挂载(mount)使用。Linux系统中,块设备读写时,每次只能传输一个或多个块。

  • 字符设备和块设备在/dev路径下都有一个设备节点文件对应

3.网络设备驱动:顾名思义针对网络设备设计的一种驱动,不管是无线网络还是有线网络,都是网络设备。使用ifconfig命令查看网络设备,如果要使用网络设备进行通信,则应该使用socket编程API实现。

  • 注意:有的设备属于多种设备驱动类型,比如随身WIFI设备(usb接口的),既能USB驱动也可以网卡驱动,所有既属于字符设备也属于网络设备。比如U盘,既能进行USB接口驱动属于字符设备,又能存储属于块设备。实际上,USB只是一种设备与CPU之间通信的一种通信协议,这样USB设备在Linux内核根据功能模拟实现不同的设备驱动(USB网卡模拟网络设备,U盘则模拟块设备)。

1.5内核开发注意事项(应用开发和内核开发的差异)

  • 内核及驱动程序开发时不能访问C库。因为C库是使用内核中的系统调用来实现的,而且是在用户空间实现的。所以编写Linux驱动时不能调用printf()函数,而是用printk()函数,可以理解为Linux内核里的printf()函数。
  • 内核及驱动程序开发时必须使用GNU C,因为Linux从一开始就使用GNU C。也可以使用别的编译工具,但需要对之前的代码进行大量修改。
  • 内核只有一个很小的定长堆栈。这样在驱动编程的过程中,不能像应用程序一样随意开辟一段大的内存空间。注意:内核动态分配内存使用完后记得释放内存。
  • 内核支持异步终端、抢占和SMP,故必须注意同步和并发。
  • 内核及驱动程序开发要考虑可移植性。因为在不同的平台,驱动程序可能不兼容。
  • Linux内核及驱动程序开发时不支持浮点数,因为浮点数很难使用,应该使用整形数。比如写温湿度传感器驱动时,往往不会直接返回一个浮点类型的数值。
  • 内核支持异步终端、抢占和SMP,故必须注意同步和并发。
  • Linux应用程序空间的每个进程都有受保护的4GB虚拟地址空间,这样我们在应用程序编程出现指针错误时,会导致系统报段错误(Segmentation Fault),并导致进程崩溃。然而在Linxu内核驱动编程中出现指针错误则会导致整个Linux系统死机Kernel Panic),所以Linux内核编程要十分谨慎小心。

1.6本人总结的学习Linux驱动程序开发的一些ideas:

  1. 确认你的环境:确保你正在使用一台运行Linux操作系统的计算机。对于驱动程序开发,最好是选择一个具备良好的硬件支持和最新内核版本的Linux发行版。

  2. 了解设备驱动程序的类型:在Linux中,驱动程序通常分为字符设备驱动和块设备驱动两种类型。字符设备驱动用于处理像终端、键盘等字符流的设备,而块设备驱动用于处理像硬盘、固态驱动器等块数据的设备。

  3. 学习Linux设备模型:Linux内核采用一种称为设备模型的框架来管理和表示设备。学习如何在设备模型中注册设备、分配和释放资源以及与设备进行交互是非常重要的。

  4. 掌握C语言和Linux内核编程:熟悉C语言编程和Linux内核编程是进行驱动程序开发的基础。了解C语言的基本语法、指针操作和内存管理等知识是必要的。

  5. 学习Linux驱动程序框架和API:Linux提供了一些用于驱动程序开发的框架和API。例如,platform_driverfile_operations等是常用的驱动程序框架和API。学习如何使用这些框架和API可以简化驱动程序的开发过程。

  6. 阅读相关文档和书籍:Linux内核官方文档提供了丰富的关于驱动程序开发的信息和指导。此外,还有一些经典的书籍,如《Linux设备驱动程序》(Linux Device Drivers),提供了深入的驱动程序开发指导和示例代码。

  7. 参与社区和讨论:加入Linux开发者社区,参与相关的讨论和交流,可以获得更多的帮助和指导。在邮件列表、论坛或IRC频道上与其他开发者分享问题和经验。

希望这个ideas和以上的知识对您有所帮助,并祝您在Linux驱动程序开发的学习过程中取得成功!

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林同学_ioT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值