这次介绍的是四大基本OS概念:Thread,Address Space,Process,Dual Mode Operation。这次的Note内容是对上一次Note的一些补充和扩展,比如对于Thread等概念进行了阐述。Thread在原课件中的定义是:Thread: Single unique execution context:Program Counter, Registers, Execution Flags, Stack, Memory State这里就是在描述,线程是程序执行时的上下文,它完整描述着程序的状态:Program Counter( PC )RegistersExecution FlagsStack知道上面这四样东西,就知道程序本身就正在处于什么状态。这也是为什么thread的核心不是代码本身,而是当前的执行状况。当一个thread正在某个core上执行的时候,它的状态是resident in processor registers,也就是寄存器保存了线程的根状态( 上下文 ):PC在寄存器里寄存器内容就是它的执行状态stack pointer也在寄存器里CPU正在按照这个线程的上下文执行下面这张图展现了程序执行时真正的流程Core单核跑多线程原理原理很简单,因为OS在做`Time Multiplexing #Time_Multiplexing如果我们以足够细的颗粒度来执行每个thread,就会看起来像是有很多虚拟CPU跑线程。在这个过程中也传递了PC,SP还有registers:OS 保存 vCPU1 的 PC、SP、registers 到它的 TCBOS 从 vCPU2 的 TCB 恢复 PC、SP、registersCPU 跳转到 vCPU2 的 PC 开始执行OS通过时间复用( Time Multiplexing )让多个线程轮流占用物理core,于是每个线程都看起来像有一个自己的core。需要提醒的是:thread本身就是virtual CPUTCB当thread不执行的时候,它的上下文就不会驻留在CPU里,而是保存到内存中,通常会保存在一个专门的数据结构里面:TCB = Thread Control Block这也让线程可能处于两种位置:在物理核心上执行在内存中的TCB里被保存这也是线程是虚拟CPU的根本原因Address Space在原课件中的定义是:Address space = the set of accessible addresses + associated state:32 位:2322^{32}232地址64 位:2642^{64}264地址这句话表明的是地址空间是程序能够访问的地址集合,以及与这些地址相关的状态。注意不是简单的内存区域,与地址相关的状态涉及到了:哪些地址程序能读,哪些地址程序能写对这些地址访问有什么效果典型的地址空间布局如下图所示地址空间这个概念存在的必要性,正是体现在限制程序可见和可访问的内存范围这一方面,确保每个程序只看到属于自己的那部分地址。我们先前提及到的 #Time_Multiplexing,每个vCPU都有权限访问非CPU资源,每个线程都可以读写内存,这就导致了线程很有可能篡改OS的内容?也有可能篡改别的线程的内容?我们就思考硬件该怎么帮助OS免受进程的非法篡改?这就引出了B&B,是一种限制线程访问内存权限的方法Base And Bound这是一种很基础的机制,我们有两个register,分别是base register和bound register。程序发出的地址不会直接拿去访问物理内存,而是会先检查:是否在合法范围内或者和base做转换后是否落在允许的区域内( 段基址+偏移地址 )Virtural Address Space这是一种更一般的思想:程序运行在一个和物理内存不同的地址空间里: 程序看到的是virtual address,真正访问的是physical address,中间要经过translation这带来了两个巨大好处:程序看不到不该看的内存程序不再需要连续放在物理内存里Paged Virtual Address Space这是一种分页思想,把整个虚拟地址空间分成固定大小的块,同时把整个物理内存也切成同样大小的块,然后由硬件通过page table完成映射。需要注意的是:每个 virtual page 可以映射到任意 physical frame页面大小固定,管理更方便如果某页不在内存里,访问会触发page fault其中虚拟地址可以看成<Page #> + <Page Offset>,其中<Page #>用来查page table,<Page Offset>直接保留,最后组合出了真实的physical address这是进程隔离最重要的底层机制之一Process原课件的定义:execution environment with Restricted Rights(Protected)Address Space with One or More ThreadsOwns memory(address space)Owns file descriptors, file system context, …Encapsulate one or more threads sharing process resources为什么需要Process这个定义?Process彼此隔离OS也需要被保护进程提供内存保护边界还需要注意的一点是进程内通信容易,进程间通信更难,原因也很简单:同一进程的多个线程共享很多资源;不同进程彼此隔离不共享Address Space,要通信就必须通过OS提供的机制Single and Multithreaded Processes为什么一个进程要有多个线程?Parallelism: 利用多核硬件并行执行Concurrrency: 更容易处理 I / O和多个同时发生的事件PCB每个Process有一个PCB,这可以看成thread在内核中的官方档案,TCB则更偏向于线程执行状态档案。TCB may be inside PCBPCB包含了:状态( running, ready, blocked )registers状态Process ID( PID ), User, Executbable, Priority执行时间内存空间和地址翻译信息Protection And Isolation我们再次回顾一下刚才放的一张图,这就是我们采取保护和隔离的目的但是仅有地址空间隔离还不够,即使有page table/ address translation,为什么进程不能自己改page table ptr?为什么不能直接发I/O指令绕过OS?我们就必须再加上权限控制,这就引入了:Dual Mode OperationDual Mode OperationDual Mode Operation的含义是硬件至少提供两种模式: Kernel Mode和User Mode。User Mode权限受限,不能做敏感操作;Kernel Mode拥有完整硬件访问能力。课件中列出的User mode不能做的东西包括:changing the page table pointerdisabling interruptsinteracting directly with hardwarewriting to kernel memory我们可以通过Unix System Structure的结构来理解Dual Mode Operation,下图所示的便是Unix。User -> Kernel 的三种方式Syscall进程主动请求系统服务,比如:exitopenreadwriteInterrupt外部的异步事件触发,比如:timer interruptI/O device interruptTrap/Exception进程内部的同步异常触发,比如:divide by 0protection violation( segment fault )这是一种因为硬件/异常机制强制切换控制流OS加载进程的真实过程第一步: OS在kernel mode下准备进程OS会在这一步设置一些基本的Base,Bound,user PC,other oregisters需要注意的是B&B只有在sysmode = 1的时候才可以填写第二步: RTU( Return to User )OS执行返回User mode,开始从用户PC执行用户程序第三步: 执行用户代码此时程序运行在受保护的地址空间里,内核暂时放手第四步: 内核重新拿回控制权通过timer interrupt还有I/O request / interrupt还有exception / trap来重新拿回控制权,这在User -> Kernel是提及到过的第五步: 发生中断后硬件会:保存用户 PC切换到 kernel mode跳到 interrupt vector 对应的 handler第六步: OS可能进行调度如果决定换一个线程/进程来运行:就会选择保存当前thread到TCB恢复下一个thread的TCB再RTU
这次介绍的是四大基本OS概念:Thread,Address Space,Process,Dual Mode Operation。这次的Note内容是对上一次Note的一些补充和扩展,比如对于Thread等概念进行了阐述。Thread在原课件中的定义是:Thread: Single unique execution context:Program Counter, Registers, Execution Flags, Stack, Memory State这里就是在描述,线程是程序执行时的上下文,它完整描述着程序的状态:Program Counter( PC )RegistersExecution FlagsStack知道上面这四样东西,就知道程序本身就正在处于什么状态。这也是为什么thread的核心不是代码本身,而是当前的执行状况。当一个thread正在某个core上执行的时候,它的状态是resident in processor registers,也就是寄存器保存了线程的根状态( 上下文 ):PC在寄存器里寄存器内容就是它的执行状态stack pointer也在寄存器里CPU正在按照这个线程的上下文执行下面这张图展现了程序执行时真正的流程Core单核跑多线程原理原理很简单,因为OS在做`Time Multiplexing #Time_Multiplexing如果我们以足够细的颗粒度来执行每个thread,就会看起来像是有很多虚拟CPU跑线程。在这个过程中也传递了PC,SP还有registers:OS 保存 vCPU1 的 PC、SP、registers 到它的 TCBOS 从 vCPU2 的 TCB 恢复 PC、SP、registersCPU 跳转到 vCPU2 的 PC 开始执行OS通过时间复用( Time Multiplexing )让多个线程轮流占用物理core,于是每个线程都看起来像有一个自己的core。需要提醒的是:thread本身就是virtual CPUTCB当thread不执行的时候,它的上下文就不会驻留在CPU里,而是保存到内存中,通常会保存在一个专门的数据结构里面:TCB = Thread Control Block这也让线程可能处于两种位置:在物理核心上执行在内存中的TCB里被保存这也是线程是虚拟CPU的根本原因Address Space在原课件中的定义是:Address space = the set of accessible addresses + associated state:32 位:2322^{32}232地址64 位:2642^{64}264地址这句话表明的是地址空间是程序能够访问的地址集合,以及与这些地址相关的状态。注意不是简单的内存区域,与地址相关的状态涉及到了:哪些地址程序能读,哪些地址程序能写对这些地址访问有什么效果典型的地址空间布局如下图所示地址空间这个概念存在的必要性,正是体现在限制程序可见和可访问的内存范围这一方面,确保每个程序只看到属于自己的那部分地址。我们先前提及到的 #Time_Multiplexing,每个vCPU都有权限访问非CPU资源,每个线程都可以读写内存,这就导致了线程很有可能篡改OS的内容?也有可能篡改别的线程的内容?我们就思考硬件该怎么帮助OS免受进程的非法篡改?这就引出了B&B,是一种限制线程访问内存权限的方法Base And Bound这是一种很基础的机制,我们有两个register,分别是base register和bound register。程序发出的地址不会直接拿去访问物理内存,而是会先检查:是否在合法范围内或者和base做转换后是否落在允许的区域内( 段基址+偏移地址 )Virtural Address Space这是一种更一般的思想:程序运行在一个和物理内存不同的地址空间里: 程序看到的是virtual address,真正访问的是physical address,中间要经过translation这带来了两个巨大好处:程序看不到不该看的内存程序不再需要连续放在物理内存里Paged Virtual Address Space这是一种分页思想,把整个虚拟地址空间分成固定大小的块,同时把整个物理内存也切成同样大小的块,然后由硬件通过page table完成映射。需要注意的是:每个 virtual page 可以映射到任意 physical frame页面大小固定,管理更方便如果某页不在内存里,访问会触发page fault其中虚拟地址可以看成<Page #> + <Page Offset>,其中<Page #>用来查page table,<Page Offset>直接保留,最后组合出了真实的physical address这是进程隔离最重要的底层机制之一Process原课件的定义:execution environment with Restricted Rights(Protected)Address Space with One or More ThreadsOwns memory(address space)Owns file descriptors, file system context, …Encapsulate one or more threads sharing process resources为什么需要Process这个定义?Process彼此隔离OS也需要被保护进程提供内存保护边界还需要注意的一点是进程内通信容易,进程间通信更难,原因也很简单:同一进程的多个线程共享很多资源;不同进程彼此隔离不共享Address Space,要通信就必须通过OS提供的机制Single and Multithreaded Processes为什么一个进程要有多个线程?Parallelism: 利用多核硬件并行执行Concurrrency: 更容易处理 I / O和多个同时发生的事件PCB每个Process有一个PCB,这可以看成thread在内核中的官方档案,TCB则更偏向于线程执行状态档案。TCB may be inside PCBPCB包含了:状态( running, ready, blocked )registers状态Process ID( PID ), User, Executbable, Priority执行时间内存空间和地址翻译信息Protection And Isolation我们再次回顾一下刚才放的一张图,这就是我们采取保护和隔离的目的但是仅有地址空间隔离还不够,即使有page table/ address translation,为什么进程不能自己改page table ptr?为什么不能直接发I/O指令绕过OS?我们就必须再加上权限控制,这就引入了:Dual Mode OperationDual Mode OperationDual Mode Operation的含义是硬件至少提供两种模式: Kernel Mode和User Mode。User Mode权限受限,不能做敏感操作;Kernel Mode拥有完整硬件访问能力。课件中列出的User mode不能做的东西包括:changing the page table pointerdisabling interruptsinteracting directly with hardwarewriting to kernel memory我们可以通过Unix System Structure的结构来理解Dual Mode Operation,下图所示的便是Unix。User -> Kernel 的三种方式Syscall进程主动请求系统服务,比如:exitopenreadwriteInterrupt外部的异步事件触发,比如:timer interruptI/O device interruptTrap/Exception进程内部的同步异常触发,比如:divide by 0protection violation( segment fault )这是一种因为硬件/异常机制强制切换控制流OS加载进程的真实过程第一步: OS在kernel mode下准备进程OS会在这一步设置一些基本的Base,Bound,user PC,other oregisters需要注意的是B&B只有在sysmode = 1的时候才可以填写第二步: RTU( Return to User )OS执行返回User mode,开始从用户PC执行用户程序第三步: 执行用户代码此时程序运行在受保护的地址空间里,内核暂时放手第四步: 内核重新拿回控制权通过timer interrupt还有I/O request / interrupt还有exception / trap来重新拿回控制权,这在User -> Kernel是提及到过的第五步: 发生中断后硬件会:保存用户 PC切换到 kernel mode跳到 interrupt vector 对应的 handler第六步: OS可能进行调度如果决定换一个线程/进程来运行:就会选择保存当前thread到TCB恢复下一个thread的TCB再RTU