深入Linux内核架构笔记(第1章 )

本文深入探讨了操作系统内核的关键组成部分及其工作原理,包括进程管理、内存管理、设备驱动程序、网络支持、文件系统等核心功能。同时介绍了内核实现策略如微内核与宏内核的区别,以及内核如何通过系统调用来与用户空间交互。
摘要由CSDN通过智能技术生成

1.1 内核的任务
*在纯技术层面上,内核是硬件与软件之间的一个中间层。其作用是将应用程序的请求传递给硬件,并充当底层驱动程序。对系统中的各种设备和组建进行寻址。
*当若干程序在同一系统中并发运行时,也可以将内核是为资源管理程序。
*另一种研究内核的视角是将内核设为库,其提供了一组面向系统的命令。

1.2 实现策略
当前,在操作系统实现方面,有以下两种主要的范型。
(1)微内核:这种范型中,只有最基本的功能直接由中央内核实现
(2)宏内核:与微内核相反,宏内核是构建系统内核的传统方法。在这种方法中,内核的全部代码,包括所有子系统(如内存管理、文件系统、设备驱动程序)都打包到一个文件中。模块特性依赖于内核与用户曾之间设计精巧的通信方法,这使得模块的热插拔和动态装载得以实现。

1.3 内核的组成部分
1.3.1 进程 、进程切换、调度
传统上,UNIX操作系统下运行的应用程序,服务器及其他程序都成为进程。每个进程都在CPU的虚拟内存中分配地址空间。各个进程的地址空间是完全独立的,因此进程并不会意识到彼此的存在。从进程的角度来看,他会认为自己是系统中唯一的进程。如果进程想要彼此通信,那么必须使用特定的内核机制。
(1)内核借助于CPU的帮助,负责进程切换的技术细节。
(2)内核还必须确定如何在现存进程之间共享CPU时间。重要进程得到的CPU时间多一点,次要进程得到的少一点。确定哪个进程运行多长时间的过程称为调度。
2 内存映射
内存映射是一种虫咬的抽象手段。映射方法可以讲仁义来源的数据传输到进程的虚拟地址空间。文件的内容可以映射到内存中。处理之许读取响应的内存及可访问文件内容,或向内存写入数据来修改文件的内容。内核讲保证任何修改都会自动同步到文件中。
内核在实现设备驱动是直接使用了内存映射。外设的输入/输出可以映射到虚拟地址空间的区域中。对相关内存区域的读写绘有系统重定向到设备,因而大大简化了驱动程序的实现。

================================================
1.3.5 物理内存的分配
在内核分配内存时,必须记录页帧的已分配或空闲状态,以免两个进程使用同样的内存区域中。由于内存分配和释放非常频繁,内核还必须保证相关操作尽快完成。内核可以治分配完整的页帧。将内存划分为更少的部分的工作,则委托给用户空间中的我标准库。标准库讲来源于内核的页帧查分为小的区域,病为进程分配内存。
1 伙伴系统
系统中的空闲内存块总是两两分组,没组中的两个内存块称为伙伴。但如果两个伙伴都是空闲的,内核绘讲起合并为一个更大的内存块,作为下一层次上某个内存块的伙伴
2.slab缓存
内核本身经常需要比完整页帧小的多的内存块。由于内核无法使用标准库的函数,因而必须在伙伴系统基础上自私那个定义额外的你存管理层,讲伙伴系统提供页划分为更小的部分。改方法不仅可以分配内存,还为频繁使用的小队向实现了一个一般性的缓存——slab缓存。
(1)队频繁使用对象,内核定义了之包含了所需类型对象实例的缓存。每次需要某种对象时,可以从对应缓存快速分配。slab缓存自动维护与伙伴系统的交互,子啊缓存佣金时绘请求信得页帧。
(2)对通常情况下小内存块的分配,内核针对不同大小的对象定义了一组slab 缓存,可以向用户空间编程一样,用相同的函数访问这些缓存。不同之处是这些函数都增加了前缀k,表明是与内核相关联的:kmalloc和kfree.
(3)页面交换和页面回收
页面回收用于将内存映射被修改的内容与底层的块设备同步,为此有事业简称为数据回写。数据刷出后,内核即可将业帧用于其他用途。内核的数据结构包含了与此相关的所有信息,当再次需要改数据时,可根据相关信息从硬盘找到响应的数据并加载。
=========================================
1.3.6 计时
内核必须能够测量时间以及不同时间点的时差,进程调度就会用到改功能。jiffies是一个合适的时间坐标。名为jiffies_64和jiffiess的全局变量,绘按恒定的时间间隔递增。每种计算机底层体系结构都提供了一些执行周期操作的手段,通常的形式是定时器中断。对前述的两个全局变量的更新可使用的地城体系结构提供的各种定时器机制执行。
jiffies递增的频率同体系结构有关,取决于内核中一个主要的常数HZ.
及时的周期是可以动态改变的。动态改变及时周期对于供电受限的系统是很有用的。

