用户ⅣO软件 °用户进程请求读磁盘文件操作 ·用户进程使用标准C库函数 fread,或 Windows apl函数 ReadFile,或Unix/ Linux的系统调用函数read等要求读一个 磁盘文件块。 用户程序中涉及O操作的函数最终会被转换为一组与具体机器 架构相关的指令序列,这里我们将其称为o请求指令序列。 例如,若用户程序在IA-32架构上执行,则o函数被转换为 IA-32的指令序列。 ·每个指令系统中一定有一类陷阱指令(有些机器也称为软中断 指令或系统调用指令),主要功能是为操作系统提供灵活的系 统调用机制。 在/O请求指令序列中,具体I/o请求被转换为一条陷阱指令 在陷阱指令前面则是相应的系统调用参数的设置指令
用户I/O软件 ° 用户进程请求读磁盘文件操作 • 用户进程使用标准C库函数fread,或Windows API函数 ReadFile,或Unix/Linux的系统调用函数read等要求读一个 磁盘文件块。 • 用户程序中涉及I/O操作的函数最终会被转换为一组与具体机器 架构相关的指令序列,这里我们将其称为I/O请求指令序列。 • 例如,若用户程序在IA-32架构上执行,则I/O函数被转换为 IA-32的指令序列。 • 每个指令系统中一定有一类陷阱指令(有些机器也称为软中断 指令或系统调用指令),主要功能是为操作系统提供灵活的系 统调用机制。 • 在I/O请求指令序列中,具体I/O请求被转换为一条陷阱指令, 在陷阱指令前面则是相应的系统调用参数的设置指令
系统Ⅳo软件 os在I/O子系统中的重要性由O系统以下三个特性决定: (1)共享性。I/o系统被多个程序共享,须由OS对o资源统一 调度管理,以保证用户程序只能访问自己有权访问的那部分/O 设备,并使系统的吞吐率达到最佳。 (2)复杂性。I/0O设备控制细节复杂,需OS提供专门的驱动程序 进行控制,这样可对用户程序屏蔽设备控制的细节。 (3)异步性。不同设备之间速度相差较大,因而,IO设备与主 机之间的信息交换使用异步的中断/o方式,中断导致从用户态 向内核态转移,因此必须由oS提供中断服务程序来处理。 那么,如何从用户程序对应的用户 进程进入到操作系统内核执行呢? 系统调用!
系统I/O软件 OS在I/O子系统中的重要性由I/O系统以下三个特性决定: (1)共享性。I/O系统被多个程序共享,须由OS对I/O资源统一 调度管理,以保证用户程序只能访问自己有权访问的那部分I/O 设备,并使系统的吞吐率达到最佳。 (2)复杂性。I/O设备控制细节复杂,需OS提供专门的驱动程序 进行控制,这样可对用户程序屏蔽设备控制的细节。 (3)异步性。不同设备之间速度相差较大,因而,I/O设备与主 机之间的信息交换使用异步的中断I/O方式,中断导致从用户态 向内核态转移,因此必须由OS提供中断服务程序来处理。 那么,如何从用户程序对应的用户 进程进入到操作系统内核执行呢? 系统调用!
系统调用和AP oS提供一组系统调用为用户进程的I/O请求进行具体的I/o操作 应用编程接口(API)与系统调用两者在概念上不完全相同,它们都 是系统提供给用户程序使用的编程接口,但前者指的是功能更广泛、 抽象程度更高的函数,后者仅指通过软中断(自陷)指令向内核态发 出特定服务请求的函数。 °系统调用封装函数是API函数中的一种。 API函数最终通过调用系统调用实现Io。一个API可能调用多个系 统调用,不同API可能会调用同一个系统调用。但是,并不是所有 API都需要调用系统调用。 °从编程者来看,API和系统调用之间没有什么差别。 °从内核设计者来看,API和系统调用差别很大。API在用户态执行, 系统调用封装函数也在用户态执行,但具体服务例程在内核态执行
系统调用和API ° OS提供一组系统调用为用户进程的I/O请求进行具体的I/O操作。 ° 应用编程接口(API)与系统调用两者在概念上不完全相同,它们都 是系统提供给用户程序使用的编程接口,但前者指的是功能更广泛、 抽象程度更高的函数,后者仅指通过软中断(自陷)指令向内核态发 出特定服务请求的函数。 ° 系统调用封装函数是 API 函数中的一种。 ° API 函数最终通过调用系统调用实现 I/O。一个API 可能调用多个系 统调用,不同 API 可能会调用同一个系统调用。但是,并不是所有 API 都需要调用系统调用。 ° 从编程者来看,API 和 系统调用之间没有什么差别。 ° 从内核设计者来看,API 和 系统调用差别很大。API 在用户态执行, 系统调用封装函数也在用户态执行,但具体服务例程在内核态执行
系统调用及其参数传递 在用户态,当进程调用一个系统调用时,cPU切换到内核态,并 开始执行一个被称为系统调用处理程序的内核函数 例如,IA-32中,可以通过两种方式调用Lnux的系统调用 执行软中断指令int80 执行指令 sysenter(老的x86不支持该指令) °内核实现了许多系统调用,因此,用一个系统调用号(存放在 EAX中)来标识不同的系统调用 °除了调用号以外,系统调用还需要其他参数,不同系统调用所需 参数的个数和含义不同,输入参数通过通用寄存器传递,若参数 个数超出寄存器个数,则将需传递参数块所在内存区首址放在寄 存器中传递(除调用号以外,最多6个参数) 传递参数的寄存器顺序:EAX(系统调用号)、EBX、ECX EDX、ESI、ED和EBP °返回参数为整数值。正数或0表示成功,负数表示出错码
系统调用及其参数传递 ° 在用户态,当进程调用一个系统调用时,CPU切换到内核态,并 开始执行一个被称为系统调用处理程序的内核函数 ° 例如,IA-32中,可以通过两种方式调用Linux的系统调用 • 执行软中断指令int 80 • 执行指令sysenter(老的x86不支持该指令) ° 内核实现了许多系统调用,因此,用一个系统调用号(存放在 EAX中)来标识不同的系统调用 ° 除了调用号以外,系统调用还需要其他参数,不同系统调用所需 参数的个数和含义不同,输入参数通过通用寄存器传递,若参数 个数超出寄存器个数,则将需传递参数块所在内存区首址放在寄 存器中传递(除调用号以外,最多6个参数) • 传递参数的寄存器顺序:EAX(系统调用号)、EBX、ECX 、EDX、ESI、EDI和EBP ° 返回参数为整数值。正数或0表示成功,负数表示出错码
用户程序、C函数和内核 用户程序总是通过某种Io函数或Jo操作符请求/o操作。 例如,读一个磁盘文件记录时,可调用C标准I/o库函数 fread0, 也可直接调用系统调用封装函数 g reado来提出Io请求。不管是C库 函数、API函数还是系统调用封装函数,最终都通过操作系统内核提 供的系统调用来实现Io。 printf函数的调用过程如下: 运行在用户态 运行在内核态 ,,于 调用pim010库函数pi0-+封装函数wt+-i+wrte系统i调用 用户程序 C语言函数库 内核
用户程序、C函数和内核 ° 用户程序总是通过某种I/O函数或I/O操作符请求I/O操作。 例如,读一个磁盘文件记录时,可调用C标准I/O库函数fread(), 也可直接调用系统调用封装函数read()来提出I/O请求。不管是C库 函数、API函数还是系统调用封装函数,最终都通过操作系统内核提 供的系统调用来实现I/O。 printf()函数的调用过程如下: