内核态和用户态

基本概念

  • 用户态和内核态是操作系统的两种运行级别,两者最大的区别就是特权级不同
  • 用户态拥有最低的特权级,内核态具有较高的特权级
  • 运行在用户态的程序不能直接访问操作系统内核结构和数据
  • 操作系统数据都是存放于系统空间的,用户态进程的数据是存放在用户空间的,分开来存放就是为了让系统的数据和用户的数据互不干扰,保证系统的稳定性,分开存放,管理上比较方便,并且对于两部分数据的访问就可以进行控制,避免用户态程序恶意修改操作系统的数据和结构

为什么需要有用户态和内核态

由于需要限制不同程序之间的访问能力,防止它们获取别的程序的内存数据,或者获取外围设备的数据并发送到网络。某些程序和安全性不高,如果执行了这些CPU的某些指令,会导致系统崩溃,如:设置时钟、清理内存、调整网络

当我们在系统中运行一个程序时,大部分时间是运行在用户态下的,在其需要操作系统帮助完成某些它没有权力完成的工作时就会切换到内核态

特权级

在Unix/Linux系统中,fork的工作实际上是以系统调用的方式完成相应功能的,具体的工作是由sys_fork负责实施,其实对任何操作系统来说,创建一个新的进程都是属于核心功能,因为它要做很多底层细致地工作,消耗系统的物理资源,比如分配物理内存,从父进程拷贝相关信息,拷贝设置页目录页表等等,这些显然不能随便让哪个程序就能去做,于是引出特权级的概念。对于最关键性的权力必须由搞特权的程序来执行,这样才能做到集中管理,减少有限资源的访问和使用冲突。

两种状态的转换方式

  • 系统调用
    • 用户进程主动要求切换到内核态的一种方式,用户进程通过系统调用申请操作系统提供的服务程序完成工作
  • 异常
    • 当CPU在执行运行在用户态的程序时,发现了某些事情不可知的异常,这是会触发由当前运行进程切换到处理此异常的内核相关程序中,也就到了内核态,比如缺页异常
  • 外围设备中断
    • 当外围设备完成用户请求的操作之后,会像CPU发出相应的中断信号,这时CPU会暂停执行下一条将要执行的指令,转而去执行中断信号的处理程序
    • 比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等

这三种方式是系统运行时由用户态转到内核态的最主要方式,其中系统调用可以认为是用户进程主动发起的,异常和外围设备中断则是被动的

用户态和内核态之间可以通过指针传递数据吗

  • 用户态不能访问内核态的指针

    • 为了实现内存的保护,防止越界访问而造成受保护内存被非法修改,甚至造成系统的崩溃,这种直接传递数据指针来传递数据的方式,被禁止
  • 内核态可以访问用户态的指针(有前提)

    • 必须保证用户态虚拟空间的指针(虚拟内存地址)已经分配给物理地址,否则指针传入内核态中将会引发缺页异常而报错
  • 内核中访问用户进程的地址使用copy_from_user,而不是memcopy直接拷贝(使用用户态指针)

    • copy_from_user函数主要提供了以下功能
      1. 对用户进程传过来的地址范围进行合法性检查
      2. 对用户传来的地址没有分配物理地址时,定义了缺页处理后的异常发生地址,保证程序顺序执行
      3. 对于用户进程访问虚拟地址,如果还未分配物理地址,就会触发内核缺页异常,接着内核会负责分配物理地址,并修改映射页表,这个过程对于用户进程时是完全透明的,但是在内核空间发生缺页时,必须进行显示进行处理,否则会导致内核出现错误
    • 但是直接使用memcopy时并没有报错

    ​ 只有用户传来的空间地址没有分配对应的物理地址时才会进行修复,如果用户进程之前已经 使用过这段空间,代表已经分配了物理地址,自然不会引发缺页异常

参考链接

https://blog.csdn.net/ddna/article/details/4941373

https://github.com/twomonkeyclub/BackEnd/tree/master/计算机基础知识/操作系统#用户态和内核态

posted @ 2021-05-30 17:09  简约的信仰  阅读(1349)  评论(0编辑  收藏  举报