Linux设备驱动开发详解【三】_Linux 内核及内核编程

本文简介

        由于 Linux 驱动编程本质属于 Linux 内核编程,因此有必要掌握 Linux 内核及内核编程的基础知识。
        3.1~3.2 节讲解 Linux 内核的演变及 Linux 2.6 内核的特点。
        3.3 节分析了 Linux 内核源代码目录结构和 Linux 内核的组成部分及其关系,并对 Linux 的用户空间和内核空间进行了讲解。
        3.4 节讲解了 Linux 2.6 内核的编译及内核引导过程。另外,还描述了在 Linux内核中新增程序的方法,驱动工程师编写的设备驱动也应该以此方式被添加。
        3.5 节讲解了 Linux 下 C 编程的命名习惯以及 Linux 所使用的 GNU C 针对标准C 的扩展语法。

 

 

3.1 Linux 内核的发展与演变

        Linux 操作系统诞生于 1991 年 10 月 5 日(第一次正式向外公布的时间)。 Linux 操作系统的诞生、发展和成长过程依赖于 UNIX 操作系统、 MINIX 操作系统、 GNU 计划、 POSIX 标准和 Internet。

1. UNIX 操作系统
        UNIX 操作系统是美国贝尔实验室的 Ken. Thompson和 Dennis Ritchie于 1969 年在 DEC PDP-7 小型计算机上开发的一个分时操作系统。 Linux 操作系统可看作 UNIX 操作系统的一个克隆版本。

2. Minix 操作系统
        Minix 操作系统也是 UNIX 操作系统的一种克隆系统,它于 1987 年由著名计算机教授 Andrew S.Tanenbaum 开发完成。开放源代码 Minix 操作系统的出现在全世界的大学中刮起了学习 UNIX 操作系统的旋风。 Linux 操作系统刚开始就是参照 Minix 操作系统开发进行。

3. GNU 计划
        GNU 计划和自由软件基金会(FSF)是由 Richard M. Stallman 于 1984 年创办的, GNU 是“GNU’s NotUNIX”的缩写。到 20 世纪 90 年代初, GNU 项目已经开发出许多高质量的免费软件,其中包括 Emacs 编辑系统、 Bash Shell 程序、 GCC 系列编译程序、 GDB 调试程序等。这些软件为 Linux 操作系统的开发创造了一个合适的环境,是 Linux 操作系统诞生的基础之一。没有 GNU 软件环境, Linux 操作系统将寸步难行。因此,严格而言, Linux 应该被称为 GNU/Linux 操作系统。

4. POSIX 标准
        POSIX(Portable Operating System Interface for Computing Systems,可移植的操作系统接口)是由 IEEE和 ISO/IEC 开发的一组标准。该标准基于现有的 UNIX 实践和经验完成, 描述了操作系统的调用服务接口,用于保证编制的应用程序可以在源代码一级上在多种操作系统上移植。该标准在推动 Linux 操作系统朝着正规化方向发展起着重要的作用,是 Linux 前进的灯塔。

5. Internet
        如果没有 Internet,没有遍布全世界的 Linux 爱好者的无私奉献,那么 Linux 操作系统就不可能发展到现在的水平。Linux 操作系统重要版本的变迁历史及各版本的主要特点如表 3.1 所示。


                     

                     

                                                                 表 3.1 Linux 操作系统版本历史
 

        从表 3.1 可以看出, Linux 操作系统一直朝着支持更多的 CPU、硬件体系结构和外部设备,支持更广泛领域的应用,提供更好的性能方向发展。
        除了 Linux 内核本身可提供免费下载以外,一些厂商封装了 Linux 内核和大量有用的软件包,制定了相应的Linux 发行版,如 Red Hat Linux、 TurboLinux、 Debian、 SuSe,国内的 RedFlag 和 Xteam 等。针对嵌入式系统的应用,一些改进内核的 Linux 操作系统被开发出来,如改进实时性的 Hard Hat Linux和 RTLinux,支持不含 MMU CPU 的 McLinux,面向数字相机和 MP3 等微型嵌入式设备的 ThinLinux,以及颇有商业背景的 MontaVista 等。

 

 

3.2 Linux 2.6 内核的特点

       尽管 Linux 2.4 目前仍然被广泛应用,但是本书是基于 Linux 2.6 内核的。从 2003 年 12 月 Linux 2.6.0发布至今,一直还处于开发之中,并还将稳定较长一段时间。 Linux 2.6 相对于 Linux 2.4 有相当大的改进,主要体现在如下几个方面。

