132
9 9 Linux Linux Linux 第

第九章 文件系统

  • Upload
    ruana

  • View
    168

  • Download
    6

Embed Size (px)

DESCRIPTION

第九章 文件系统. (一)文件系统的基本概念 (二)文件的逻辑结构与存取方法 (三)文件的物理结构 (四)文件存储空间管理 (五)文件目录结构 (六)文件的共享与保护 (七)文件操作. (一)文件系统的基本概念. 一 . 文件 所有的计算机应用程序都要:存储信息,检索信息 三个基本要求: 存储大量的信息 ; 长期保存信息 ; 可以共享信息 解决方法:把信息以一种单元,即文件的形式存储在磁盘或其他外部介质上. 1. 什么是文件. 文件是在逻辑上具有完整意义的信息集合。它有一个名字以供标识。文件名是以字母开头的字母数字串。 - PowerPoint PPT Presentation

Citation preview

Page 1: 第九章   文件系统

第第 99 章 章 LinuxLinux 系统系统

Linux 系统

Page 2: 第九章   文件系统

LinuxLinux 系统概述系统概述

LinuxLinux 的特权级与中断处理的特权级与中断处理

LinuxLinux 系统功能调用系统功能调用

LinuxLinux 系统的进程管理系统的进程管理

LinuxLinux 系统的存储管理系统的存储管理

LinuxLinux 系统的设备驱动系统的设备驱动

LinuxLinux 文件文件系统系统

1

Linux 系统——主要内容

Page 3: 第九章   文件系统

Linux 系统概述

Linux 系统—— Linux 系统概述

Page 4: 第九章   文件系统

1. Linux1. Linux 系统的定义系统的定义 Linux 系统是一个类 UNIX 的操作系统,与 UNIX 完全兼容, 在操作系统功能、使用方法等方面极为相似。

(1) (1) 什么是什么是 LinuxLinux 操作系统操作系统 Linux 是一个多用户、多任务操作系统

(2) Linux(2) Linux 与与 UNIXUNIX 操作系统的不同点操作系统的不同点① 源代码编写方式② 商业模式 ③ 开发模式

2

Linux 系统—— Linux 系统概述

Page 5: 第九章   文件系统

(4) Linux(4) Linux 系统的特点系统的特点① 单体结构内核② 可抢占式内核③ 多线程应用程序的支持④ 多处理机支持⑤ 支持多种文件系统

(3) Linux(3) Linux 系统的组成系统的组成 Linux 操作系统包括 Linux 内核,还包括 shell 、带有多窗

口 管理器的 X-Windows 图形用户接口、文本编辑器、高级语 言编译器等应用软件。

3

Linux 系统—— Linux 系统概述

Page 6: 第九章   文件系统

2. Linux2. Linux 系统的内核结构系统的内核结构

(1) Linux(1) Linux 内核的组成内核的组成 Linux 内核包含最基础、最核心的概念,提供系统其他部

分必须的服务支持。

组成

进程调度程序、主存管理程序

负责网络、进程间通信的服务程序

中断处理程序和设备驱动等核心服务程序

4

Linux 系统—— Linux 系统概述

Page 7: 第九章   文件系统

5

(2) Linux(2) Linux 系统的核心结构系统的核心结构

系 统 调 用 界 面

程 序 库

进程通信

进程调度

存储管理

文件子系统

高速缓冲

字符设备 块设备 设备驱动程序

用户程序

硬 件 控 制

硬 件

用户级核心级

硬件层

进程管理与存储管理 网络管理

网络协议

网络驱动

Linux 系统的核心结构示意图

Linux 系统—— Linux 系统概述

Page 8: 第九章   文件系统

Linux 系统的特权级与中断处理

Linux 系统—— Linux 系统的特权级与中断处理

Page 9: 第九章   文件系统

6

1. Linux1. Linux 系统的特权级系统的特权级Linux 系统使用两个级别 ( 处理机提供四个特权级 ) :特权级 0 —— 核态 ( 内核模式 )

特权级 3 —— 用户态 ( 用户模式 )

2. Linux2. Linux 系统中断处理的上半部和下半部系统中断处理的上半部和下半部 (1) (1) 为什么要区分上半部和下半部为什么要区分上半部和下半部

Linux 系统—— Linux 系统的特权级与中断处理

为提高中断处理的效率,中断处理程序的执行必须快速、简洁。为此, Linux 系统将中断处理程序分为两部分。

将中断响应后必须立即处理的工作即刻执行,这就是中断处理程序的上半部 (tophalf) 。

将更多的处理工作向后推迟执行,这就是中断处理程序序的下半部(bottom half) 。

Page 10: 第九章   文件系统

7

(2) (2) 中断处理程序的上半部中断处理程序的上半部上半部是中断处理中有严格时间限制的工作,是关键而

紧迫的部分 ;

上半部的工作是不可被打断的,即在屏蔽所有中断的情 况下进行的。例:与硬件设备应答或使硬件复位的工作。

(3) (3) 中断处理程序的下半部中断处理程序的下半部下半部处理那些可以稍后完成的工作; 下半部的执行是可以打断的,即是在开中断的情况下执

行。

Linux 系统—— Linux 系统的特权级与中断处理

Page 11: 第九章   文件系统

8

3. 3. 中断处理下半部的实现机制中断处理下半部的实现机制 Linux 系统中,用于实现实现将工作推后执行的内核机制称为 “ 下半部机制”,下半部机制主要有 tasklet 和工作队列两种。

(1) tasklet(1) tasklet

① tasklet 通过软中断实现

ⅰ 一个软中断被标记后才能执行,称为触发软中断。

ⅱ 待处理的软中断会在以下时机被检查和执行:从一个硬件中断返回时;在 ksoftirqd 内核线程中;在显示检查和执行待处理的软中断的代码中。

Linux 系统—— Linux 系统的特权级与中断处理

Page 12: 第九章   文件系统

9

② Tasklet 软中断ⅰ tasklet 的软中断表示是 TASKLET_SOFTIRQ ;

ⅱ Taskle 由结构体 tasklet_struct 结构表示

struct tasklet_struct

{

struct tasklet_struct *next; /* 链表中的下一个 taskle */

unsignet long state; /* taskle 的状态 */

atomic_t count; /* 引用计数器 */

void (*func) (unsigned long); /* taskle 的处理函数 */

unsigned long data; /* 给 taskle 处理函数的参数 */

}

tasklet 由 tasklet_schedule() 函数调度

Linux 系统—— Linux 系统的特权级与中断处理

Page 13: 第九章   文件系统

10

(2) (2) 工作队列工作队列① 工作队列机制将中断处理程序的下半部交给一个内核线

程去执行。

② 下半部是在进程上下文 ( 用户地址空间 ) 执行,可以睡眠和

被重新调度。

注:这一点与上述的 tasklet 不同。如果下半部工作需要睡

眠 ( 如需要执行阻塞式 I/O 操作时,或要等待信号灯 )

时应

选择工作队列机制;否则可选择 tasklet 机制。

Linux 系统—— Linux 系统的特权级与中断处理

Page 14: 第九章   文件系统

11

③ 工作者线程

ⅰ 该线程接收由各内核中断处理程序交给它的下半部。

ⅱ 该线程内核线程实现的。执行的函数是 work_thread() ,

对应的数据结构是工作队列链表。

④ 工作队列链表

ⅰ 由若干个 work_struct 结构组成。

ⅱ work_struct 结构

Linux 系统—— Linux 系统的特权级与中断处理

Page 15: 第九章   文件系统

12

work_struct 结构

每个 work_struct 结构描述如下

struct work_struct

{

unsigned long pending; /* 该工作正在等待处理? */

struct list_head entry; /* 勾链字 */

void (*func) (void *); /* 该工作的处理函数 */

void *data; /* 传递该该处理函数的参数 */

void *wq_data; /* 内部使用 */

struct timer_list timer; /* 延迟的工作队列所用的定时器 */

}

Linux 系统—— Linux 系统的特权级与中断处理

Page 16: 第九章   文件系统

13

⑤ 执行函数 work_thread()ⅰ 执行一个死循环;ⅱ 若工作队列链表不空时,执行链表上的所有工作。工 作被执行完毕,它就将相应的 work_struct 对象从链表 上移走;ⅲ 当链表为空时,它进入睡眠状态;ⅳ 当有下半部插入到队列时,函数是 work_thread()

被唤醒,将继续处理新加入的下半部 。

Linux 系统—— Linux 系统的特权级与中断处理

Page 17: 第九章   文件系统

Linux 系统的功能调用

Linux 系统—— Linux 系统功能调用

Page 18: 第九章   文件系统

14

1. Linux1. Linux 系统功能调用的过程系统功能调用的过程在 Linux 系统中,系统调用通过异常类型实现;

当执行了 int 0x80指令而发生的软件中断;

系统自动将用户态切换为核心态来处理该事件,执行自陷处理程序 ( 系统调用处理程序 ) 。

Linux 系统—— Linux 系统功能调用

Page 19: 第九章   文件系统

15

(1) (1) 系统功能调用过程系统功能调用过程

abc();

abc();

{

syscall;

}

system_call:

