精华内容
下载资源
问答
  • CPU有4个运行级别,如下图,我们所说的内核就是Ring0当CPU运行ring0态的时候就是内核态(也就是CPL=0),此时拥有最 高的权限 而在用户态的时候就是CPL=3此时CPU处于用户态 再次提出几个问题解决...

            应该学习过一段时间的人,都能唱出来,低2GB是用户空间,高2GB是内核空间,我们如果在用户空间访问内核空间数据,直接给你一个0xC0000005异常,告诉你你没有权限访问,

           今天就给大家完全的解析什么是内核空间,什么是用户空间

    CPU有4个运行级别,如下图,我们所说的内核就是Ring0当CPU运行ring0态的时候就是内核态(也就是CPL=0),此时拥有最           高的权限

    而在用户态的时候就是CPL=3此时CPU处于用户态

        再次提出几个问题解决了这几个问题就解决了

    1.我在用户态访问高2GB内存会失败是因为我不是内核态所有访问失败的嘛?

    2.内核态真的只是高2GB的时候才能处于内核态嘛

     

    首先我使用用户态访问一个高2GB内存

    void  _declspec(naked) taolaoda(){
        __asm{
            pushad
            pushfd
            mov eax,0x8003f008
            mov ecx,[eax]
            mov edx,[eax+4]
            mov Vluae,ecx
            mov Vluae1,edx
            popfd
            popad
            retf
        }
    }
    int main(int argc, char* argv[])
    {
        char buf[6];
        char buf2[6];
        *((WORD*)&buf[4])=0x1b;                                                      //这个就是本来cs的选择子 没有改变  直接调用taolaoda函数也    是一样我用长调用的方式调用,是为了后面构造段描述符方便少该代码
        *((DWORD*)&buf[0])=(int)taolaoda;
        __asm{
            call buf;
        }
        printf("Vluae=%p  Vluae\n",Vluae,Vluae1);
        getchar();
        return 0;
    }

    结果是访问访问高2GB的   0xC0000005访问异常,这是谁不让我们访问?

    答案是页机制(没有学过页的不要紧后面我们会有一篇帖子专门介绍页),

     

      我通过Windug修改0x8003f000这个物理页的访问权看看,首先通过Windug输入 !process 0 0遍历所有进程,获得自己正在运行的Cr3,然后找到0x8003f000对应的物理页

    这我自己写的一个2-9-9-12地址拆分器

    看到下面红框起来的,可以看到找到了0x8003f000对应的物理页,数据吻合

    修改自己进程 0x8003f000对应的物理页PTE的属性 的第2位和第8位

    第2位是U/S  U/S位=1的时候  允许用户态访问CPL=3,(CPU允许CPL=0,1,2访问用户态)

                         U/S位=0的时候  允许内核态访问,此时只有CPL=0的时候访问这个页地址的时候才能通过

    第7位是G位  G=0给刷新一下CPU内部的TLB表,后面会将这章的重点是让我们明白 段和页的限制以及内核态用户态的是

    根据什么来定的

    修改PDE的属性    修改U/S=1

    这是接着上面0xC0000005运行的那个进程接着运行的没有重新运行

    这就是为什么高2GB用户态无法访问了,所有进程高2GB都是内核是共享的,操作系统通过页机制,

    把0x80000000-0xFFFFFFFF这些地址对应的物理页PTE,PDE的U/S设置0位只允许内核态访问呢就是CPL=0时候

    mov  eax,[0x8003f008]这条执行才能执行,或者把0x8003f000这个物理页的对应的PTE和PDE的 全都设置为U/S=1

    此时这条指令mov  eax,[0x8003f008],在CPL=0,1,2,3的时候都能访问。

            所以可以说是页机制将高2GB和第2GB数据分格开,由于操作系统将高2GB的内存的物理页PTE全都设置成了U/S=0只允许CPL=0的时候访问,所以高2GB又被一些人称为内核(因为此时候CPL=0才被称为内核的),https://blog.csdn.net/taolaodawho/article/details/108957337 这是我们写一的一篇段权限检查,里面描述了段机制做了什么,

    保护模式保护的是内存(和一些特权指令),段机制对保护内存做的不多,对内存的保护是页做的,能够将高2GB和第2GB分开,其实很多人对内核的理解都是有误的,本意应该是当CPU执行某条指令的时候 CPL的值,如果此时CPL=3就是用户态,CPL=0就是内核态,这说明的是CPU的状态,很多人却将其与内存对应起来,说高2GB是内核,(再次是申明一下内核态是CPU的状态,与内存无关),高2GB的内存别操作系统设置过物理页的属性,只允许CPL=0(内核态访问),而低2GBCPU运行与任何状态都可以访问,这就是页机制做的内存保护

    我们也谈一谈段对内存的保护,也有但是远远无法和页做的相比,段对内存就做就比如数据段(好你可以访问0x00000000-0xFFFFFFFF这4GB空间,以可读,或者可读可写的权限(段把内存看成一个整体,这个整体权限完全相同)),页是在段的基础上将分割成一个一个页(每个小页0x1024字节),每个一页都有它自己的属性,有的页只允许CPL=0的指令访问,有些页只读,有些页可读可写,所有说对内存的保护主要是页机制做的,因为段主要做的是加载段描述符,具有提权功能(会进行权限检查),

    我们构造一个系统段,调用们提权

    通过调用们提权后可以看到直接直接读高2GB内存的数据

    可以看到通过调用们提权后发现 调试的时候是WIndug内核调试器接受的调试信息,此时CPL=0就是内核态了,也就是说也可以访问高2GB内存了,结合所有应该能够明白了,权限说的是CPU的概念,访问不同内存需要的权限不同,所以CPL在不同级能够访问的数据不同,也有一写特权指令执行在内核态才能执行成功,段就是提升CPU权限的手段,当然也能降低。

    当段机制和页机制同时配合起来的时候,就有了高2GB是内核空间(只允许内核态访问 页限制),低2GB是用户空间(允许所有权限访问),用户空间中有些区域是只读区,有些可读可,这有是页机制的杰作

    上面的测试可以看到地址0x401050  处的指令也是在内核态,在很多正向人眼里这是用户空间,这说明他根本不知道什么是应用空间,内核空间,到这里大家应该能了解到那些是段机制做的了,那些事页机制做的。

     

     

    展开全文
  • 内核态到底是什么呢?其实从本质上说就是我们所说的内核,它是一种特殊的软件程序,特殊在哪儿呢?控制计算机的硬件资源,例如协调CPU资源,分配内存资源,并且提供稳定的环境供应用程序运行。 用户态就是提供应用...

    什么是用户态和内核态

    在这里插入图片描述
    从图上我们可以看出来通过系统调用将Linux整个体系分为用户态和内核态(或者说内核空间和用户空间)。
    那内核态到底是什么呢?其实从本质上说就是我们所说的内核,它是一种特殊的软件程序,特殊在哪儿呢?控制计算机的硬件资源,例如协调CPU资源分配内存资源,并且提供稳定的环境供应用程序运行。

    用户态就是提供应用程序运行的空间,为了使应用程序访问到内核管理的资源例如CPU,内存,I/O。内核必须提供一组通用的访问接口,这些接口就叫系统调用。

    为什么要区分内核态和用户态

    往往我们的系统的资源是固定的,例如内存2G,CPU固定,磁盘2TB,网络接口固定。所以就需要操作系统对资源进行有效的利用。假设某个应用程序过分的访问这些资源,就会导致整个系统的资源被占用,如果不对这种行为进行限制和区分,就会导致资源访问的冲突。所以,Linux的设计的初衷:给不同的操作给与不同的“权限”。Linux操作系统就将权限等级分为了2个等级,分别就是内核态和用户态。

    各位有没有发现,前面讲了这么多内核态和用户态什么不同,其实用一句话就能概括:它们权限不同。用户态的进程能够访问的资源受到了极大的控制,而运行在内核态的进程可以“为所欲为”。一个进程可以运行在用户态也可以运行在内核态,那它们之间肯定存在用户态和内核态切换的过程。打一个比方:C库接口malloc申请动态内存,malloc的实现内部最终还是会调用brk()或者mmap()系统调用来分配内存。

    如何从用户态进入内核态

    • 系统调用:这是用户态进程主动要求切换到内核态的一种方式。用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作。例如fork()就是执行了一个创建新进程的系统调用。系统调用的机制和新是使用了操作系统为用户特别开放的一个中断来实现,所以系统调用本身就是中断,但是软件中断,跟硬中断不同。
    • 异常:如果当前进程运行在用户态,如果这个时候发生了异常事件,就会触发切换。例如:缺页异常。
    • 外设中断:当外设完成用户的请求时,会向CPU发送中断信号。这时CPU会暂停执行下一条即将要执行的指令而转到与中断信号对应的处理程序去执行,如果前面执行的指令时用户态下的程序,那么转换的过程自然就会是 由用户态到内核态的切换。如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后边的操作等。

    这三种方式是系统在运行时由用户态切换到内核态的最主要方式,其中系统调用可以认为是用户进程主动发起的,异常和外围设备中断则是被动的。从触发方式上看,切换方式都不一样,但从最终实际完成由用户态到内核态的切换操作来看,步骤有事一样的,都相当于执行了一个中断响应的过程。系统调用实际上最终是中断机制实现的,而异常和中断的处理机制基本一致。

    转载自:https://zhuanlan.zhihu.com/p/69554144
    https://blog.csdn.net/qq_39823627/article/details/78736650

    展开全文
  • 用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作,比如前例中fork()实际上就是执行了一个创建新进程的系统调用。而系统调用的机制其核心还是使用了操

    用户态:当进程在执行用户自己的代码时,则称其处于用户态,这时cpu 访问资源有限,运行在用户态下的程序不能直接访问操作系统内核数据结构和程序。

    内核态:当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核状态,这时cpu可以访问计算机的任何资源。

    用户态变为内核态:

    a. 系统调用

    这是用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作,比如前例中fork()实际上就是执行了一个创建新进程的系统调用。而系统调用的机制其核心还是使用了操作系统为用户特别开放的一个中断来实现,例如Linux的int 80h中断。

    b. 异常

    当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。

    c. 外围设备的中断

    当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。

    展开全文
  • 什么是用户态和内核态 Kernel 运行在超级权限模式(Supervisor Mode)下,所以拥有很高的权限。按照权限管理的原则,多数应用程序应该运行在最小权限下。因此,很多操作系统,将内存分成了两个区域: 内核空间...

    转载

    文章来源于 拉钩教育 重学操作系统 林䭽 用户态和内核态:用户态线程和内核态线程有什么区别?

    什么是用户态和内核态

    Kernel 运行在超级权限模式(Supervisor Mode)下,所以拥有很高的权限。按照权限管理的原则,多数应用程序应该运行在最小权限下。因此,很多操作系统,将内存分成了两个区域:

    1. 内核空间(Kernal Space),这个空间只有内核程序可以访问;

    2. 用户空间(User Space),这部分内存专门给应用程序使用。

    用户态和内核态

    用户空间中的代码被限制了只能使用一个局部的内存空间,我们说这些程序在用户态(User Mode) 执行。内核空间中的代码可以访问所有内存,我们称这些程序在内核态(Kernal Mode) 执行。

    系统调用过程

    如果用户态程序需要执行系统调用,就需要切换到内核态执行。下面我们来讲讲这个过程的原理。
    在这里插入图片描述
    如上图所示:内核程序执行在内核态(Kernal Mode),用户程序执行在用户态(User Mode)。当发生系统调用时,用户态的程序发起系统调用。因为系统调用中牵扯特权指令,用户态程序权限不足,因此会中断执行,也就是 Trap(Trap 是一种中断)。

    发生中断后,当前 CPU 执行的程序会中断,跳转到中断处理程序。内核程序开始执行,也就是开始处理系统调用。内核处理完成后,主动触发 Trap,这样会再次发生中断,切换回用户态工作。

    线程模型

    上面我们学习了用户态和内核态,接下来我们从进程和线程的角度进一步思考本课时开头抛出的问题。

    进程和线程

    一个应用程序启动后会在内存中创建一个执行副本,这就是进程。Linux 的内核是一个 Monolithic Kernel(宏内核),因此可以看作一个进程。也就是开机的时候,磁盘的内核镜像被导入内存作为一个执行副本,成为内核进程。

    进程可以分成用户态进程和内核态进程两类。用户态进程通常是应用程序的副本,内核态进程就是内核本身的进程。如果用户态进程需要申请资源,比如内存,可以通过系统调用向内核申请。

    那么用户态进程如果要执行程序,是否也要向内核申请呢?

    程序在现代操作系统中并不是以进程为单位在执行,而是以一种轻量级进程(Light Weighted Process),也称作线程(Thread)的形式执行。

    一个进程可以拥有多个线程。进程创建的时候,一般会有一个主线程随着进程创建而创建。
    在这里插入图片描述
    如果进程想要创造更多的线程,就需要思考一件事情,这个线程创建在用户态还是内核态。

    你可能会问,难道不是用户态的进程创建用户态的线程,内核态的进程创建内核态的线程吗?

    其实不是,进程可以通过 API 创建用户态的线程,也可以通过系统调用创建内核态的线程,接下来我们说说用户态的线程和内核态的线程。

    用户态线程

    用户态线程也称作用户级线程(User Level Thread)。操作系统内核并不知道它的存在,它完全是在用户空间中创建。

    用户级线程有很多优势,比如。

    1. 管理开销小:创建、销毁不需要系统调用。

    2. 切换成本低:用户空间程序可以自己维护,不需要走操作系统调度。

    但是这种线程也有很多的缺点。

    1. 与内核协作成本高:比如这种线程完全是用户空间程序在管理,当它进行 I/O 的时候,无法利用到内核的优势,需要频繁进行用户态到内核态的切换。

    2. 线程间协作成本高:设想两个线程需要通信,通信需要 I/O,I/O 需要系统调用,因此用户态线程需要支付额外的系统调用成本。

    3. 无法利用多核优势:比如操作系统调度的仍然是这个线程所属的进程,所以无论每次一个进程有多少用户态的线程,都只能并发执行一个线程,因此一个进程的多个线程无法利用多核的优势。

    4. 操作系统无法针对线程调度进行优化:当一个进程的一个用户态线程阻塞(Block)了,操作系统无法及时发现和处理阻塞问题,它不会更换执行其他线程,从而造成资源浪费。

    内核态线程

    内核态线程也称作内核级线程(Kernel Level Thread)。这种线程执行在内核态,可以通过系统调用创造一个内核级线程。

    内核级线程有很多优势。

    1. 可以利用多核 CPU 优势:内核拥有较高权限,因此可以在多个 CPU 核心上执行内核线程。

    2. 操作系统级优化:内核中的线程操作 I/O 不需要进行系统调用;一个内核线程阻塞了,可以立即让另一个执行。

    当然内核线程也有一些缺点。

    1. 创建成本高:创建的时候需要系统调用,也就是切换到内核态。

    2. 扩展性差:由一个内核程序管理,不可能数量太多。

    3. 切换成本较高:切换的时候,也同样存在需要内核操作,需要切换内核态。

    用户态线程和内核态线程之间的映射关系

    线程简单理解,就是要执行一段程序。程序不会自发的执行,需要操作系统进行调度。我们思考这样一个问题,如果有一个用户态的进程,它下面有多个线程。如果这个进程想要执行下面的某一个线程,应该如何做呢?

    这时,比较常见的一种方式,就是将需要执行的程序,让一个内核线程去执行。毕竟,内核线程是真正的线程。因为它会分配到 CPU 的执行资源。

    如果一个进程所有的线程都要自己调度,相当于在进程的主线程中实现分时算法调度每一个线程,也就是所有线程都用操作系统分配给主线程的时间片段执行。这种做法,相当于操作系统调度进程的主线程;进程的主线程进行二级调度,调度自己内部的线程。

    这样操作劣势非常明显,比如无法利用多核优势,每个线程调度分配到的时间较少,而且这种线程在阻塞场景下会直接交出整个进程的执行权限。

    由此可见,用户态线程创建成本低,问题明显,不可以利用多核。内核态线程,创建成本高,可以利用多核,切换速度慢。因此通常我们会在内核中预先创建一些线程,并反复利用这些线程。这样,用户态线程和内核态线程之间就构成了下面 4 种可能的关系:

    多对一(Many to One)
    用户态进程中的多线程复用一个内核态线程。这样,极大地减少了创建内核态线程的成本,但是线程不可以并发。因此,这种模型现在基本上用的很少。我再多说一句,这里你可能会有疑问,比如:用户态线程怎么用内核态线程执行程序?

    程序是存储在内存中的指令,用户态线程是可以准备好程序让内核态线程执行的。后面的几种方式也是利用这样的方法。
    在这里插入图片描述
    一对一(One to One)

    该模型为每个用户态的线程分配一个单独的内核态线程,在这种情况下,每个用户态都需要通过系统调用创建一个绑定的内核线程,并附加在上面执行。 这种模型允许所有线程并发执行,能够充分利用多核优势,Windows NT 内核采取的就是这种模型。但是因为线程较多,对内核调度的压力会明显增加。
    在这里插入图片描述
    多对多(Many To Many)
    这种模式下会为 n 个用户态线程分配 m 个内核态线程。m 通常可以小于 n。一种可行的策略是将 m 设置为核数。这种多对多的关系,减少了内核线程,同时也保证了多核心并发。Linux 目前采用的就是该模型。
    在这里插入图片描述
    两层设计(Two Level)
    这种模型混合了多对多和一对一的特点。多数用户态线程和内核线程是 n 对 m 的关系,少量用户线程可以指定成 1 对 1 的关系。
    在这里插入图片描述
    上图所展现的是一个非常经典的设计。

    我们这节课讲解的问题、考虑到的情况以及解决方法,将为你今后解决实际工作场景中的问题打下坚实的基础。比如处理并发问题、I/O 性能瓶颈、思考数据库连接池的配置等,要想完美地解决问题,就必须掌握这些模型,了解问题的本质上才能更好地思考问题衍生出来的问题。

    用户态线程和内核态线程的区别?

    用户态线程工作在用户空间,内核态线程工作在内核空间。用户态线程调度完全由进程负责,通常就是由进程的主线程负责。相当于进程主线程的延展,使用的是操作系统分配给进程主线程的时间片段。内核线程由内核维护,由操作系统调度。

    用户态线程无法跨核心,一个进程的多个用户态线程不能并发,阻塞一个用户态线程会导致进程的主线程阻塞,直接交出执行权限。这些都是用户态线程的劣势。内核线程可以独立执行,操作系统会分配时间片段。因此内核态线程更完整,也称作轻量级进程。内核态线程创建成本高,切换成本高,创建太多还会给调度算法增加压力,因此不会太多。

    实际操作中,往往结合两者优势,将用户态线程附着在内核态线程中执行。

    展开全文
  • 说了用户态和内核态之后,那么什么是系统调用呢? 我们运行的程序基本都运行在用户态,如果我们调用操作系统提供的内核态的子功能咋办呢,这就需要系统调用了。 也就是说我们运行的用户程序中,凡是与系统态级别的...
  • 什么是内核态

    2018-04-06 12:15:40
    内核操作系统的内部核心程序,它向外部提供了对计算机设备的核心管理调用。...当执行到内河空间的一段代码时,我们称程序处于内核态,而当程序执行到外部空间代码时,我们称程序处于用户态。 ...
  • 主要为了安全性:上古时代的操作系统,没有用户态和内核态的区分的。内核态的权限比用户态高很多的,可能不小心一个误操作就对计算机造成很大的伤害。用户态权限比较小,只能进行一些比较低风险的操作。 ...
  • 在高执行级别下,代码可以执行特权指令,访问任意的物理地址,这种CPU执行级别就对应着内核态。 如何区分用户态和内核态? CS寄存器的最低两位表明了当前代码的特权级。 CPU每条指令的读取都通过CS:eip这两个...
  • 在高执行级别下,代码可以执行特权指令,访问任意的物理地址,这种CPU执行级别就对应着内核态。而在相应的低级别执行状态下,代码的掌控范围会受到限制。只能在对应级别允许的范围内活动。举例:intel x86 CPU有四种...
  • 究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得在于因为大部分时候我们在写程序时关注的重点和着眼的角度放在了实现的功能和代码的逻辑性上,先看一个例子: ...
  • 之前学习并发的时候只知道挂起线程或者唤醒线程要从用户态转换到内核态,那么什么是用户态?什么是内核态?这也一个频率较高的面试题。 首先在讲用户态和核心态的时候,为了更容易理解先说下什么是操作系统的特权...
  • 太长不看的提前总结:内核态,或者说CPU的特权模式,CPU的一种工作状态,它影响CPU对不同指令的执行结果。操作系统通过跟CPU配合,设置特权模式和用户模式,来防止应用程序进行越权的操作防止应用程序越权访问内存...
  • 本篇博客转载自什么是内核态和用户态  在单内核模式系统中,操作系统提供服务的流程为(即用户应用程序调用系统内核功能):应用主程序使用指定的参数执行系统调用指令(intel x80),使CPU从用户态(User Mode)...
  • 1、用户态和内核态的区别? 明白这两个概念之前,我们得知道用户空间和内核空间。 用户空间:指的就是用户可以操作和访问的空间,这个空间通常存放我们用户自己写的数据等。 内核空间:系统内核来操作的一块...
  • 每天3分钟操作系统修炼秘籍(3):内核态和用户态,什么是系统内核点我查看秘籍连载限制进程:内核态和用户态进程可分为两种类型。一操作系统自身运行时的内核类进程,也称为操作系统进程。另一种即非内核类进程,...
  • 凡是回答里说“操作系统分0环和3环”的就从底子上不对。 那叫“操作系统分”的吗?...可能没有理解“操作系统”在这句话里是什么意思,也没有理解什么是“用户态”和“内核态”,也并不是很理解什么是“...
  • 什么是用户态和内核态? Kernel 运行在超级权限模式(Supervisor Mode)下,所以拥有很高的权限。按照权限管理的原则,多数应用程序应该运行在最小权限下。因此,很多操作系统,将内存分成了两个区域: 内核空间...
  • 用户态和内核态

    2020-12-02 00:02:21
    什么是内核态?CPU特权级:用户态和内核态从用户态进入内核态的方式系统调用异常中断用户态、内核态的具体切换过程结语 前言 在本文中,会涉及到中断,异常,系统调用等概念。在有些参考资料上,会将中断和系统调用...
  • 用户态与内核态

    2020-05-18 12:41:19
    一、什么是用户态与内核态: 为什么要有用户态和内核态? 由于需要限制不同的程序之间的访问能力, 防止他们获取别的程序的内存数据, 或者获取...也即,用户态与内核态是对CPU使用的权限划分。目的是防止普通程序错误或
  • 内核态和用户态

    2020-11-18 16:02:41
    什么是内核态和用户态? 内核态:cpu可以访问内存的所有数据,包括外围设备,例如:硬盘,网卡,cpu,也可以将自己从一个程序切换到另一个程序 用户态:只能访问受限的访问内存,且不允许访问外围设备,占用cpu 的...
  • 用户态和内核态是什么? 用户级线程和内核级线程是一个怎样的对应关系? 内核响应系统调用是一个怎样的过程? …… 而且这个问题还关联到了我们后面要学习的多线程、I/O 模型、网络优化等。 所以这是一道很不错...
  • 经常听到的用户态与内核态是什么?CPU执行命令的不同权限状态

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,728
精华内容 691
关键字:

内核态是什么