1.新的调度器
        2.6 版本的 Linux 内核使用了新的进程调度算法,它在高负载的情况下执行得极其出色,并且当有很多处理器时也可以很好地扩展。

2.内核抢占
        在 2.6 版本的 Linux 内核中,内核任务可以被抢占,从而提高系统的实时性。这样做最主要的优势在于可以极大地增强系统的用户交互性。

3.改进的线程模型
        2.6 版本的 Linux 内核中线程操作速度得以提高,可以处理任意数目的线程, PID 最大可以到2000000000。

4.虚拟内存的变化
        从虚拟内存的角度来看,新内核融合了 r-map(反向映射)技术,显著改善虚拟内存在一定程度负载下的性能。

5.文件系统
        2.6 版本的 Linux 内核增加了对日志文件系统功能的支持,解决了 2.4 版本的 Linux 内核在这方面的不足。 2.6 版本的 Linux 内核在文件系统上的关键变化还包括对扩展属性及 POSIX 标准访问控制的支持。Ext2/Ext3 作为大多数 Linux 系统缺省安装的文件系统,在 2.6 版本的 Linux 内核中增加了对扩展属性的支持,可以给指定的文件在文件系统中嵌入元数据。

6.音频
        新的 Linux 音频体系结构 ALSA(Advanced Linux Sound Architecture)取代了缺陷很多的旧的 OSS(Open SoundSystem)。新的声音体系结构支持 USB 音频和 MIDI 设备,并支持全双工重放等功能。

7.总线
        SCSI/IDE 子系统经过大幅度的重写,解决和改善了以前的一些问题。比如 2.6 版本的 Linux 内核可以直接通过 IDE 驱动程序来支持 IDE CD/RW 设备,而不必像以前那样使用一个特别的 SCSI 模拟驱动程序。

8.电源管理
        支持 ACPI(高级电源配置管理界面, Advanced Configuration and Power Interface),用于调整 CPU 在不同的负载下工作于不同的时钟频率以降低功耗。

9.联网和 IPSec
        2.6 版本的 Linux 内核中加入了对 IPSec 的支持,删除了原来内核内置的 HTTP 服务器 kttpd,加入了对新的 NFSv4(网络文件系统)客户机/服务器的支持,并改进了对 IPv6 的支持。

10.用户界面层
        2.6 版本的 Linux 内核重写了帧缓冲/控制台层,人机界面层还加入了对大多数接口设备的支持(从触摸屏到盲人用的设备和各种各样的鼠标)。
        在设备驱动程序的方面, Linux 2.6 相对于 Linux 2.4 也有较大的改动,这主要表现在内核 API 中增加了不少新功能(例如内存池)、 sysfs 文件系统、内核模块从.o 变为.ko、驱动模块编译方式、模块使用计数、模块加载和卸载函数的定义等方面。

 

 

3.3 Linux 内核的组成

一、Linux 内核源代码目录结构

        本文范例程序所基于的 Linux 2.6.15.5 内核源代码压缩包“linux-2.6.15.5.tar.bz2”共 38.912KB,包含如下目录。
     arch:包含和硬件体系结构相关的代码,每种平台占一个相应的目录,如 i386、 ARM、 PowerPC、MIPS 等。
     block:块设备驱动程序 I/O 调度。
     crypto:常用加密和散列算法(如 AES、 SHA 等),还有一些压缩和 CRC 校验算法。
     Documentation:内核各部分的通用解释和注释。
     drivers:设备驱动程序,每个不同的驱动占用一个子目录,如 char、 block、 net、 mtd、 i2c 等。
     fs:支持的各种文件系统,如 EXT、 FAT、 NTFS、 JFFS2 等。
     include:头文件,与系统相关的头文件被放置在 include/linux 子目录下。
     init:内核初始化代码。
     ipc:进程间通信的代码。
     kernel:内核的最核心部分,包括进程调度、定时器等,而和平台相关的一部分代码放在 arch/*/kernel目录下。
     lib:库文件代码。
     mm:内存管理代码,和平台相关的一部分代码放在 arch/*/mm 目录下。
     net:网络相关代码,实现了各种常见的网络协议。
     scripts:包含用于配置内核的脚本文件。
     security:主要包含 SELinux 模块。
     sound: ALSA、 OSS 音频设备的驱动核心代码和常用设备驱动。
     usr:实现了用于打包和压缩的 cpio 等。
 

二、Linux 内核的组成部分

        如图 3.1 所示, Linux 内核主要由进程调度(SCHED)、内存管理(MM)、虚拟文件系统(VFS)、网络接口(NET)和进程间通信(IPC)等 5 个子系统组成。

 

                                                      

                                                                      图3.1  Linux内核的组成部分与关系

 