sys_abc

SYSEXIT

sysabc()

{

}

用户态 核心态

用户程序系统调用

在 libc 标准库中的封装例程

系统调用处理程序

系统调用服务例程

Linux 系统调用过程

Linux 系统—— Linux 系统功能调用

Page 20: 第九章   文件系统

16

(2) (2) 例:例: getuidgetuid 系统调用过程 系统调用过程

int main()

{

getuid();

}

int getuid(void)

{

long_res;

int $0x80;

}

ENTRY(system_call)

pushl % esx

SAVE_ALL

GET_CURRENT(%ebx)

call sys_getuid16

RESTORE_ALL

asmlinkage long

sys_getuid16(void)

{

return high2lowuid

(current_uid);

}

用户程序 系统调用处理程序标准 C 库 内核例程

getuid 系统调用过程

Linux 系统—— Linux 系统功能调用

Page 21: 第九章   文件系统

17

2. Linux2. Linux 系统功能调用的实现机制系统功能调用的实现机制 (1) Linux(1) Linux 系统调用的进入系统调用的进入

① Linux 系统的软中断指令是 int 0x80 汇编语言指令

② 该指令的执行会发生中断

③ 处理机的状态由用户态自陷到内核态

④ 从 system_call() 开始执行系统调用处理程序。

⑤ 当系统调用处理完毕后,通过 iret 汇编语言指令返回到用

户态。

Linux 系统—— Linux 系统功能调用

Page 22: 第九章   文件系统

18

(2) (2) 系统调用号系统调用号① linux 中,每个系统调用被赋予一个唯一的系统调用号 ② 系统调用号定义在 include/asm-i386/unistd.h头文件中 ③ 系统调用号格式如下 #define __NR_restart_syscall 0

#define __NR_exit 1

#define __NR_fork 2

#define __NR_read 3

#define __NR_write 4

#define __NR_open 5

…………

…………

#define __NR_mq_getsetattr 282

Linux 系统—— Linux 系统功能调用

Page 23: 第九章   文件系统

19

(3) (3) 系统调用表系统调用表① 系统调用表记录了内核中所有已注册过的系统调用,

它是系统调用的跳转表。

② 系统调用表是一个函数指针数组,表中依次保存所有

系统调用的函数指针

③ Linux 系统调用表保存在 arch/i386/kernel/ 下的 entry.S 中

Linux 系统—— Linux 系统功能调用

Page 24: 第九章   文件系统

20

④ 系统调用表格式如下

ENTRY(sys_call_table)

.long sys_restart_syscall /* 0 */

.long sys_exit /* 1 */

.long sys_fork /* 2 */

.long sys_read /* 3 */

.long sys_write /* 4 */

.long sys_open /* 5 */

…………

…………

.long sys_mq_getsetattr /* 282 */

Linux 系统—— Linux 系统功能调用

Page 25: 第九章   文件系统

21

(4) (4) 系统调用处理程序系统调用处理程序 系统调用处理程序是 system_call() ,主要工作如下

宏 SAVE_ALL保护现场;

正确性检查 ;

依 eax 中所包含的系统调用号,调用其对应的服务例

程;

系统服务例程结束时,通过宏 RESTORE_ALL恢复寄

存器;

最后通过 iret指令返回。

Linux 系统—— Linux 系统功能调用

Page 26: 第九章   文件系统

22

3. 3. 增加一个新的增加一个新的系统功能调用的方法系统功能调用的方法 (1) (1) 添加新的服务例程添加新的服务例程

① 在 /usr/src/linux/kernel/sys.c 文件中增加一个新的函数,

该函数的名字是 sys_mysyscall

② 例:一个简单的系统调用,其功能是返回一个整型值 asmlinkage int sys_mycall(int number)

{

return number;

}

Linux 系统—— Linux 系统功能调用

Page 27: 第九章   文件系统

23

(2) (2) 增加新的系统功能调用号增加新的系统功能调用号 ① 在文件 include/asm-i386/unistd.h 中添加一项

#define __NR_mysyscall XX

② XX 为新增加的系统调用号,此数字选一未用值。

③ 例 #define __NR_restart_syscall 0

#define __NR_exit 1

…………

…………

#define __NR_mq_getsetattr 282

#define __NR_mysyscall 283

Linux 系统—— Linux 系统功能调用

Page 28: 第九章   文件系统

24

(3) (3) 修改系统调用表修改系统调用表 ① 在文件 /arch/i386/kernel/entry.S 中的系统调用表

sys_call_table 中添加新增的系统调用

sys_call_table 数组包含指向内核中每个系统调用的指针

② 例 ENTRY(sys_call_table)

.long sys_restart_syscall /* 0 */

.long sys_exit /* 1 */

…………

…………

.long sys_mq_getsetattr /* 282 */

.long sys_mysyscall /*283*/

Linux 系统—— Linux 系统功能调用

Page 29: 第九章   文件系统

25

(4) (4) 重新编译内核并启动新内核重新编译内核并启动新内核 为使新的系统调用生效,需要重建 Linux 的内核。

这需要以超级用户身份登录后重新编译内核。

(5) (5) 在用户程序中访问新的系统调用在用户程序中访问新的系统调用

在用户程序中,测试新增加的系统调用是否能正确使用。

Linux 系统—— Linux 系统功能调用

Page 30: 第九章   文件系统

Linux 系统的进程管理

Linux 系统—— Linux 系统的进程管理

Page 31: 第九章   文件系统

26

1. Linux1. Linux 系统进程与线程系统进程与线程 (1) Linux(1) Linux 系统中的进程系统中的进程 进程是程序在处理机上的一次执行过程。进程是处于执行 期的程序,它是分配系统资源和调度的实体。 进程包括可执行的程序代码、打开的文件、挂起的信号、 内核数据、地址空间、处理机状态、一个或多个可执行 的线程等。

(2) Linux(2) Linux 系统中的线程系统中的线程 Linux 系统将线程看作是一种特殊的进程。线程被视为一 个与其他进程共享某些资源的进程。

Linux 系统—— Linux 系统的进程管理

Page 32: 第九章   文件系统

27

2. Linux2. Linux 系统的进程描述符系统的进程描述符 Linux 内核使用进程描述符 (又称为进程控制块 )来描述一

进程的完整信息。(1) (1) 进程控制块的结构进程控制块的结构

Linux 系统—— Linux 系统的进程管理

Page 33: 第九章   文件系统

28

指向进程基本控制块的指针

进程状态 state

进程标识

进程调度有关的字段

进程亲属关系的字段

指向当前目录的指针指向文件描述符的指针指向主存描述符的指针指向信号结构的指针指向 tty 结构的指针

task_struct

thread_info

当前目录

文件描述符

主存描述符

所接收的信号

与进程相关的 tty

指向进程队列

priopidtgidpgrp

sessinthread_info

run_list

tty

real_parentparent

childrensibling

fsfilesmm

signal

进程控制块的结构

进程控制块结构

LinuxLinux 系统——系统—— LinuxLinux 系统的进程管理系统的进程管理

Page 34: 第九章   文件系统

29

(2) (2) 进程控制块的主要内容进程控制块的主要内容

① 进程标识符 进程标识符 process ID

进程描述符中的标识符字段

字段名 说明

pid 进程的 PID

tgid 线程组领头进程的 PID

pgrp 进程组领头的进程 PID

session 会话领头进程的 PID

Linux 系统—— Linux 系统的进程管理

Page 35: 第九章   文件系统

30

② 进程状态

反映进程当前状态,包括以下几种可能的状态

ⅰ 可运行状态 TASK_RUNNING

ⅱ 可中断的等待状态 TASK_INTERRUPTIBLE

ⅲ 不可中断的等待状态 TASK_UNINTERRUPTIBLE

ⅳ 暂停状态 TASK_STOPPED

ⅴ 终止状态 TXIT_ZOMBIE

Linux 系统—— Linux 系统的进程管理

Page 36: 第九章   文件系统

31

③ 进程基本信息 每个进程都有一个进程基本信息块。在进程描述符的 thr

ead_info 字段中包含了指向该结构的指针 ④ 与进程调度有关的信息 可运行进程链表 ( 最多可有 140 个 )

⑤ 进程的亲属关系 进程描述符中的亲属关系字段

字段名 说明

real_parent 指向创建 p 进程的父进程的描述符,若该父进程不再存在,就指向 1# 进程

parent 指向 p 进程的当前父进程,它的值通常与 real_parent 一致,偶尔也可不同

children 链表的头部,链表中的所有进程都是 p 进程创建的子进程sibling 指向兄弟进程链表中的下一个或前一个元素的指针

Linux 系统—— Linux 系统的进程管理

Page 37: 第九章   文件系统

32

⑥ 其他字段 在进程描述符的 thread_info 字段中包含了指向各种结构

的 指针。ⅰ fs —— 指向当前目录结构 fs_steuct

ⅱ files —— 指向文件描述符结构 files_struct

ⅲ mm ——指向主存描述符结构 mm_struct

ⅳ signal ——指向信号结构 signal_struct

ⅴ tty ——指向进程相关的 tty_struct 结构

Linux 系统—— Linux 系统的进程管理