============================================
1.3.7 系统调用
系统调用时用户进程与内核交互的经典方法。
*进程管理:创建信进程,查询信息,调试。
*信号:发送信号,定时器以及相关处理机制。
*文件:创建、打开和关闭文件,从文件读取和向文件写入,查询信息和状态。
*目录和文件系统:创建、删除和崇明名目录,查询信息,链接,变更目录。
*保护机制:读取和变更UID/GID,命名空间的处理
*定时器函数:定时器函数和统计信息

===========================================
1.3.8 设备驱动程序、块设备和字符设备
设备驱动程序用于与系统链接的输入/输出装置通信。按照经典的UNIX箴言“万物皆文件”(everything is a file),对外设的访问可利用 /dev目录下的设备文件来完成,程序对设备的处理完全累世与常规的文件。设备驱动程序的任务在于支持应用程序经由设备文件与设备通信。换言之,是的能够按适当的方式在设备上读取/写入数据。
(1)字符设备:提供连续的数据流,应用程序可以顺序读取,通常不支持随机存取。相反,此类设备支持按字符/字符来读写数据。
(2)块设备:应用程序可以随机访问设备数据,程序可自行确定读取数据的位置。硬盘式典型的块设备,应用程序可以寻址磁盘上的任何位置,并由此读取数据。此外数据的读写只能以块(通常是512B)的倍数进性。与字符设备不同,块设备病不支持基于字符的寻址。

=================================================
1.3.9 网络
网卡页可以通过设备驱动程序控制,但子啊内核中属于特殊状况,因为网卡不能利用设备文件访问。为支持通过文件接口处理网络连接,Linux使用了源于BSD的套接字抽象。套接字可以看作应用程序、文件借口、内核的网络实现之间的代理。

====================================
1.3.10 文件系统
Linux系统有数以千计乃至百万计的文件组成,器数据存储在硬盘或其他块设备。存储使用了层次式文件系统。文件系统使用目录结构组织存储的数据,并将其他元信息与实际数据关联起来。Linux支持许多不同的文件系统:标准的Ext2和Ext3文件系统、ReiserFS、XFS\ VFAT,还有许多其他文件系统。不同文件系统所给予的概念抽象,在某种程度上可以说是南辕北辙。Ext2基于inode,即他对每个文件都构造了一个单独的管理结构,称为inode,并存储到磁盘上。inode包含了文件锁有的元信息,以及指向相关数据块的指针。目录可以表示为普通文件,器数据包括了指向目录所有文件的inode的指针,因而层次结构得意建立。ReiserFS广泛应用了树形结构来同同样的功能。
内核必须提供一个额外的软件层,将各种底层文件系统的具体特性与应用层(和内核自身)隔离开来。改软件层称为VFS(Virtual Filesystem或Virtual Filesystem Switch,虚拟文件系统或虚拟问阿金系统交换器)。VFS既是向下的接口(所有文件系统都必须实现改接口),同时也是向上的接口(用户进程通过系统调用最终能够访问文件系统功能)。

