Linux内核目录结构

来自华清远见研发中心
FarSight讨论 | 贡献2020年7月27日 (一) 15:58的版本

跳转至: 导航搜索

Linux内核是Linux操作系统的核心,也是整个Linux功能体现。它是用C语言编写,符合POSIX标准。Linux最早是由芬兰黑客Linus Torvalds为尝试在英特尔X86架构上提供自由免费的类Unix操作系统而开发的。该计划开始于1991年,这里有一份Linus Torvalds当时在Usenet新闻组comp.os.minix所登载的帖子,这份著名的帖子标志着Linux计划的正式开始。在计划的早期有一些Minix黑客提供了协助,而今天全球无数程序员正在为该计划无偿提供帮助。

今天Linux是一个一体化内核(Monolithic Kernel)系统。设备驱动程序可以完全访问硬件。Linux内的设备驱动程序可以方便地以模块化(Modularize)的形式设置,并在系统运行期间可直接装载或卸载。

Linux内核主要功能包括:进程管理、内存管理、文件管理、设备管理、网络管理等。

进程管理:进程是在计算机系统中资源分配的最小单元。内核负责创建和销毁进程, 而且由调度程序采取合适的调度策略,实现进程之间的合理且实时的处理器资源的共享。从而内核的进程管理活动实现了多个进程在一个或多个处理器之上的抽象。内核还负责实现不同进程之间、进程和其他部件之间的通信。

内存管理:内存是计算机系统中最主要的资源。内核使得多个进程安全而合理地共享内存资源,为每个进程在有限的物理资源上建立一个虚拟地址空间。内存管理部分代码可以分为硬件无关部分和硬件有关部分:硬件无关部分实现进程和内存之间的地址映射等功能;硬件有关部分实现不同体系结构上的内存管理相关功能并为内存管理提供硬件无关的虚拟接口。

文件管理:在Linux系统中的任何一个概念几乎都可以看作一个文件。内核在非结构化的硬件之上建立了一个结构化的虚拟文件系统,隐藏了各种硬件的具体细节。从而在整个系统的几乎所有机制中使用文件的抽象。Linux在不同物理介质或虚拟结构上支持数十种文件系统。例如, Linux支持磁盘的标准文件系统ext3和虚拟的特殊文件系统。

设备管理:Linux系统中几乎每个系统操作最终都映射到一个或多个物理设备上。 除了处理器, 内存等少数的硬件资源之外, 任何一种设备控制操作都由设备特定的驱动代码来进行。内核中必须提供系统中可能要操作的每一种外设的驱动。

网络管理:内核支持各种网络标准协议和网络设备。网络管理部分可分为网络协议栈和网络设备驱动程序。网络协议栈负责实现每种可能的网络传输协议(TCP/IP协议等);网络设备驱动程序负责与各种网络硬件设备或虚拟设备进行通讯。

Linux内核源代码非常庞大,随着版本的发展不断增加。它使用目录树结构,并且使用Makefile组织配置编译。

初次接触Linux内核,最好仔细阅读顶层目录的readme文件,它是Linux内核的概述和编译命令说明。readme的说明更加针对X86等通用的平台,对于某些特殊的体系结构,可能有些特殊的地方。

顶层目录的Makefile是整个内核配置编译的核心文件,负责组织目录树中子目录的编译管理,还可以设置体系结构和版本号等。

内核源码很复杂,包含多级目录,形成一个庞大的树状结构,通常称为Linux源码目录树。本章节以linux 4.19.94为例来介绍一下linux内核目录结构。

首先来看第一级目录

47-1.png

目录 内容
arch 包含各体系结构特定的代码,如 arm、x86、ia64、mips等,在每个体系结构目录下通常都有:

(1) /boot:内核需要的 特定平台代码。
(2) /kernel:体系结构特有的代码。
(3) /lib:通用函数在特定体系结构的实现。
(4) /math-emu:模拟FPU的代码。
(5) /mm:特定体系结构的内存管理实现。
(6) /include:特定体系的头文件 。

block 存放块设备相关代码
crypto 存放加密、压缩、CRC校验等算法相关代码
Documentation 存放相关说明文档,很多实用文档,包括驱动编写等
drivers 存放 Linux 内核设备驱动程序源码。