Page 38: 第九章   文件系统

33

(1) TASK_RUNNING ((1) TASK_RUNNING ( 可运行状态可运行状态 ) )

① 它或者正在执行,运行状态② 或者在运行队列中等待执行,就绪状态

(2) TASK_INTERRUPTIBLE ((2) TASK_INTERRUPTIBLE ( 可中断的等待状态可中断的等待状态 ))

进程正在等待某一事件的发生 ( 如某一硬件中断或一个信 号 ) ,它处于挂起或称睡眠状态。

(3) TASK_UNINTERRUPTIBLE ((3) TASK_UNINTERRUPTIBLE ( 不可中断的等待不可中断的等待 状态状态 ) )

除了不会因为接收到信号而被唤醒从而投入运行外,这个 状态与可中断等待状态相同。

3. Linux3. Linux 系统进程状态及变迁系统进程状态及变迁Linux 系统—— Linux 系统的进程管理

Page 39: 第九章   文件系统

34

(4) TASK_ZOMBIE ((4) TASK_ZOMBIE ( 僵死状态僵死状态 ))

表示进程已经结束,但其父进程还没有调用 wait4() 系统

调用。子进程的进程描述符在此之前仍然被保留

(5) TASK_STOPPED ((5) TASK_STOPPED ( 停止停止 ))

表示进程停止执行,进程没有投入运行也不能投入运行。

通常这种状态发生在接收到 SIGSTOP 、 SIGTSTP 、

SIGTTIN 、 SIGTTOU 等信号的时候。

Linux 系统—— Linux 系统的进程管理

Page 40: 第九章   文件系统

35

(6) Linux(6) Linux 系统进程状态的变迁系统进程状态的变迁

运行TASK—UNNING

进程调度

等待某事件

等待的事件发生

创建新进程

就绪TASK—UNNING

进程 终止

等待TASK—INTERRUPTIBLETASK—UNINTERRUPTIBLE

被抢占

创建

进程完成

Linux 系统进程状态变迁图

Linux 系统—— Linux 系统的进程管理

Page 41: 第九章   文件系统

36

(1) (1) 进程创建进程创建 Linux 系统用 fork() 系统调用创建一个进程。

① 写时拷贝ⅰ 在创建新进程时内核不复制父进程的整个地址空间, 而是让父进程和子进程以读方式共享同一拷贝ⅱ 只有当一方真正需要写入时,数据才被复制,这时, 父、子进程才拥有各自的拷贝

4. Linux4. Linux 系统进程创建与终止系统进程创建与终止

② 系统提供 fork() 和 clone() 系统调用ⅰ fork() 用来创建一般进程ⅱ clone() 用来创建轻量级进程 ( 线程 )

Linux 系统—— Linux 系统的进程管理

Page 42: 第九章   文件系统

37

(2) (2) 进程终止进程终止 Linux 系统提供 exit() 系统调用以终止某一个进程。其主

要 功能由 do_exec() 函数完成。 进程终止后,此进程处于僵死状态,但系统还保留了它的 进程描述符。只有父进程发出了与被终止进程相关的 wait() 系统调用后,子进程的 task_struct 结构才能释放。

Linux 系统—— Linux 系统的进程管理

Page 43: 第九章   文件系统

38

(1) (1) 进程等待进程等待 ① 两种等待状态 TASK_INTERRUPTIBLE 和 TASK_UNINTERRUPTIBLE 区别:处于 TASK_UNINTERRUPTIBLE 状态的进程如果接收到一个

信 号会被提前唤醒并响应该信号,而处于 TASK_INTERRUPTIBLE 状态 的进程会忽略信号。

5. Linux5. Linux 系统的进程等待与唤醒系统的进程等待与唤醒

② 进程等待的主要步骤ⅰ 调用 declare_waitqueue()创建一个等待队列的元素。 ⅱ 调用 add_wait_queue() 将该元素加入到等待队列。ⅲ 进程的状态设置为 TASK_INTERRUPTIBLE 状态 TASK_UNINTERRUPTIBLE 状态。ⅳ 转进程调度程序 schedule() 。

Linux 系统—— Linux 系统的进程管理

Page 44: 第九章   文件系统

39

(2) (2) 进程唤醒进程唤醒 进程唤醒的主要步骤 ① 当进程状态设置为 TASK_INTERRUPTIBLE ,则由信号唤醒进程, 这是所谓的伪唤醒 ( 不是直接由所等待的事件唤醒 ) ,因此需要检 查并处理信号。 ② 若检查条件为真 ( 所等待的事件发生 ) ,转④;若条件不为真,转

进 程调度 schdule() 。 ③ 当进程被唤醒时 (因事件发生 ) ,检查条件是否为真,若为真转④; 否则转进程调度 schdule() 。 ④ 当条件满足时,进程状态设置为 TASK_RUNNING ,并将该进程 移出等待队列。 ⑤ 该函数将进程状态设置为 TASK_RUNNING ,再将此进程加入到 可执行队列。若被唤醒进程的优先级比当前正在运行的进程的优 先级高,设置 need_resched 标志。

Linux 系统—— Linux 系统的进程管理

Page 45: 第九章   文件系统

Linux 系统的进程调度

Linux 系统—— Linux 系统的进程调度

Page 46: 第九章   文件系统

40

1. Linux1. Linux 进程调度目标和特点进程调度目标和特点

进程调度程序是内核的组成部分,负责选择下一个要运

行的进程。

进程调度可看作在可运行态进程之间分配有限的处理器

时间资源的内核子系统。

进程调度程序是如 Linux 这样的多任务操作系统的基础。

(1) Linux(1) Linux 进程调度策略进程调度策略 ① 基于动态优先级和可变时间的调度

② 调度方式为可抢占式调度

Linux 系统—— Linux 系统的进程调度

Page 47: 第九章   文件系统

41

(2) (2) 调度目标调度目标① 实现算法复杂度为 O(1) 级的调度

ⅰ 进程调度算法保证在恒定的时间内完成ⅱ 算法执行时间与系统中处于就绪 ( 可运行 ) 状态的进程

个 数无关

② 提高交互性能提高交互性能,保证系统能快速响应

③ 保证公平ⅰ 在合理设定的时间范围内,没有进程会出现饥饿状态ⅱ 也不会有进程获得大量的时间片

④ 实现 SMP 可扩展性

Linux 系统—— Linux 系统的进程调度

Page 48: 第九章   文件系统

42

(3) I/O(3) I/O消耗型和处理器消耗型的进程消耗型和处理器消耗型的进程① I/O消耗型进程

大部分时间是使用外部设备,交互式进程具有此特征。

② 处理器消耗型进程

大部分时间是使用 CPU ,计算进程具有此特征。

交互式的程序都是 I/O消耗型的。 Linux 为了保证交互式应用,优化了进程的响应,更倾

向 于优先调度 I/O消耗型进程,但并未忽略处理器消耗型

程 序。

Linux 系统—— Linux 系统的进程调度

Page 49: 第九章   文件系统

43

(4) (4) 进程调度的特点进程调度的特点① Linux 系统实现了基于进程过去行为的启发式算法;

② Linux 系统选择优先级高的进程先运行,相同优先级的进

程按循环方式调度;

③ 动态优先级依进程占有 CPU 的情况、休眠时间的长短来

增、减 ;

④ 系统根据进程优先级调整分配给它的时间片;

⑤ 实施可抢占调度方式

Linux 系统—— Linux 系统的进程调度

Page 50: 第九章   文件系统

44

2. 2. 可变优先级可变优先级 (1) (1) 基于优先级的调度基于优先级的调度 优先级高的进程先运行,低的后运行,相同优先级的进程 按轮转方式进行调度。

(2) (2) 静态优先级静态优先级① 静态优先级的确定 在进程创建时,新创建的进程继承 父进程的静态优先级② 静态优先级的取值范围 100 ( 最高优先级 ) 139 ( 最低 优先级 ) ,取值越小,优先级越高 ;

③ 静态优先级的改变 用户可以通过系统调用改变 nice值, 从而改变自己拥有的静态优先级。

Linux 系统—— Linux 系统的进程调度

Page 51: 第九章   文件系统

45

(3) (3) 动态优先级动态优先级① 每个进程有一个动态优先级 它是进程调度程序选择可运 行进程所使用的参数,其取值范围是 100 ( 最高优先级 )

139 ( 最低优先级 )

② 动态优先级的计算 动态优先级 = max(100 , min(静态优先级- bonus + 5 , 139))

bonus 是范围 0 ~ 10 的值,

值小于 5 表示降低动态优先级以示惩罚

值大于 5 表示增加动态优先级以示奖励

进程调度使用的是动态优先级,通过 effective_prio( ) 函数 来计算一个进程的动态优先级。

Linux 系统—— Linux 系统的进程调度

Page 52: 第九章   文件系统

46

(4) (4) 确定确定 I/OI/O消耗型和处理器消耗型进程的方法消耗型和处理器消耗型进程的方法① 依据 —— 进程睡眠时间的长短

若进程睡眠时间长 —— I/OI/O 消耗型消耗型

若进程睡眠时间短 ——处理器消耗型处理器消耗型

