MAINTAINERS----维护者名单。
CREDITS----Linux主要的贡献者名单。
REPORTING-BUGS----Bug上报的手册。
Documentation,README----帮助、说明文档。
Linux内核体系结构评析简述
图1Linux层次结构
最前面是用户(或应用程序)空间。这是用户应用程序执行的地方。用户空间之下是内核空间,Linux内核正是坐落这儿。GNUCLibrary(glibc)也在这儿。它提供了联接内核的系统调用插口,还提供了在用户空间应用程序和内核之间进行转换的机制。这点十分重要,由于内核和用户空间的应用程序使用的是不同的保护地址空间。每位用户空间的进程都使用自己的虚拟地址空间,而内核则占用单独的地址空间。
Linux内核可以进一步界定成3层。最前面是系统调用插口深入linux内核架构,它实现了一些基本的功能,比如read和write。系统调用插口之下是内核代码,可以更精确地定义为独立于体系结构的内核代码。这种代码是Linux所支持的所有处理器体系结构所通用的。在这种代码之下是依赖于体系结构的代码,构成了一般称为BSP(BoardSupportPackage)的部份。这种代码用作给定体系结构的处理器和特定于平台的代码。
Linux内核实现了好多重要的体系结构属性。在或高或低的层次上,内核被界定为多个子系统。Linux也可以看作是一个整体,由于它会将所有那些基本服务都集成到内核中。这与微内核的体系结构不同,前者会提供一些基本的服务,比如通讯、I/O、内存和进程管理,更具体的服务都是插入到微内核层中的。每种内核都有自己的优点,不过这儿并不对此进行讨论。
随着时间的流逝,Linux内核在显存和CPU使用方面具有较高的效率,而且十分稳定。并且对于Linux来说,最为有趣的是在这些大小和复杂性的前提下,仍然具有良好的可移植性。Linux编译后可在大量处理器和具有不同体系结构约束和需求的平台上运行。一个反例是Linux可以在一个具有显存管理单元(MMU)的处理器上运行,也可以在这些不提供MMU的处理器上运行。
Linux内核的uClinux移植提供了对非MMU的支持。
图2Linux内核体系结构
Linux内核的主要组件有:系统调用插口、进程管理、内存管理、虚拟文件系统、网络堆栈、设备驱动程序、硬件构架的相关代码。
(1)系统调用插口
SCI层提供了个别机制执行从用户空间到内核的函数调用。正如上面讨论的一样,这个插口依赖于体系结构,甚至在相同的处理器家族内也是这么。SCI实际上是一个十分有用的函数调用多路复用和多路分解服务。在./linux/kernel中您可以找到SCI的实现,并在./linux/arch中找到依赖于体系结构的部份。
(2)进程管理
进程管理的重点是进程的执行。在内核中,这种进程称为线程,代表了单独的处理器虚拟化(线程代码、数据、堆栈和CPU寄存器)。在用户空间,一般使用进程这个术语,不过Linux实现并没有分辨这两个概念(进程和线程)。内核通过SCI提供了一个应用程序编程插口(API)来创建一个新进程(fork、exec或PortableOperatingSystemInterface[POSIX]函数),停止进程(kill、exit),并在它们之间进行通讯和同步(signal或则POSIX机制)。
进程管理还包括处理活动进程之间共享CPU的需求。内核实现了一种新型的调度算法,不管有多少个线程在竞争CPU,这些算法都可以在固定时间内进行操作。这些算法就称为O(1)调度程序linux运维博客,这个名子就表示它调度多个线程所使用的时间和调度一个线程所使用的时间是相同的。O(1)调度程序也可以支持多处理器(称为对称多处理器或SMP)。您可以在./linux/kernel中找到进程管理的源代码,在./linux/arch中可以找到依赖于体系结构的源代码。
(3)显存管理
内核所管理的另外一个重要资源是显存。为了提升效率,若果由硬件管理虚拟显存,显存是根据所谓的显存页形式进行管理的(对于大部份体系结构来说都是4KB)。Linux包括了管理可用显存的方法,以及数学和虚拟映射所使用的硬件机制。不过显存管理要管理的可不止4KB缓冲区。Linux提供了对4KB缓冲区的具象,比如slab分配器。这些显存管理模式使用4KB缓冲区为基数linux deepin,之后从中分配结构,并跟踪显存页使用情况,例如什么显存页是满的,什么页面没有完全使用,什么页面为空。这样就容许该模式依据系统须要来动态调整显存使用。为了支持多个用户使用显存,有时会出现可用显存被消耗光的情况。因为这个缘由,页面可以移出显存并放入c盘中。这个过程称为交换,由于页面会被从显存交换到硬碟上。显存管理的源代码可以在./linux/mm中找到。
(4)虚拟文件系统
虚拟文件系统(VFS)是Linux内核中十分有用的一个方面,由于它为文件系统提供了一个通用的插口具象。VFS在SCI和内核所支持的文件系统之间提供了一个交换层(请看图)。
在VFS里面,是对例如open、close、read和write之类的函数的一个通用API具象。在VFS下边是文件系统具象,它定义了下层函数的实现方法。它们是给定文件系统(超过50个)的插件。文件系统的源代码可以在./linux/fs中找到。文件系统层之下是缓冲区缓存,它为文件系统层提供了一个通用函数集(与具体文件系统无关)。这个缓存层通过将数据保留一段时间(或则随后预先读取数据便于在须要是就可用)优化了对化学设备的访问。缓冲区缓存之下是设备驱动程序,它实现了特定化学设备的插口。
(5)网路堆栈
网路堆栈在设计上依循模拟合同本身的分层体系结构。回想一下,InternetProtocol(IP)是传输合同(一般称为传输控制合同或TCP)下边的核心网路层合同。TCP里面是socket层,它是通过SCI进行调用的。socket层是网路子系统的标准API,它为各类网路合同提供了一个用户插口。从原始帧访问到IP合同数据单元(PDU),再到TCP和UserDatagramProtocol(UDP),socket层提供了一种标准化的方式来管理联接,并在各个终点之间联通数据。内核中网路源代码可以在./linux/net中找到。
(6)设备驱动程序
Linux内核中有大量代码都在设备驱动程序中,它们就能运转特定的硬件设备。Linux源码树提供了一个驱动程序子目录,这个目录又进一步界定为各类支持设备,比如Bluetooth、I2C、serial等。设备驱动程序的代码可以在./linux/drivers中找到。
(7)依赖体系结构的代码
虽然Linux很大程度上独立于所运行的体系结构,并且有些元素则必须考虑体系结构能够正常操作并实现更高效率。./linux/arch子目录定义了内核源代码中依赖于体系结构的部份,其中包含了各类特定于体系结构的子目录(共同组成了BSP)。对于一个典型的桌面系统来说,使用的是x86目录。每位体系结构子目录都包含了好多其他子目录,每位子目录都关注内核中的一个特定方面,比如引导、内核、内存管理等。这种依赖体系结构的代码可以在./linux/arch中找到。
假如Linux内核的可移植性和效率还不够好,Linux还提供了其他一些特点,它们难以界定到里面的分类中。作为一个生产操作系统和开源软件,Linux是测试新合同及其提高的良好平台。Linux支持大量网路合同,包括典型的TCP/IP,以及高速网路的扩充(小于1GigabitEthernet[GbE]和10GbE)。Linux也可以支持例如流控制传输合同(SCTP)之类的合同,它提供了好多比TCP更中级的特点(是传输层合同的接替者)。
Linux还是一个动态内核,支持动态添加或删掉软件组件。被称为动态可加载内核模块,它们可以在引导时按照须要(当前特定设备须要这个模块)或在任何时侯由用户插入。
Linux最新的一个提高是可以用作其他操作系统的操作系统(称为系统管理程序)。近来,对内核进行了更改,称为基于内核的虚拟机(KVM)。这个更改为用户空间启用了一个新的插口,它可以容许其他操作系统在启用了KVM的内核之上运行。不仅运行Linux的其他实例之外,MicrosoftWindows也可以进行虚拟化。唯一的限制是底层处理器必须支持新的虚拟化指令。
Linux体系结构和内核结构区别
1.当被问到Linux体系结构(就是Linux系统是如何构成的)时,我们可以参照右图如此回答:从大的方面讲,Linux体系结构可以分为两块:
(1)用户空间:用户空间中又包含了,用户的应用程序,C库
(2)内核空间:内核空间包括,系统调用,内核,以及与平台构架相关的代码
2.Linux体系结构要分成用户空间和内核空间的缘由:
1)现代CPU一般都实现了不同的工作模式,
以ARM为例:ARM实现了7种工作模式,不同模式下CPU可以执行的指令或则访问的寄存器不同:
(1)用户模式usr
(2)系统模式sys
(3)管理模式svc
(4)快速中断fiq
(5)外部中断irq
(6)数据访问中止abt
(7)未定义指令异常
以(2)X86为例:X86实现了4个不同级别的权限,Ring0—Ring3;Ring0下可以执行特权指令,可以访问IO设备;Ring3则有好多的限制
2)所以,Linux从CPU的角度出发,为了保护内核的安全,把系统分成了2部份;
3.用户空间和内核空间是程序执行的两种不同状态深入linux内核架构,我们可以通过“系统调用”和“硬件中断“来完成用户空间到内核空间的转移
4.Linux的内核结构(注意分辨LInux体系结构和Linux内核结构)
Linux驱动的platform机制
Linux的这些platformdriver机制和传统的device_driver机制相比,一个非常显著的优势在于platform机制将本身的资源注册进内核,由内核统一管理,在驱动程序中使用这种资源时通过platform_device提供的标准插口进行申请并使用。这样提升了驱动和资源管理的独立性,但是拥有较好的可移植性和安全性。下边是SPI驱动层次示意图,Linux中的SPI总线可理解为SPI控制器引出的总线:
和传统的驱动一样,platform机制也分为三个步骤:
1、总线注册阶段:
内核启动初始化时的main.c文件中的kernel_init()→do_basic_setup()→driver_init()→platform_bus_init()→bus_register(&platform_bus_type),注册了一条platform总线(虚拟总线,platform_bus)。
2、添加设备阶段:
设备注册的时侯Platform_device_register()→platform_device_add()→(pdev→dev.bus=&platform_bus_type)→device_add(),就这样把设备给挂到虚拟的总线上。
3、驱动注册阶段:
Platform_driver_register()→driver_register()→bus_add_driver()→driver_attach()→bus_for_each_dev(),对在每位挂在虚拟的platformbus的设备作__driver_attach()→driver_probe_device(),判定drv→bus→match()是否执行成功,此时通过表针执行platform_match→strncmp(pdev→name,drv→name,BUS_ID_SIZE),倘若相符就调用really_probe(实际就是执行相应设备的platform_driver→probe(platform_device)。)开始真正的侦测,假如probe成功,则绑定设备到该驱动。
从里面可以看出,platform机制最后还是调用了bus_register(),device_add(),driver_register()这三个关键的函数。
下边看几个结构体:
struct platform_device
(/include/linux/Platform_device.h)
{
const char * name;
int id;
struct device dev;
u32 num_resources;
struct resource * resource;
};
Platform_device结构体描述了一个platform结构的设备,在其中包含了通常设备的结构体structdevicedev;设备的资源结构体structresource*resource;还有设备的名子constchar*name。(注意,这个名子一定要和前面platform_driver.driveràname相同,缘由会在前面说明。)
该结构体中最重要的就是resource结构,这也是之所以引入platform机制的缘由。
struct resource
( /include/linux/ioport.h)
{
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
struct resource *parent, *sibling, *child;
};
其中 flags位表示该资源的类型,start和end分别表示该资源的起始地址和结束地址(/include/linux/Platform_device.h):
struct platform_driver
{
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*suspend_late)(struct platform_device *, pm_message_t state);
int (*resume_early)(struct platform_device *);
int (*resume)(struct platform_device *);
struct device_driver driver;
};
Platform_driver结构体描述了一个platform结构的驱动。其中不仅一些函数表针外,还有一个通常驱动的device_driver结构。
名子要一致的缘由:
里面说的驱动在注册的时侯会调用函数bus_for_each_dev(),对在每位挂在虚拟的platformbus的设备作__driver_attach()→driver_probe_device(),在此函数中会对dev和drv做初步的匹配,调用的是drv->bus->match所指向的函数。platform_driver_register函数中drv->driver.bus=&platform_bus_type,所以drv->bus->match就为platform_bus_type→match,为platform_match函数,该函数如下:
static int platform_match(struct device * dev, struct device_driver * drv)
{
struct platform_device *pdev = container_of(dev, struct platform_device, dev);
return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
}
是比较dev和drv的name,相同则会步入really_probe()函数,因而步入自己写的probe函数做进一步的匹配。所以dev→name和driver→drv→name在初始化时一定要填一样的。
不同类型的驱动,其match函数是不一样的,这个platform的驱动,比较的是dev和drv的名子,还记得usb类驱动里的match吗?它比较的是ProductID和VendorID。
个人总结Platform机制的益处:
1、提供platform_bus_type类型的总线,把这些不是总线型的soc设备都添加到这条虚拟总线上。促使,总线——设备——驱动的模式可以得到普及。
2、提供platform_device和platform_driver类型的数据结构,将传统的device和driver数据结构嵌入其中,但是加入resource成员,以易于和OpenFirmware这些动态传递设备资源的新型bootloader和kernel接轨。
Linux内核体系结构
由于Linux内核是单片的,所以它比其他类型的内核占用空间最大,复杂度也最高。这是一个设计特点,在Linux初期造成了相当多的争辩,但是依然带有一些与单内核固有的相同的设计缺陷。
为了解决这种缺陷,Linux内核开发人员所做的一件事就是使内核模块可以在运行时加载和卸载,这意味着您可以动态地添加或删掉内核的特点。这除了可以向内核添加硬件功能,还可以包括运行服务器进程的模块,例如低级别虚拟化,但也可以替换整个内核,而不须要在个别情况下重启计算机。
想像一下,假若您可以升级到Windows服务包,而不须要重新启动……
内核模块
假如Windows早已安装了所有可用的驱动程序,而您只须要打开所需的驱动程序怎样办?这本质上就是内核模块为Linux所做的。内核模块,亦称为可加载内核模块(LKM),对于保持内核在不消耗所有可用显存的情况下与所有硬件一起工作是必不可少的。
模块一般向基本内核添加设备、文件系统和系统调用等功能。lkm的文件扩充名是.ko,一般储存在/lib/modules目录中。因为模块的特点,您可以通过在启动时使用menuconfig将模块设置为load或d,或则通过编辑/boot/config文件,或则使用modprobe动态地加载和卸载模块,轻松订制内核。
第三方和封闭源码模块在一些发行版中是可用的,例如Ubuntu,默认情况下可能难以安装,由于这种模块的源代码是不可用的。该软件的开发人员(即nVidia、ATI等)不提供源代码,而是建立自己的模块并编译所需的.ko文件便于分发。其实这种模块像beer一样是免费的,但它们不像speech那样是免费的,因而不包括在一些发行版中,由于维护人员觉得它通过提供非免费软件“污染”了内核。
内核并不神奇,但对于任何正常运行的计算机来说,它都是必不可少的。Linux内核不同于OSX和Windows,由于它包含内核级别的驱动程序,并使许多东西“开箱即用”。希望您能对软件和硬件怎么协同工作以及启动计算机所需的文件有更多的了解。
原文链接://blog.csdn.net/darnell888/article/details/106970752?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163791847416780357291017%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163791847416780357291017&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-16-106970752.first_rank_v2_pc_rank_v29&utm_term=linux%E5%86%85%E6%A0%B8%E7%BD%91%E7%BB%9C%E5%9F%BA%E7%A1%80%E6%9E%B6%E6%9E%84&spm=1018.2226.3001.4187
本文原创地址://gulass.cn/lnhtxjgjxjxt.html编辑:刘遄,审核员:暂无