驱动源码在 Linux 内核源码中站了很大比例,常见外设几乎都有可参考源码,对驱动开发而言,该目录非常重要。
该目录包含众多驱动,目录按照 设备类别 进行分类,如char、block、input、i2c、spi、pci、usb等。

firmware 存放处理器相关的一些特殊固件
fs 存放所有文件系统代码,如fat、ext2、ext3、ext4、ubifs、nfs、sysfs等。
include 存放内核所需、与平台无关的头文件,与平台相关的头文件已经被移动到arch平台的include目录,如 ARM 的头文件目录<arch/arm/include/asm/>
init 包含内核初始化代码
ipc 存放进程间通信代码
kernel 包含Linux内核管理代码
lib 库文件代码实现
mm 存放内存管理代码
net 存放网络相关代码
samples 存放提供的一些内核编程范例,如kfifo;

相关用户态编程范例,如hidraw。

scripts 存放一些脚本文件,如menuconfig脚本
security 存放系统安全性相关代码
sound 存放声音、声卡相关驱动
tools 编译过程中一些主机必要工具
usr cpio相关实现
virt 内核虚拟机KVM

Linux内核源码中接近一半的代码量是驱动,对某一个特定主板的系统而言,驱动也占据很大的比例,底层开发的很大一部分是驱动相关工作。掌握从众多驱动中找到正确的驱动源码文件,并根据产品的实际需求进行修改调整的方法,能有效促进产品开发的进度。

Linux内核源码树drivers目录很复杂,包含了各种外设的驱动。对嵌入式Linux开发而言,通常需要关注如下目录。

目录 说明
drivers/gpio 系统GPIO子系统 和 驱动目录,包括处理器内部GPIO以及外扩GPIO驱动。遵循GPIO子系统的驱动,可通过/sys/class/gpio进行访问
drivers/hwmon 硬件监测相关驱动,如温度传感器、风扇监测等
drivers/i2c I2C子系统驱动。各I2C控制器的驱动在i2c/busses目录下
drivers/input 输入子系统驱动目录
drivers/input/keyboard 非HID键盘驱动,如GPIO键盘、矩阵键盘等
drivers/input/touchscreen 触摸屏驱动,如处理器的触摸屏控制器驱动、外扩串行触摸屏控制器驱动、串口触摸屏控制器驱动等
drivers/leds LED子系统和驱动,如GPIO驱动的LED。遵循 LED子系统的驱动 ,可通过/sys/class/leds进行访问
drivers/mfd 多功能器件(Multi-Function Device)驱动。如果一个器件能做多种用途,通常需要借助MFD来完成。
drivers/misc 杂项(Miscellaneous)驱动。所驱动的设备可通过/sys系统访问
drivers/mmc SD(Secure Digital)/MMC(Mutimedia Card)卡驱动目录
drivers/mtd MTD(Memory Technology Device)子系统和驱动,包括NAND、oneNAND等。
drivers/mtd/nand NAND FALSH的MTD驱动目录,包括NAND的基础驱动和控制器接口驱动
drivers/net 网络设备驱动,包括MAC、PHY、CAN、USB 网卡、无线、PPP协议等
drivers/net/can CAN设备驱动。

Linux已经将CAN归类到网络中,采用socket_CAN接口

drivers/net/ethernet 所支持的MAC驱动。

常见厂家的MAC驱动都能找到,如broadcom、davicom、marvell、micrel、smsc等厂家的MAC,处理器自带MAC的驱动也在该目录下

drivers/net/phy PHY驱动,比如marvell、micrel和smsc的一些PHY驱动
drivers/rtc RTC子系统和RTC芯片驱动
drivers/spi SPI子系统和SPI控制器驱动,含GPIO 模拟SPI的驱动
drivers/tty TTY 驱动
drivers/tty/serial 串口驱动,包括8250串口以及各处理器内部串口驱动实现
drivers/uio 用户空间IO驱动
drivers/usb USB驱动,包括USB HOST、Gadget、USB转串口以及OTG等支持。
drivers/video Video驱动,包括Framebuffer驱动、显示控制器驱动和背光驱动等。
drivers/video/backlight 背光控制驱动
drivers/video/logo Linux内核启动LOGO图片目录
drivers/watchdog 看门狗驱动,包括软件看门狗和各种硬件看门狗驱动实现