② 方法 Linux 记录进程睡眠和执行时间 ( 存放在 task_struct 的 sleep_avg域中 ) ,范围: 0 ~ MAX_SLEEP_AVG ,默认值

为 10ms

ⅰ 当进程从开始休眠到要恢复执行这一时间内 sleep_avg

增加,直到达到MAX_SLEEP_AVG 为止;ⅱ 进程每执行一个时钟节拍, sleep_avg 递减直到 0 为止。

Linux 系统—— Linux 系统的进程调度

Page 53: 第九章   文件系统

47

③ 进程休眠时间与 bonus 值的关系 平均休眠时间 bonus值

大于或等于 0 , 小于 100ms 0

大于或等于 100 ,小于 200ms 1

大于或等于 200 ,小于 300ms 2

大于或等于 300 ,小于 400ms 3

大于或等于 400 ,小于 500ms 4

大于或等于 500 ,小于 600ms 5

大于或等于 600 ,小于 700ms 6

大于或等于 700 ,小于 800ms 7

大于或等于 800 ,小于 900ms 8

大于或等于 900 ,小于 1000ms 9

大于 1s 10

Linux 系统—— Linux 系统的进程调度

Page 54: 第九章   文件系统

48

3. 3. 可变时间片可变时间片 (1) Linux(1) Linux 系统的进程调度的目标系统的进程调度的目标 ① 对交互式进程,系统提供较长的时间片 ② 调度程序根据进程的优先级动态调整分配给它的时间片

Linux 系统—— Linux 系统的进程调度

(2) (2) 时间片的计算时间片的计算① 基本时间片

静态优先级本质上决定了进程的基本时间片 (140 -静态优先级 ) ×20 若静态优先级 < 120

(140 -静态优先级 ) ×5 若静态优先级 ≥ 120

静态优先级越高 (值越小 ) ,基本时间片越长。

基本时间片 =

Page 55: 第九章   文件系统

49

表 6.6 普通进程的静态优先级和基本时间片的典型值

说明 静态优先级 nice 值 基本时间片

最高静态优先级 100 -20 800ms

高静态优先级 110 -10 600ms

缺省静态优先级 120 0 100ms

低静态优先级 130 +10 50ms

最低静态优先级 139 +19 5ms

初始创建的进程 父进程的值 父进程的值 父进程的一半

Linux 系统—— Linux 系统的进程调度

更高的优先级

更高的交互性

更低的优先级

更低的交互性

最小5ms

默认100ms

最大800ms

进程静态优先级与基本时间片的关系图

Page 56: 第九章   文件系统

50

(3) (3) 时间片处理的时机时间片处理的时机① 创建新进程时的处理

新创建的子进程和父进程均分父进程剩余的时间片 ② 进程用完时间片时的处理

ⅰ 当一个进程的时间片用完时,依任务的动态优先级重 新计算时间片;ⅱ task_timeslice() 函数为给定任务返回一个新的时间片。

Linux 系统—— Linux 系统的进程调度

② 可变时间片当一个进程的时间片用完时,根据进程的动态优先级重新计算时间片。

Page 57: 第九章   文件系统

51

(4) (4) 时间片的使用时间片的使用① 一个进程拥有的时间片可分多次使用,放弃 CPU 时进 入活动队列② 当一个进程的时间片耗尽时,认为是过期进程,进入过 期队列

Linux 系统—— Linux 系统的进程调度

Page 58: 第九章   文件系统

52

(5) (5) 活动队列和过期队列活动队列和过期队列 每个处理器维护两个优先级数组—— 活动数组和过期数组

① 活动数组上的可执行队列中的进程都有剩余时间片

② 过期数组上的可执行队列中的进程都已耗尽时间片 当一个进程的时间片耗尽时,被移至过期队列中; 当活动数组上的可执行队列中的所有进程都已耗尽时时间 片,这时,在活动数组和过期数组之间切换指针。

Linux 系统—— Linux 系统的进程调度

Page 59: 第九章   文件系统

53

4. Linux4. Linux 进程调度算法中使用的数据结构进程调度算法中使用的数据结构 (1) (1) 可执行队列 可执行队列 (runqueue(runqueue 结构结构 ))

可执行队列是给定处理机上的可执行进程链表runqueue 结构

类型 名称 说明

spinlock_t lock 保护进程链表的自旋锁

prio_array_t *active 指向活动进程链表的指针

prio_array_t *expired 指向过期进程链表的指针

prio_array_t[2] arrays 活动进程和过期进程的两个集合

Linux 系统—— Linux 系统的进程调度

Page 60: 第九章   文件系统

54

(2) (2) 优先级数组优先级数组 优先级数组是 prio_array 类型的结构体,该数组描述了可 运行进程的集合,包括

① 140 个双向链表头 ( 每个链表对应一个优先级队列 )

② 一个进程优先级位图

③ 该数组所包含的进程总数 struct prio_array {

int nr_active; /* 任务数目 */

unsigned bitmap[BITMAP_SIZE]; /* 优先级位图 */

struct list_head queue[MAX_PRIO]; /*优先级队列 */

}

Linux 系统—— Linux 系统的进程调度

Page 61: 第九章   文件系统

55

④ 优先级数组图示

*active

*expired

arrays[0]

arrays[1]

task

task

优先级 0

优先级 139

task

task

优先级 0

优先级 139

过期进程数组

活动进程数组

runqueue 结构中的两个进程数组

Linux 系统—— Linux 系统的进程调度

Page 62: 第九章   文件系统

56

⑤ ⑤ 优先级位图的处理 ⅰ 初始时,所有位被置为 0 ; ⅱ 当某个拥有一确定优先级的进程准备运行时 ( 状态为 TASK_RUNNING) ,位图中相应位置 1 ; ⅲ 调度时,查找系统中优线级最高的进程就转化为查找 位图中被置为 1 的第一个位。 由于优先级个数是定值,所以查找时间恒定,不受系统 中可执行进程数目的影响,使 Linux 系统的进程调度算 法具有 O(1) 的算法复杂度。

Linux 系统—— Linux 系统的进程调度

Page 63: 第九章   文件系统

57

5. Linux5. Linux 进程调度程序进程调度程序 scheduler( )scheduler( )

(1) (1) 调度时机调度时机① 当进程要休眠时② 当进程被抢占时③ 系统发生抢占时

(2) (2) 进程调度程序的主要工作进程调度程序的主要工作① 在活动优先级数组中找到第一个被设置的位;② 选择该优先级链表里的第一个进程;③ 调上下文切换函数 context_switch( ) 。

Linux 系统—— Linux 系统的进程调度

Page 64: 第九章   文件系统

58

(3) Linux O(1)(3) Linux O(1) 级进程调度图解级进程调度图解

位 9 进程链表

优先级位图

0 1 0

1

9

位 6

位 9

位13

位 6 进程链表

位 130 进程链表

位 130

LinuxO(1) 级进程调度算法图解

Linux 系统—— Linux 系统的进程调度

Page 65: 第九章   文件系统

Linux 系统的存储管理

Linux 系统—— Linux 系统的存储管理

Page 66: 第九章   文件系统

59

1. Linux1. Linux 系统段页式地址变换系统段页式地址变换 (1) Linux(1) Linux 系统的分段系统的分段

Linux 系统处在用户态时,使用用户代码段和用户数据

段来对指令和数据寻址

在核态时,使用内核代码段和内核数据段来对指令和

数据寻址

每个分段是一个连续的线性地址空间,从 0 开始直到

232−1 的寻址长度。

Linux 系统—— Linux 系统的存储管理

Page 67: 第九章   文件系统

60

(2) 80x86(2) 80x86 分页结构 分页结构 80x86微处理器的分页单元处理 4KB 的页。一个 32 位的

线 性地址分为 3 个域。

页目录 页表 页内位移

31 22 21 12 11 0

ⅰ 页目录字段指向页目录项;

ⅱ 页表字段指向进程的一个页表项;

ⅲ 页内位移则是页内偏移量

80X86 分页机构

Linux 系统—— Linux 系统的存储管理

Page 68: 第九章   文件系统

61

(3) (3) 三级页表 三级页表 ① 第一级 —— 全局目录 (PGD)

PGD 中的表项指向页目录中的一个表项

② 二级页表 —— 页目录 (PMD)

PMD 中的表项指向页表 PTE 中的一个表项

③ 三级 —— 页表

该表项指向物理页 (页框 ) 的主存地址

Linux 系统—— Linux 系统的存储管理

Page 69: 第九章   文件系统

62

(4) (4) 线性地址转换为物理地址线性地址转换为物理地址① 地址转换过程 Linux 系统通过三级页表完成线性地址到物理地址的转换

页目录 页表 页内位移

31 22 21 12 11 0

cr3

+

+

页目录表页表

物理页+

+

+

由线性地址转换为物理地址

Linux 系统—— Linux 系统的存储管理

Page 70: 第九章   文件系统

63

② 地址变换步骤 ⅰ 由 cr3指示的当前页目录的物理地址与分页结构中的页 目录字段的内容相加指向页目录表项;

