第1章 Linux内核介绍
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Linux系统调用 1.1.1 Linux系统调用
所有的操作系统在内核里都有一些内建的函数, 所有的操作系统在内核里都有一些内建的函数,这些函 数完成对硬件的访问和对文件的打开、 关闭等操作。 数完成对硬件的访问和对文件的打开、读、写、关闭等操作。 Linux系统中称这些函数叫做“系统调用”(即systemcall)。 系统中称这些函数叫做“ 系统中称这些函数叫做 系统调用” )。 这些函数实现了将操作从用户空间转换到内核空间, 这些函数实现了将操作从用户空间转换到内核空间,有了这些 接口函数,用户就可以方便地访问硬件。例如, 接口函数,用户就可以方便地访问硬件。例如,在用户空间调 函数, 用open()函数,则会在内核空间调用 函数 则会在内核空间调用sys_open()。一个已经安 。 装的系统所支持的系统都调用可以在/usr/include/bits/syscall.h 装的系统所支持的系统都调用可以在 文件里面看到。 文件里面看到。
第1 章
Leabharlann Baidu
Linux内核介绍 Linux内核介绍
在进行系统移植的时候,移植的核心就是内核的移植。 在进行系统移植的时候,移植的核心就是内核的移植。 内核移植的不仅影响到系统的功能, 内核移植的不仅影响到系统的功能,而且还影响到整个系统 的性能。因此,了解Linux内核,有利于开发人员进行系统裁 内核, 的性能。因此,了解 内核 剪和移植。下面主要针对Linux内的五个重要部分系统调用接 剪和移植。下面主要针对 内的五个重要部分系统调用接 进程管理、内存管理、虚拟文件系统和设备驱动程序, 口、进程管理、内存管理、虚拟文件系统和设备驱动程序, 进行介绍。 进行介绍。
1.2.5 进程地址空间
Linux的虚拟地址空间为 ~4G字节。虚拟的 字节空 的虚拟地址空间为0~ 字节 虚拟的4G字节空 字节。 的虚拟地址空间为 间被Linux内核分为内核空间和用户空间两部分。将最高的 内核分为内核空间和用户空间两部分。 间被 内核分为内核空间和用户空间两部分 1G字节(从虚拟地址 字节( ),留给内 字节 从虚拟地址0xC0000000到0xFFFFFFFF),留给内 到 ), 核使用,称为“内核空间” 将较低的3G字节 字节( 核使用,称为“内核空间”。将较低的 字节(从虚拟地址 0x00000000到0xBFFFFFFF),留给用户进程使用,称为“ ),留给用户进程使用 到 ),留给用户进程使用,称为“ 用户空间” 因为每个进程可以通过系统调用进入内核, 用户空间”。因为每个进程可以通过系统调用进入内核,因 内核空间被系统的所有进程共享, 此,Linux内核空间被系统的所有进程共享,实际上对于某个 内核空间被系统的所有进程共享 进程来说,它仍然可以拥有4G字节的虚拟空间 字节的虚拟空间。 进程来说,它仍然可以拥有 字节的虚拟空间。
1.1.4 系统调用过程
通常情况下abc()系统调用对应的服务例程的名字是 系统调用对应的服务例程的名字是 通常情况下 sys_abc()。 。 (1)用户程序中调用库函数 )用户程序中调用库函数abc()。 。 库调用索引和参数后, (2)系统加载 )系统加载libc库调用索引和参数后,执行 库调用索引和参数后 执行int $0x80或者 或者sysenter汇编指令进入系统调用,执行 汇编指令进入系统调用, 或者 汇编指令进入系统调用 执行system_call 函数。 函数。 (3)system_call函数根据传递过来的参数处理所有的 ) 函数根据传递过来的参数处理所有的 系统调用。使用system_call_table[参数 执行系统调用。 参数]执行系统调用 系统调用。使用 参数 执行系统调用。 (4)系统调用返回。 )系统调用返回。 或者sysexit汇编指令两种方式退出系统调 (5)执行 )执行iret或者 或者 汇编指令两种方式退出系统调 并调用resume_userspace进入用户空间。 进入用户空间。 用,并调用 进入用户空间 库中执行, (6)继续在 )继续在libc库中执行,执行完成后返回到用户应 库中执行 用程序中。 用程序中。
1.2.2 进程描述符
内核对进程的优先级、进程的状态、 内核对进程的优先级、进程的状态、地址空间等采用进程描述 符表示。 内核内, 符表示。在 Linux 内核内,进程是由相当大的一个称为 task_struct 的结构表示。 的结构表示。 state:表示进程的状态,-1代表“不能运行”,0代表“运行” 代表“ 代表“ :表示进程的状态, 代表 不能运行” 代表 运行” 代表“ ,>0代表“停止”。 代表 停止” flags:定义了很多指示符,表明进程是否正在被创建( :定义了很多指示符,表明进程是否正在被创建( PF_STARTING)或退出(PF_EXITING),或是进程当前是否在分 ),或是进程当前是否在分 )或退出( ), 配内存(PF_MEMALLOC)。可执行程序的名称(不包含路径)占 配内存( )。可执行程序的名称(不包含路径) )。可执行程序的名称 用 comm(命令)字段。 (命令)字段。 tasks 字段提供了链接列表的能力。它包含一个 prev 指针(指向 字段提供了链接列表的能力。 指针( 前一个任务) 指针(指向下一个任务)。 前一个任务)和一个 next 指针(指向下一个任务)。
1.3
内存管理
RAM的一部分被静态地划分给了内核,用来存放内核 的一部分被静态地划分给了内核, 的一部分被静态地划分给了内核 代码和静态数据结构。 的其余部分称为动态内存( 代码和静态数据结构。RAM的其余部分称为动态内存( 的其余部分称为动态内存 dynamic memory),这不仅是运行用户进程所需的宝贵资 ),这不仅是运行用户进程所需的宝贵资 ), 也是内核所需的宝贵资源。事实上, 源,也是内核所需的宝贵资源。事实上,整个系统的性能取 决于如何有效地管理动态内存。 决于如何有效地管理动态内存。
1.3.1 内存管理技术
页表( ):进程在读取指令和存取数据时都 页表(page tables):进程在读取指令和存取数据时都 ): 要访问内存。在一个虚拟内存系统中, 要访问内存。在一个虚拟内存系统中,所有的地址都是虚拟 地址而非物理地址。 地址而非物理地址。操作系统维护虚拟地址和物理地址转换 的信息,处理器通过这组信息将虚拟地址转换为物理地址。 的信息,处理器通过这组信息将虚拟地址转换为物理地址。 虚拟内存和物理内存被分为适当大小的块,叫做页。 虚拟内存和物理内存被分为适当大小的块,叫做页。为了将 虚拟地址转换为物理地址,首先, 虚拟地址转换为物理地址,首先,处理器要找到虚拟地址的 页编号和页内偏移量;然后, 页编号和页内偏移量;然后,处理器根据虚拟地址和物理地 址的映射关系将虚拟页编号转换为物理的页;最后, 址的映射关系将虚拟页编号转换为物理的页;最后,根据偏 移量访问物理页的确定偏移位置。 移量访问物理页的确定偏移位置。每个物理页面都有一个 struct page结构,位于 结构, 结构 位于include/linux/mm.h,该结构体包含 , 了管理物理页面时的所有信息。 了管理物理页面时的所有信息。
1.2.4 进程调度
Linux进程调度的目的就是调度程序运行时,要在所有 进程调度的目的就是调度程序运行时, 进程调度的目的就是调度程序运行时 可运行状态的进程中选择最值得运行的进程投入运行。 可运行状态的进程中选择最值得运行的进程投入运行。每个 进程的task_struct结构中有以下四项 结构中有以下四项policy、priority、 进程的 结构中有以下四项 、 、 counter、rt_priority。这四项是选择进程的依据。 、 。这四项是选择进程的依据。
1.2.3 进程状态
进程描述符中state字段描述进程当前的状态。它由一组 字段描述进程当前的状态。 进程描述符中 字段描述进程当前的状态 标志组成,其中每个标志描述一种可能的进程状态。 标志组成,其中每个标志描述一种可能的进程状态。下面分别 对这些状态进行描述: 对这些状态进行描述: 可运行状态:进程处于运行(它是系统的当前进程) 可运行状态:进程处于运行(它是系统的当前进程)或 者准备运行状态(它在等待系统将CPU分配给它)。 分配给它)。 者准备运行状态(它在等待系统将 分配给它 等待状态:进程在等待一个事件或者资源。 等待状态:进程在等待一个事件或者资源。Linux将等待 将等待 进程分成两类;可中断的等待状态与不可中断的等待状态。 进程分成两类;可中断的等待状态与不可中断的等待状态。可 中断等待进程可以被信号中断; 中断等待进程可以被信号中断;不可中断等待进程直接在硬件 条件等待,并且任何情况下都不可中断。 条件等待,并且任何情况下都不可中断。 暂停状态:进程被暂停,通常是通过接收一个信号。 暂停状态:进程被暂停,通常是通过接收一个信号。正 在被调试的进程可能处于停止状态。 在被调试的进程可能处于停止状态。 僵死状态:进程的执行被终止,但是, 僵死状态:进程的执行被终止,但是,父进程还没有发 布wait4()或waitpid()系统调用来返回有关死亡进程的信息。 或 系统调用来返回有关死亡进程的信息。 系统调用来返回有关死亡进程的信息
1.1.3 系统调用与服务例程的对应关系
为了通过系统调用号来调用不同的内核服务例程, 为了通过系统调用号来调用不同的内核服务例程,系 统必须创建并管理好一张系统调用表。 统必须创建并管理好一张系统调用表。该表用于将系统调用 号与内核服务函数的映射。 是用数组sys_call_table来 号与内核服务函数的映射。Linux是用数组 是用数组 来 表示这个表。 表示这个表。在这个表的每个表项中存放着对应内核服务例 程的指针, 程的指针,而该表项的下标就是该内核服务例程的系统调用 规定, 体系中, 号。Linux规定,在I386体系中,处理器的寄存器 用来传 规定 体系中 处理器的寄存器eax用来传 递系统调用号。 递系统调用号。
1.1.5 系统调用传递的参数
系统调用中输入输出的参数为实际传递的值或者是用 户态进程的地址, 户态进程的地址,或者是指向用户态函数的指针的数据结构 地址。传递的参数放在寄存器eax中 即系统调用号。 地址。传递的参数放在寄存器 中,即系统调用号。寄存 器传递参数的个数满足两个条件: 器传递参数的个数满足两个条件: • 参数的长度不超过寄存器的长度,如果是32位平台不 参数的长度不超过寄存器的长度,如果是 位平台不 超过32位 位平台不超过64位 超过 位,64位平台不超过 位。 位平台不超过 • 不包括eax中的系统调用号 参数的个数不超过6个 中的系统调用号, 不包括 中的系统调用号,参数的个数不超过 个。
1.1
系统调用接口
系统调用是操作系统提供给用户程序调用的一组“ 系统调用是操作系统提供给用户程序调用的一组“特殊 接口。用户程序可以通过这组“特殊” ”接口。用户程序可以通过这组“特殊”接口来获得操作系 统内核提供的服务。例如, 统内核提供的服务。例如,用户可以通过文件系统相关的调 用请求系统打开文件、关闭文件或读写文件; 用请求系统打开文件、关闭文件或读写文件;通过时钟相关 的系统调用获得系统时间或设置系统时间; 的系统调用获得系统时间或设置系统时间;通过进程控制相 关的系统调用来创建进程、实现进程调度、进程管理等。 关的系统调用来创建进程、实现进程调度、进程管理等。
1.2
进程管理
进程管理包括创建进程、管理进程以及删除进程。 进程管理包括创建进程、管理进程以及删除进程。进 程管理是Linux内核的重要部分,对系统的核心资源进行管 内核的重要部分, 程管理是 内核的重要部分 做好系统移植需要对这部分知识有一定的了解。 理。做好系统移植需要对这部分知识有一定的了解。
1.2.1 进程
进程是程序执行时的一个实体。程序包含指令和数据, 进程是程序执行时的一个实体。程序包含指令和数据, 而进程包含程序计数器和全部CPU寄存器的值。进程的堆栈 寄存器的值。 而进程包含程序计数器和全部 寄存器的值 中存储着一些数据,如子程序参数、 中存储着一些数据,如子程序参数、返回地址以及变量之类 的临时数据。当前的执行程序(进程) 的临时数据。当前的执行程序(进程)包含着当前处理器中 的活动状态。 的活动状态。
1.1.2 用户编程接口
用户编程接口是为用户编程过程提供的各种功能库函 如分配空间、拷贝字符、打开文件等。 数,如分配空间、拷贝字符、打开文件等。Linux用户编程 用户编程 接口( 接口(API)遵循了在 )遵循了在UNIX中最流行的应用编程界面标准 中最流行的应用编程界面标准 ——POSIX标准。它与系统调用之间存在一定的联系和区别 标准。 标准 不同的语言和平台为用户提供了丰富的编程接口, 。不同的语言和平台为用户提供了丰富的编程接口,包括网 络编程接口、图形编程接口、数据库编程接口等, 络编程接口、图形编程接口、数据库编程接口等,但这些不 是系统调用。 是系统调用。