1.进程调度

        进程调度控制系统中的多个进程对 CPU 的访问,使得多个进程能在 CPU 中微观串行,宏观并行地执行。进程调度处于系统的中心位置,内核中其他的 子 系 统 都依赖它,因为每个子系统都需要挂起或恢复进程。
        如图 3.2 所示,Linux 的进程在几个状态间进行切换。在设备驱动编程中,当请求的资源不能得到满足时,驱动一般会调度其他进程执行,并使驱动对应的进程进入睡眠状态,直到它请求的资源被释放,才会被唤醒而进入就绪状态。睡眠分为可被打断的睡眠和不可被打断的睡眠,两者的区别在于可被打断的睡眠在收到信号的时候会醒来。 

 

                               

                                                                            图 3.2 Linux 进程状态转换

 

        在设备驱动编程中,当请求的资源不能得到满足时,驱动一般会调度其他进程执行,其对应的进程进入睡眠状态,直到它请求的资源被释放,才会被唤醒而进入就绪状态。
        设备驱动中,如果需要几个并发执行的任务,可以启动内核线程,启动内核线程的函数为:int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);

2.内存管理

        内存管理的主要作用是控制多个进程安全地共享主内存区域。当 CPU 提供内存管理单元(MMU)时, Linux 内存管理完成为每个进程进行虚拟内存到物理内存的转换。Linux 2.6 引入了对无 MMU CPU 的支持。 
        如图 3.3 所示,一般而言, Linux 的每个进程享有 4GB 的内存空间, 0~3GB 属于用户空间, 3~4GB 属于内核空间,内核空间对常规内存、 I/O 设备内存以及高端内存存在不同的处理方式。

 

                                                     

                                                                           图 3.3 Linux 进程地址空间

3.虚拟文件系统

        如图 3.4 所示, Linux 虚拟文件系统(VFS)隐藏了各种硬件的具体细节,为所有的设备提供了统一的接口。而且,它独立于各个具体的文件系统,是对各种文件系统的一个抽象,它使用超级块 super block 存放文件系统相关信息,使用索引节点 inode 存放文件的物理信息,使用目录项 dentry 存放文件的逻辑信息。


                                                   

                                                                       图 3.4 Linux 文件系统

 

4.网络接口

        网络接口提供了对各种网络的标准的存取和各种网络硬件的支持。网络接口可分为网络协议和网络驱动程序,网络协议部分负责实现每一种可能的网络传输协议,网络设备驱动程序负责与硬件设备进行通信,每一种可能的硬件设备都有相应的设备驱动程序。

5.进程通信

        Linux 支持进程间的多种通信机制,包含信号量、共享内存、管道等,这些机制可协助多个进程、多资源的互斥访问、进程间的同步和消息传递。

        Linux 内核的5个组成部分之间的依赖关系如下。
    进程调度与内存管理之间的关系:这两个子系统互相依赖。在多道程序环境下,必须为程序创建进程,而创建进程的第一件事情就是将程序和数据装入内存。
    进程间通信与内存管理的关系:进程间通信子系统要依赖内存管理支持共享内存通信机制,这种机制允许两个进程除了拥有自己的私有空间,还可以存取共同的内存区域。
    虚拟文件系统与网络接口之间的关系:虚拟文件系统利用网络接口支持网络文件系统(NFS),也利用内存管理支持 RAMDISK 设备。
        内存管理与虚拟文件系统之间的关系:内存管理利用虚拟文件系统支持交换,交换进程(swapd)定期由调度程序调度,这也是内存管理依赖于进程调度的惟一原因。当一个进程存取的内存映射被换出时,内存管理向文件系统发出请求,同时,挂起当前正在运行的进程。
        除了这些依赖关系外,内核中的所有子系统还要依赖于一些共同的资源。这些资源包括所有子系统都用到的例程,如分配和释放内存空间的函数、打印警告或错误信息的函数及系统提供的调试例程等。


                                 

                                                                       图 3.5 Linux 网络体系结构

 

三、Linux 内核空间与用户空间

        现代 CPU 内部往往实现了不同的操作模式(级别)。例如, ARM 处理器有以下 7 种工作模式。
    用户模式(usr):大多数的应用程序运行在用户模式下,当处理器运行在用户模式下时,某些被保护的系统资源是不能被访问的。
    快速中断模式(fiq):用于高速数据传输或通道处理。
    外部中断模式(irq):用于通用的中断处理。
    管理模式(svc):操作系统使用的保护模式。
    数据访问终止模式ÿ

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值