ⅱ 由页目录表项内容得到当前使用的页表的始地址,通过 分页结构中的页表字段的内容找到该页表项; ⅲ 由页表项指示的该页的物理页 (页框 ) 的主存地址与分页

结构中的页内位移相加,得到最终的物理地址。

Linux 系统—— Linux 系统的存储管理

Page 71: 第九章   文件系统

64

2. Linux2. Linux 系统动态内核管理系统动态内核管理 (1) (1) 物理页的描述物理页的描述① Linux 系统主存分配的基本单位是物理页 (又称为页框 )

② 主存管理单元MMU 以页为单位进行分配和处理 ③ 32 位体系结构支持 4KB 的页, 64 位体系结构支持 8KB

的页④ 内核用 struct page 结构描述页框 struct page {

flags; /* 页的状态 */

_count; /* 该页被引用的次数 */

*virtual; /* 页的虚拟地址,记录页在虚拟主存中的地址 */

};

Linux 系统—— Linux 系统的存储管理

Page 72: 第九章   文件系统

65

(2) (2) 物理主存分区物理主存分区 内核将系统中的所有页框划分为不同的区,具有相似特 征的页框归为同一个分区。 Linux 系统共分为三种分区① ZONE_DMA

这个分区包含的页只能用来执行 DMA 操作,大小为 16MB ; ② ZONE_NORMAL

这个分区包含的页都是能正常映射的页,大小为 16MB 896MB

③ ZONE_HIGHMEM

这个分区包含的是“高端主存”,其中的物理页并不能永久地映射到内

核地址空间,大小为 896MB 。

Linux 系统—— Linux 系统的存储管理

Page 73: 第九章   文件系统

66

(3) (3) 分区页框的分配 分区页框的分配 ① Linux 内核通过页框和区对主存进行管理,实现了请求

主存的底层机制;

② 内核提供提供一组访问接口 ( 函数或宏 ) 可以直接的方

式获得动态主存,注意这种方式只能由内核使用。

Linux 系统—— Linux 系统的存储管理

Page 74: 第九章   文件系统

67

(4) (4) 分区页框分配器 分区页框分配器 ① 分区页框分配器 ( Zoned page frame allocator) 是一个内 核子系统,它负责对连续页框的主存分配。 ② 分区页框分配器的组成如下图

分区页框分配器的组成

Linux 系统—— Linux 系统的存储管理

管理区分配器

每 CPU页框 高速缓存

每 CPU页框 高速缓存

每 CPU页框 高速缓存

伙伴系统 伙伴系统 伙伴系统

ZONE_DMA

主存管理区 ZONE_NORMAL

主存管理区 ZONE_HIGHMEM

主存管理区

Page 75: 第九章   文件系统

68

(5) (5) 伙伴系统算法 伙伴系统算法 ① 主存管理中的外碎片问题

ⅰ 当频繁地请求和释放不同大小的连续页框,就会导致在已分配页

框内产生许多小的、分散的空闲页框;

ⅱ Linux 系统采用伙伴系统算法记录当前空闲的连续页框块的情况,

以尽量避免为满足小块的请求而分割大的空闲块。

② 伙伴系统算法中页框的组织ⅰ 将所有的空闲页框分组为 11 个块链表;

ⅱ 每个块链表分别包含大小为 1 、 2 、 4 、 8 、 16 、 32 、 64 、 1

28 、 256 、

512 、 1024 个连续页框;

ⅲ 每个块的第一个页框的物理地址是该块大小的整数倍。

Linux 系统—— Linux 系统的存储管理

Page 76: 第九章   文件系统

69

(6) (6) 页框的分配过程页框的分配过程 以分配 256 个页框的块为例说明伙伴系统算法的页框的 分配过程 ① 首先在 256 个页框的链表中检查是否有空闲块满足需要; ② 若没有,则在 512 个页框的链表中找满足需要的空闲块 ⅰ 若存在这样的块,算法将这 512 的页框分为 2 半; ⅱ 一半用来满足请求,另一半插入到 256 个页框的链表中;③ 若还没有,则在 1024 个页框的链表中找满足需要的空闲块;

ⅰ 若存在,则将 256块用来满足要求,其余部分分为 256

块 和 512块分别插入到相应的链表中;

ⅱ 若不存在;算法放弃并给出不能满足分配的信息。

Linux 系统—— Linux 系统的存储管理

Page 77: 第九章   文件系统

70

(7) (7) 页框的释放过程页框的释放过程 分配过程的逆过程就是页框的释放过程

① 内核试图将大小为 b 的一对空闲伙伴块合并为一个大小为

2b 的单独块。满足以下条件的两个块称为伙伴:

ⅰ 两个块的大小相同,记为 b ;

ⅱ 它们的物理地址是连续的;

ⅲ 第一块的第一个页框的物理地址是 2×b×212 的倍数。

② 算法是迭代的,如果它成功合并所释放的块,它会试图

合并 2b 的块,以再次试图形成跟更大的块。

Linux 系统—— Linux 系统的存储管理

Page 78: 第九章   文件系统

71

3. Linux3. Linux 系统的进程地址空间系统的进程地址空间 Linux 内核提供用于页框分配和释放的函数 ( 或宏 ) 。这些函数只能由内

核直 接使用,用户进程请求主存时不能直接使用。 当用户进程请求动态主存时,内核采用推迟分配的方法,即用户并没有获 得请求的页框,而仅仅获得对一个新的线性地址区间的使用权。 这一线性地址区间成为进程地址空间的一部分,称为“线性区”。

(1) (1) 进程地址空间的描述进程地址空间的描述① 进程的地址空间由每个进程的线性地址区组成,是一个独 立的连续区间。② 描述进程地址空间的信息存放在主存描述符中。主存描述 符由 mm_struct 结构体表示,进程描述符的 mm 字段指向

这 个结构。

Linux 系统—— Linux 系统的存储管理

Page 79: 第九章   文件系统

72

(2) (2) 进程线性区的描述进程线性区的描述① 进程的地址空间由若干个线性区组成;

② 线性区域 (又称为主存区域 ) 用 vm_area_struct 结构体描述。

(3) (3) 主存描述符与主存区域描述符的关系主存描述符与主存区域描述符的关系① 进程地址空间可以由多个主存区域组成,描述这些主存区

域的数据结构 vm_area_struct 组成一个链表;

② mm_struct 中的 mmap指向这个链表的头结构。

Linux 系统—— Linux 系统的存储管理

Page 80: 第九章   文件系统

73

③ 主存描述符 mm_struct 和主存区域描述符 vm_area_struct ,这

两类数据结构的关系如图所示。

主存描述符、线性区描述符与进程线性地址空间

Linux 系统—— Linux 系统的存储管理

线性地址空间

主存线性区域 vm_area_struct 结构

主存描述符mm_struct 结构

mmap

Page 81: 第九章   文件系统

Linux 系统的设备驱动

Linux 系统—— Linux 系统的设备驱动

Page 82: 第九章   文件系统

74

1. Linux1. Linux 系统设备的分类系统设备的分类 (1) (1) 字符设备字符设备

字符设备是能够像字符流的方式被有序访问的设备。 这类设备以字节为单位进行数据处理。

(2) (2) 块设备块设备 块设备是能随机访问固定大小数据 (又称为块 ) 的设备。 常见的块设备有硬盘、软盘驱动器、 CD-ROM 驱动器和闪

存等。 块设备以块为单位进行处理,大多数块设备采用缓冲技术。

Linux 系统—— Linux 系统的设备驱动

Page 83: 第九章   文件系统

75

2. 2. 设备文件及标识设备文件及标识 (1) (1) 设备文件设备文件

Linux 系统将设备称为设备特殊文件,是文件类型的一种。

(2) (2) 主、次设备号主、次设备号 在 Linux 系统中描述文件的数据结构称为文件索引节点。

设备特殊文件的索引节点包含硬件设备的一个标识符,该

标识符对应字符设备或块设备。

Linux 系统—— Linux 系统的设备驱动

Page 84: 第九章   文件系统

76

① 主设备号ⅰ 主设备号标识设备的类型。ⅱ 具有相同主设备号 ( 即类型一样 ) 的所有设备共享相同

的 文件操作集合。

② 次设备号ⅰ 次设备号标识主设备号相同的一组设备中的一个特定的 设备。ⅱ 如由相同的磁盘控制器管理的一组磁盘,具有相同的主 设备号和不同的次设备号。

Linux 系统—— Linux 系统的设备驱动

Page 85: 第九章   文件系统

77

(3) VFS(3) VFS 对设备文件的处理 对设备文件的处理 ① 虚拟文件系统 VFS (Virtual Filesystem) 负责处理与 UNIX

标 准文件系统相关的所有系统调用,为各种文件系统提供一 个通用的接口。② VFS 在打开设备文件时改变缺省的文件操作。它将缺省的 文件操作 (f_op ) 字段改变为块设备 ( 或字符设备 ) 的文件

操 作表 (def_bik_fops) 的地址 。③ 对设备文件的每次系统调用都将转换成与设备相关的操作 函数调用。④ 当与设备相关的操作函数被调用后,就可以对硬件设备进 行操作,以完成进程所请求的 I/O 传输。