=================================================
1.3.11 模块和热插拔
模块用于在运行时冬天地向内核添加功能,内核的任何字熊几乎都可以模块化。这消除了宏内核与微内核相比一个重要的不利之处。
模块还可以在运行时从内核卸载,这在开发信得内核组件时很有用。
模块在本质上不过是普通的程序,只是在内核空间而不是用户空间执行而已。某块必须提供某些代码段在模块初始化(和终止)时执行,以便向内核注册和注销模块。另外,模块代码与普通内核代码的权利(和义务)都是相同的,可以像编译到内核中的代码一样,访问内核中所有的函数和数据。
内核社区中一个长期存在的争论则是围绕之同二进制代码的模块展开的,即不提供源代码的模块。在大多数私有的操作系统上只提供二进制代码的模块式普遍存在的,但许多内核开发者认为邪恶的化身。内核是开源软件,因此他们呢认为,处于各种法律和技术原因,模块页应该是开源的。

============================================
1.3.13 缓存
内核使用缓存来改进系统性能。从低俗的块设备读取的数据会暂时保存在内存中,及时数据在当时已经不再需要了。在应用程序下一次访问该数据时,他可以从访问速度较快的内存中读取,因而绕过低俗的块设备。由于内核是通过基于页的内存映射来实现访问块设别的,因此缓存也按页组织,页就是说整页都缓存起来,古城为页缓存(page cache)

==========================================
1.3.13 链表处理
C程序中重复出现的一项任务是对双链表的处理。内核也需要处理这样的链表。
内核提供的标准链表可用于讲任何类型的数据结构彼此链接起来。加入链表的数据结构必须包含一个类型为list_head的成员,其中包含了正向和反向指针。
*list_add(new, head)用于现存的head元素之后,紧接着插入new元素
*list_add_tail(new,head)用于在head元素之前,紧接着插入new元素。如果指定head为表头,由于链表是循环的,那么new元素就插入到链表的末尾.
*list_del(entry)从链表中删除一项
*list_empty(head)检测链表是否为空,页就是链表是否没有包含元素。
*list_splice(list, head)负责合并两个链表,把list插入到领一个现存链表的head元素之后。
*查找链表元素必须使用list_entry.ptr是指向数据结构中list_head成员实例的一个指针,type是改数据结构的类型,而member则是数据结构中表示链表元素的成员名。
*list_for_each(pos, head)用于遍历链表的所有元素。pos表示链表中的当前位置,而head指定了表头。

===========================================
1.3.14 对象管理和引用计数
一般性的内核对象机制可用于执行下列对象操作:
* 引用计数
* 管理对象那个链表(集合);
* 集合加锁
* 讲对象属性到处到用户空间(通过sysf文件系统)。
1一般性的内核对象
kobject不是通过指针与其他数据接哦故链接起来,而必须直接嵌入。这样做,通过管理kobject即达到了对包含kobject对象的管理,由于kobject结构绘嵌入懂啊内核的许多数据结构中。开发者需要注意保持改结构较少。向该数据结构添加一个新成员,则会导致许多其他数据结构的大小增加。
*k_name是对象的文本名称,可利用sysfs导出用户空间。sysfs是一个虚拟文件系统,可以将系统各种属性描述导出到用户空间。sd即用与支持内核对像与sysfs之间的关联,
*kref类型为struct kref,用于简化引用计数的管理
*将对象鱼其他对象放置到一个集合时,则需要kset
*parent是一个纸箱父对象的指针,可用于在kobject之间建立层次结构
*ktype提供了包含kobject的数据接哦故的更多详细信息。其中,最重要的是用于释放改数据结构资源析构函数。
kobject与面向对象编程语言中的对象概念的相似性绝不是巧合。kobject抽象实际上同乐在内核使用面向对象结束的可能性,而无需C++的所有额外机制。

kobject_get, kobject_put
kobject_(un)register
kobject_init
kobject_add
kobject_cleanup

2.对象集合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值