Linux 系统—— Linux 系统的设备驱动

Page 86: 第九章   文件系统

78

缺省的块设备文件操作表 def_bik_fops 表

方法 用于块设备文件的函数

open blkdev_open()

release blkdev_close()

llseek blkdev_llseek()

read generic_file_read()

write blkdev_file_write()

块设备文件操作表

Linux 系统—— Linux 系统的设备驱动

Page 87: 第九章   文件系统

79

3. Linux3. Linux 块设备的处理块设备的处理 (1) (1) 块设备处理中内核组件之间的关系块设备处理中内核组件之间的关系

虚拟文件系统 VFS

磁盘高速缓存

文件系统映射层

通用块层

I/O 调度程序

块设备驱动程序

块设备驱动程序

磁盘 磁盘

块设备驱动程序涉及的内核组件

Linux 系统—— Linux 系统的设备驱动

Page 88: 第九章   文件系统

80

(2) (2) 以进程的以进程的 read()read() 系统调用为例,分析内核组件的 系统调用为例,分析内核组件的 调用过程调用过程

① 在读操作之前,相应的设备文件已打开;② VFS 通过块设备文件操作表调用适当的 VFS 函数,传递的 参数是:文件描述符、文件的偏移量;③ VFS 相应的函数首先访问磁盘高速缓存,若所需数据在高 缓存中,不必启动磁盘读操作;否则启动磁盘读操作。假 定为后者;④ 在磁盘文件系统映射层,计算请求数据的逻辑块号,根据 该文件的索引节点中的索引结构确定该逻辑块号对应的磁 盘物理块号。然后,对块设备发出读请求;

Linux 系统—— Linux 系统的设备驱动

Page 89: 第九章   文件系统

81

⑤ 通用块层接收到所需数据所在的磁盘块号、操作类型,给

I/O 调度程序发出启动磁盘读操作的命令;

⑥ I/O 调度程序根据预先定义好的 I/O 调度策略,将待处理的

I/O 数据传送请求进行归类。其目的是尽量将在磁盘上物

理介质相邻的数据请求聚集在一起,以使 I/O 处理的效率最

高;

⑦ 最后,块设备驱动程序向磁盘控制器的硬件接口发出设备

启动命令,从而进行实际的数据传送。

Linux 系统—— Linux 系统的设备驱动

Page 90: 第九章   文件系统

82

4. 4. 用于块设备处理的数据结构用于块设备处理的数据结构 设备驱动程序涉及的数据结构有设备请求队列和 bio请求块。

(1) bio(1) bio 结构结构① bio 是描述块设备 I/O 操作的描述符 ⅰ 包括一个磁盘存储区标识符 ( 存储区的起始扇区号和扇区总数 ) ; ⅱ 一个或多个描述与 I/O 操作相关的主存区的段。

② bio 结构以片段为单位的链表形式来组织块 I/O 操作

ⅰ 一个片段是一小块连续的主存。当缓冲区分散在主存的多个位置

时, bio 结构体也能对内核保证 I/O 操作的执行。

ⅱ 在 bio 结构体中有几个相关的域 bi_io_vec 、 bi_vcnt 和 bi_idx 。

Linux 系统—— Linux 系统的设备驱动

Page 91: 第九章   文件系统

83

③ bi_io_vec 、 bi_vcnt 和 bi_idx

ⅰ bi_io_vec域指向一个 bio_vec 数组

该数组包含了提供特定 I/ O 操作所需要使用到的所有片

段。

ⅱ 在指定的 I/ O 操作中, bi_vcnt域用来描述 bi_io_vec 所指

向的 bio_vec 数组中的向量数目。

ⅲ 当块 I/O 操作执行完毕后, bi_idx域指向数组的当前索引。

Linux 系统—— Linux 系统的设备驱动

Page 92: 第九章   文件系统

84

④ bio 结构、 bio_vec 结构数组和 page 结构之间的关系

bio_vec 结构数组 总数为 bi_vcnt

bio_idxbio_io_vec

bio_vec bio_vec bio_vec bio_vec

页面

页面

页面

页面

ⅰ I/O 操作的第一个片段由 bio 结构中的 bio_io_vec 字段所指向,其他的

片段在其后依次存放,共有 bi_vcnt 个片段;ⅱ 当 I/O 操作开始执行时,使用着各个片段,这时, bi_idx域会不断

地 更新,它总是指向正在操作的当前片段。

bio 结构、 bio_vec 结构数组和 page 结构之间的关系

Linux 系统—— Linux 系统的设备驱动

Page 93: 第九章   文件系统

85

(2) (2) 设备队列和请求描述符设备队列和请求描述符① 设备请求队列 设备请求队列是一个双向链表,包含待处理的请求,由 request_queue 结构描述。

② 请求描述符

请求描述符 request 描述每个块设备待处理的请求。

Linux 系统—— Linux 系统的设备驱动

Page 94: 第九章   文件系统

86

字段 说明queue_head 待处理请求的链表request_fn 实现驱动程序的策略例程入口点的方法back_marge_fn 检查是否可能将 bio合并到请求队列的最后一个请求中

的方法front_marge_fn 检查是否可能将 bio合并到请求队列的第一个请求中的

方法marge_requests_fn 合并请求队列中两个相邻请求的方法make_request_fn 将一个新请求插入到请求队列时调用的方法prep_rq_fn 将处理请求的命令发送给硬件设备的方法queue_flags 描述请求队列状态的标志

request_queue 结构的字段request_queue 结构的字段

Linux 系统—— Linux 系统的设备驱动

Page 95: 第九章   文件系统

87

③ 一个新请求加入设备请求队列时的操作

ⅰ 若队列中存在一个与新请求的磁盘扇区相邻的请求,则

将新请求与这个已存在的请求合并成为一个请求;

ⅱ 若无相邻的请求,新请求插入到按扇区递增的合适的位

置;

ⅲ 如果队列中不存在该请求合适的插入位置,新请求被插

入到队列的尾部;

ⅳ 如果队列中存在一个驻留时间过长的请求,那么新请求

插入到队尾,以防止旧请求发生饥饿。

Linux 系统—— Linux 系统的设备驱动

Page 96: 第九章   文件系统

88

5. 5. 输入输入 // 输出调度程序输出调度程序 (1) (1) 输入输入 //输出调度程序的工作输出调度程序的工作

I/O 调度程序的主要工作是管理块设备请求队列,延迟激活

块设备驱动程序,对队列中的请求进行排序,以减少磁盘 寻址时间。

(2) (2) 合并与排序合并与排序① 合并 将两个或多个 I/O请求结合成一个新请求称为合并,使新请

求只对一个或多个相邻的磁盘扇区进行操作。 ② 排序 将设备请求队列按磁盘扇区增长的方向排序,使磁头可以 按其前进方向上移动,这样就缩短了系统对所有 I/O请求

处 理的总时间 。

Linux 系统—— Linux 系统的设备驱动

Page 97: 第九章   文件系统

89

(3) (3) 电梯调度电梯调度① 电梯调度算法 是从当前 I/O请求的磁盘位置开始,沿着臂的移动方向将请求按磁盘

扇区的顺序排序,总是选择离当前位置最近的那个 I/O请求,如果在 磁盘移动方向上无请求访问时,就改变移动方向再选择。

② 新请求加入设备队列时的操作 ⅰ 如果队列中已存在一个与新请求的磁盘扇区相邻的请求,那么,将

新请求与这个已存在的请求合并成为一个请求;

ⅱ 如果没有相邻的请求,新请求插入到按扇区递增的合适的位置,以

保证队列中的请求是以被访问的磁盘位置为序来排序的;

ⅲ 如果队列中不存在该请求合适的插入位置,新请求被插入到队列的

尾部。

Linux 系统—— Linux 系统的设备驱动

Page 98: 第九章   文件系统

90

6. 6. 策略例程 策略例程 (1) (1) 什么是策略例程 什么是策略例程

① 设备驱动程序包含一个函数或一组函数,这些函数称为

策略例程;

② 策略例程与设备控制器一起来处理设备请求队列的 I/O

求。

(2) (2) 策略例程的调用 策略例程的调用 I/O 调度程序通过请求队列描述符中的 requst_fn方法来

用策略例程,并将请求队列描述符的地址传递该该例程。

Linux 系统—— Linux 系统的设备驱动

Page 99: 第九章   文件系统

91

(3) (3) 策略例程处理策略例程处理 I/OI/O请求的方法 请求的方法 ① 一种简单的方式

策略例程等待直到数据传送完成,然后将已经处理过的

I/O请求从队列中删除,继续处理下一个请求,直到队列

为空才结束。

② 另一个处理方式是中断方式

其处理效率高,为许多现代设备驱动程序所采用。

Linux 系统—— Linux 系统的设备驱动

Page 100: 第九章   文件系统

92

(4) (4) 在中断方式下,通用块层、在中断方式下,通用块层、 I/OI/O 调度程序、设备调度程序、设备驱驱

动程序的策略例程和中断处理程序之间的关系动程序的策略例程和中断处理程序之间的关系① 通用块层将一个 I/O 操作请求发送给 I/O 调度程序;② I/O 调度程序在相应的块设备请求队列上进行处理,产生 一个新请求或扩展一个已有的请求,然后终止;③ 块设备队列若为空,当加入一个新请求时块设备驱动程序 被激活;否则,会一个接一个地处理请求队列上的每一个 请求。设备驱动程序调用策略例程,选择一个待处理的请 求,设置磁盘控制器,以便在数据传送完成时产生一个中 断,然后策略例程终止;

Linux 系统—— Linux 系统的设备驱动

Page 101: 第九章   文件系统

93

④ 当磁盘控制器产生中断时,在该设备对应的中断处理程序

会重新调用策略例程。这时,策略例程可能处理以下两

种情况之一:

ⅰ 当前请求的所有数据块已经传送完成,则将该请求从

设备请求队列中删除,然后开始处理下一个请求;

ⅱ 当前请求的所有数据块还没有传送完成,则为当前请

求再启动一次数据传送,这通常称为中断驱动。

Linux 系统—— Linux 系统的设备驱动

Page 102: 第九章   文件系统

Linux 文件系统

Linux 系统—— Linux 文件系统

Page 103: 第九章   文件系统

94

1. 1. 虚拟文件系统虚拟文件系统 (VFS)(VFS) 概述概述 (1) (1) 什么是虚拟文件系统什么是虚拟文件系统 虚拟文件系统也称为虚拟文件系统转换,它是一个内核软件层,用 来处理与 UNIX 标准文件系统相关的所有系统调用。

(2) (2) 虚拟文件系统支持的文件类型虚拟文件系统支持的文件类型① 磁盘文件系统

ⅰ 磁盘文件系统管理本地磁盘分区中可用的存储空间或者其它可以 起到磁盘作用的设备 ( 如 USB闪存 ) 。。ⅱ Linux 使用的文件系统,如 Ext2 、 Ext3 和 Reiser 文件系统;ⅲ UNIX家族的文件系统,如 SystemⅤ文件系统、 USF 、 MINIX 文

件 系统以及 ScoUnix Ware ;ⅳ 微软公司的文件系统,如 MS-DOS 、 VFAT及 NTFS 。

Linux 系统—— Linux 文件系统

Page 104: 第九章   文件系统

95

② 网络文件系统ⅰ 网络文件系统支持对其他网络计算机上文件系统包含 文件的访问。ⅱ 虚拟文件系统支持的网络文件系统有 NFS 、 AFS 、 CI

FS

等。

③ 特殊文件系统ⅰ 特殊文件系统不管本地或远程磁盘空间,包含操作系统 内核的数据结构,它提供一种便利的方式让系统程序员 可以访问这些 数据结构 。ⅱ 其例子是 /proc 文件系统。

文件系统—— Linux 文件系统

Page 105: 第九章   文件系统

96

2. VFS2. VFS 通用文件系统模型与通用文件系统模型与 VFSVFS对象对象 (1) VFS(1) VFS 通用文件系统模型通用文件系统模型① VFS提供了一个通用的文件系统模型 该模型包括了所有不同类型的文件系统常用的功能和操 作,它定义了所有文件系统都支持的基本的、概念上的 接口和数据结构。② VFS提供了一个抽象层 该抽象层提供的统一接口隐藏了实际文件系统的具体的 实现细节。

文件系统—— Linux 文件系统

Page 106: 第九章   文件系统

97

③ VFS 使用的例用户程序中的写操作的实施过程

一个用户程序中的写操作请求通过 VFS 的映射、实际文件 系统的具体实施,最终将信息写到物理介质上。

文件系统—— Linux 文件系统

write();

用户程序

sys_write() 文件系统写方法

VFS虚拟文件系统 具体文件系统 如 Ext2

物理存储介质

一个用户程序写操作的实现步骤

Page 107: 第九章   文件系统

98

(2) VFS(2) VFS 对象类型对象类型① 超级块对象 (superblock object)

代表已安装的文件系统,存放已安装文件系统的所有信息。

② 索引节点对象 (inode object)

代表一个文件,描述一个具体文件的所有信息。

③ 目录项对象 (dentry object)

代表一个目录项,是路径名的一个组成部分 。

④ 文件对象 (file object)

它代表由进程打开的文件。

文件系统—— Linux 文件系统

Page 108: 第九章   文件系统

99

3. 3. 与进程相关的数据结构与进程相关的数据结构 每个进程都有当前目录 ( 或根目录 ) ,进程活动期间都要打开各种文件。 Linux 系统使用 fs_struct 和 file_struct 结构体描述以上信息。

(1) fs_struct(1) fs_struct 结构体结构体① 描述进程的当前目录 ( 或根目录 ) 的信息;

② 每个进程描述符的 fs 字段就指向该进程的 fs_struct 结构体

文件系统—— Linux 文件系统

fs_struct结构的主要字段

字 段 说 明count 共享此结构的进程个数*root 根目录的目录项对象*pwd 当前工作目录的目录项对象*rootmut 根目录所安装的文件系统对象*pwdmut 当前工作目录所安装的文件系统对象

Page 109: 第九章   文件系统

100

(2) file_struct(2) file_struct 结构体结构体① 描述与每个进程所有相关的信息,如打开的文件及文件描 述符等; ② 该结构的地址存放在进程描述符的 file 字段中。

文件系统—— Linux 文件系统

fs_struct结构的主要字段

字 段 说 明count 共享此结构的进程个数max_fds 文件对象当前的最大数目**fd 指向文件对象指针数组的指针*close_on_exec 指向执行 exec() 时需要关闭的文件描述符的指针*open_fds 指向打开文件描述符的指针*fd_array 文件对象指针的初始化数组

Page 110: 第九章   文件系统

4. VFS4. VFS 系统调用的实现系统调用的实现 (1) (1) 路径名的查找路径名的查找 路径名查找的实质是从文件路径名查找相应的索引节点。

① 若路径名的第一个字符是“ /” ,那么这个路径名是绝对路径,因此从 current→fs→root ( 进程的根目录 ) 所标识的目录开始搜寻;否则路径名是相对路径,因此应从 current→fs→pwd ( 进程的当前目录 )

所标识的目录开始搜寻;

② 内核检查与第一个名字匹配的目录项,以获得相应的索引节点,然后从磁盘中读出索引节点的目录文件;

③ 然后,检查与与第二个名字匹配的目录项,以获得相应的索引节点。对于包含在路径名中的每一个名字,这个过程反复执行。

④ Linux 系统使用了目录项高速缓存,以加快路径名查找的速度。

文件系统—— Linux 文件系统

101

Page 111: 第九章   文件系统

(2) open( )(2) open( ) 系统调用的实现 系统调用的实现 ① 调用形式

open() 系统调用的服务例程为 sys_open() 函数,该函数接受

的参数: filename :要打开的文件路径名

fiags :访问模式的标志

mode :该文件被创建时所需要的许可权

若该系统调用成功,返回文件描述符 ( 即为 fd 表中的索引号 ) ;

否则返回− 1 。

文件系统—— Linux 文件系统

102

Page 112: 第九章   文件系统

② sys_open() 函数的主要工作 ⅰ 调用 getname() 函数,从进程地址空间中读取文件路径名; ⅱ 在 current→file→fd 中查找一个空位置,获得在 fd 表中的索引号,

即 为该打开文件的描述符; ⅲ 调用 file_open() 函数,传递参数,包括路径名、访问模式标志、许 可权位掩码,检查操作的合法性,并设置相应的标志;

分配一个新的文件对象,设置相应的 f_flags 和 f_mode 字段; 将 f_op 字段设置为相应索引节点对象 i_fop 字段的内容,为进一步的文件操作建立所有的方法; 返回文件对象地址;

ⅳ 调用 getname() 函数,从进程地址空间中读取文件路径名; ⅴ 将 current→file→fd[fd]置为返回的文件对象的地址; ⅵ 返回 fd ( 文件描述符 ) 。

文件系统—— Linux 文件系统

103

Page 113: 第九章   文件系统

(3) read( )(3) read( ) 和和 write()write() 系统调用的实现 系统调用的实现 ① 调用形式

read( ) 和 write() 系统调用非常相似,所需参数都为 3 : fd : 文件描述符;

buf : 主存区地址,该缓存区包含要传送的数据;

count :指定的应传送的字节数。

返回:成功传送的字节数;或发送一个错误条件的信号并返回− 1 。

② read( ) 系统调用的访问例程称为 sys_read()

③ write() 系统调用的访问例程称为 sys_write()

这两个系统调用几乎执行相同的步骤

文件系统—— Linux 文件系统

104

Page 114: 第九章   文件系统

5. Ext25. Ext2 文件系统概述文件系统概述 Ext2 是 Linux 系统所固有的,它运行稳定且高效。

(1) Ext2(1) Ext2 文件系统的特征文件系统的特征① 可选择最佳块大小,提高系统性能

ⅰ 块大小可以从 1024B到 4096B 字节之间选择;

ⅱ 根据预测的文件平均长度来选择最佳块大小,可以减

少磁盘传送次数,从而减轻系统开销。

文件系统—— Linux 文件系统

105

Page 115: 第九章   文件系统

② 可选择分区上的索引节点数,有效地利用磁盘空间

根据给定的分区大小来预测可存放的文件数,以此来确定

该分区上可分配的索引节点数。这样可以有效地利用磁盘

空间 。

③ 以块组结构减少磁盘的平均寻道时间

Ext2 文件系统将磁盘块分组,每组包含存放在相邻磁道上

的数据块和索引节点。这种块组结构使得对存放在一个单

独块组中的文件进行访问时,减少了磁盘的平均寻道时间。

文件系统—— Linux 文件系统

106

Page 116: 第九章   文件系统

(2) Ext2(2) Ext2 文件类型文件类型 Ext2 文件类型如下表所示

文件系统—— Linux 文件系统

Ext2文件类型

文件类型 说 明

0 未知1 普通文件2 目录3 字符设备文件4 块设备文件5 命名管道6 套接字7 符号链接

107

Page 117: 第九章   文件系统

108

① 普通文件

普通文件是最常见的,它在刚创建时是空白的,并不需

要磁盘数据块,只有在开始有数据时才分配数据块。

② 目录文件

ⅰ 目录文件是一种特殊文件,它由 Ext2目录项组成;

ⅱ Ext2目录项是一个类型为 ext2_dir_extry_2 的结构,它

将文件名和索引节点号存放在一起。

ⅲ ext2_dir_extry_2 结构的主要字段和说明如下表所示。

文件系统—— Linux 文件系统

Page 118: 第九章   文件系统

③ 设备文件、命名管道文件和套接字 这类文件不需要数据块,所有必要的信息都存放在索引节点中。

④ 符号链接 当符号链接的路径名小于 60 个字符时,它就存放在索引节点上的 i_blocks 字段中,这样就不需要数据块。

文件系统—— Linux 文件系统ext2_dir_extry_2的结构

文件类型 说 明inode 索引节点号rec_len 目录项长度name_len 文件名长度file_type 文件类型name 文件名

109

Page 119: 第九章   文件系统

6. Ext26. Ext2 磁盘数据结构磁盘数据结构 (1) Ext2(1) Ext2 文件系统在磁盘上的分布 文件系统在磁盘上的分布

① 磁盘的第一块为引导扇区,包括一个分区表和初始引导程

序,用来引导操作系统;

② 磁盘的其余部分分成为块组,从块组 0到块组 n ,所有块组

大小相同并顺序存放。

③ Ext2 文件系统在磁盘上的分布如下图所示。

文件系统—— Linux 文件系统

110

Page 120: 第九章   文件系统

Ext2 文件系统在磁盘上的分布

文件系统—— Linux 文件系统

数据块位图

一个块

引导块 块号 0 块号 1 块号 n

超级块 组描述符 索引节点位图

索引节点表 数据块

n 个块 一个块 一个块 n 个块 n 个块

一个磁盘上可建立多少个块组决定于分区的大小和块的 大小,主要限制在于数据块位图。

数据块位图用来标识一个组中块的占用 / 空闲状况,并存 放在一个单独的块中。

Ext2 分区和块组的分布图

112

Page 121: 第九章   文件系统

(2) Ext2(2) Ext2 磁盘块组结构磁盘块组结构 Ext2磁盘块组包括超级块、组描述符、数据块位图、索引节点位

图、索引节点表和数据块。

① 超级块每个块组中的超级块存放在一个称为 ext2_super_block 的结构中。

② 组描述符每个块组都包含一个组描述符,它是一个 ext2_group_desc 结构。

③ 索引节点表 索引节点表由若干个连续的块组成,索引节点表的第一块的块号

存放在组描述符的 bg_inode_table 字段中。

文件系统—— Linux 文件系统

113

Page 122: 第九章   文件系统

7. Ext27. Ext2 磁盘空间管理磁盘空间管理 (1) (1) 从文件的偏移量从文件的偏移量 f f 确定相应数据块在磁盘上的块确定相应数据块在磁盘上的块

号需要的操作号需要的操作

① 从偏移量 f导出文件的逻辑块号 (逻辑记录 )

f/ 文件系统的逻辑块大小 ( 结果取整 )

② 将文件的逻辑块号 (逻辑记录 )转化为相应的磁盘块号ⅰ 磁盘索引节点上的 i_block 字段包含 Ext2_n_blocks ( 通常为 15) 个指

针元素,这些元素中包含已分配给文件的磁盘块号。

ⅱ 在 Linux 系统中,这 15 个元素组成的数组按如下方式使用

0 11 用作直接索引; 12 用作一级间接索引;

13 用作二级间接索引; 14 用作三级间接索引。

文件系统—— Linux 文件系统

114

Page 123: 第九章   文件系统

(2) Ext2(2) Ext2 文件系统的索引结构 文件系统的索引结构 ① 直接索引

ⅰ 0 11 个数组单元内存放的是文件的逻辑记录所在的磁盘块号;

ⅱ 直接索引可登记逻辑记录号从 0到 11范围内的映射关系。

② 一级间接索引 ⅰ 第 12 个数组单元内存放的是一级间接索引表所占用的磁盘块号;

ⅱ 一级间接索引表中每一个表项的内容是文件的逻辑记录所在的磁盘

块号。

ⅲ 设 b = 4KB (磁盘块的大小 ) ,每个逻辑记录号占 4B 字节,这样一个

磁盘块用作索引表时,可有 n 个表项: n = b/4 = 1K 个;

ⅳ 可登记逻辑记录号从 12 (b/4+11) 范围内的映射关系。

文件系统—— Linux 文件系统

115

Page 124: 第九章   文件系统

③ 二级间接索引 ⅰ 第 13 个数组单元内存放的是二级间接索引表所占用的磁盘块号;

ⅱ 二级间接索引表共有 n 个表项,每一个表项都分别指向一个一级间

接索引表,即每一个表项的内容分别是各一级间接索引表所在的磁

盘块号;

ⅲ 在每个一级间接索引表中的每一个表项中存放的是逻辑记录所在的

磁盘块号。

ⅳ 二级间接索引表可有 (b/4)2 个表项;

ⅴ 可登记逻辑记录号从 (12+1024) (12+1024) +(10242−1)范围内的映

射关系。

文件系统—— Linux 文件系统

116

Page 125: 第九章   文件系统

④ 三级间接索引

ⅰ 第 14 个数组单元内存放的是三级间接索引表所占用的磁

盘块号;

ⅱ 按以上方法类推。

ⅲ 三级间接索引表可有 (b/4)3 个表项;

ⅳ 可登记逻辑记录号

(12+1024+10242) (12+1024+10242)+(10243−1)

范围内的映射关系。

文件系统—— Linux 文件系统

117

Page 126: 第九章   文件系统

⑤ Ext2 文件系统的索引结构图示

文件系统—— Linux 文件系统

一级间接索引

二级间接索引

三级间接索引

0

12

34

5

6

7

8

9

1011121314

Ext2 文件系统的索引结构

118

Page 127: 第九章   文件系统

第第 99 章 章 LinuxLinux 系统系统小结小结

Linux 系统——小结

Page 128: 第九章   文件系统

LinuxLinux 系统概述系统概述

Linux 操作系统的类型Linux 操作系统的特点

LinuxLinux 系统的特权级与中断处理系统的特权级与中断处理

Linux 系统的特权级Linux 系统中断处理区分上半部和下半部的目的上半部、下半部的主要工作和特点

LinuxLinux 系统功能调用系统功能调用

Linux 系统功能调用的过程在 Linux 系统中增加一个新的系统功能调用需做的工作 119

Linux 系统——小结

Page 129: 第九章   文件系统

LinuxLinux 系统的进程管理系统的进程管理

Linux 系统进程的状态

Linux 系统进程状态变迁图

Linux 系统进程创建的写时拷贝技术LinuxLinux 系统的进程调度系统的进程调度

Linux 系统进程调度策略、调度方式

Linux 系统动态优先级与哪些因素有关

进程的睡眠时间与动态优先级的关系

Linux 系统可变时间片与静态优先级的关系

活动进程数组与过期进程数组

Linux 系统进程调度算法的主要工作120

Linux 系统——小结

Page 130: 第九章   文件系统

LinuxLinux 系统的存储管理系统的存储管理

Linux 系统通过三级页表完成的地址转换过程Linux 系统的三种分区伙伴系统算法伙伴系统算法中页框的组织页框的分配过程页框的释放过程

Linux 系统进程地址空间的组成

121

Linux 系统——小结

Page 131: 第九章   文件系统

LinuxLinux 系统的设备驱动系统的设备驱动

Linux 系统设备的分类设备文件、主设备号、次设备号bio 结构、设备请求队列I/O 调度程序的主要工作合并、排序电梯调度算法

122

Linux 系统——小结

Page 132: 第九章   文件系统

LinuxLinux 文件系统文件系统

VFS虚拟文件系统、支持的文件系统类型

VFS 通用的文件系统模型包含的内容

fs_struct 结构体和 file_struct 结构体的作用

open( ) 系统调用的主要工作

Ext2 文件系统的特征

Ext2 的类型

Ext2 文件系统在磁盘上的分布

Ext2 文件索引结构

123

Linux 系统——小结