zoukankan      html  css  js  c++  java
  • Linux 相关学习记录

      自己学习的备忘,从笔记转移过来,后面每一项写一篇对应的理解文章

    内核线程和用户进程异同记录

    • 所有进程的内核地址空间则都是一样的。对于内核进程,由于其始终运行在内核态,所以没有用户地址空间,其对应的tast_struct结构体中的mm域也就被赋值为NULL。而堆的概念应该是只存在于进程的用户地址空间中,所以内核进程是没有堆一说的。
    • 内核线程只工作在内核态中;而用户线程则既可以运行在内核态,也可以运行在用户态; 内核线程没有用户空间,所以对于一个内核线程来说,它的0-3G的内存空间是空白的,它的current->mm是空的,与内核使用同一张页表;而用户线程则可以看到完整的0-4G内存空间。
    • 杀死内核线程:将该task_struct的状态标志位改为 KTHREAD_SHOULD_STOP (调kthread_stop函数),内核线程忽略信号,可见 http://lzz5235.github.io/2015/06/23/how-to-kill-a-kthread.html
    • 守护进程可被信号杀死,父进程ID为1,内核进程父进程ID为2(kthreadd)

    内核空间分布和寻址

    • 这里写得挺详细:https://www.cnblogs.com/wuchanming/p/4360277.html

      1. 分 ZONE_DMA(16M), ZONE_NORMAL(16M-896M), ZONE_HIGHMEN(896M-1G)(32位机器), ZONE_NORMAL 和 ZONE_DMA 直接映射物理内存,ZONE_HIGHMEM 通过内核PTE页面建立映射,临时用,用完后归还
      2. 进程寻址空间0-4G,进程只有进入内核态才能访问3G-4G
      3. 进程通过系统调用进入内核态
      4. 每个进程虚拟空间的3G~4G部分是相同的
      5. 进程从用户态进入内核态不会引起CR3的改变但会引起堆栈的改变
    • 从用户态进入内核态过程(门的判断)

      • 图参考这里:https://blog.csdn.net/drshenlei/article/details/4265101
      • CPU特权级切换(CPL):是取的CS寄存器的低两位,在任何时候,不管CPU内部正在发生什么,只要看一眼cs中的CPL,你就可以知道此刻的特权级了。
      • 防止用户态访问内核态空间
        • 通过分段保护机制,当 RPL 和 CPL 都大于 DPL 时候才可以访问对应地址的内存
          • CPL是当前进程的权限级别(Current Privilege Level),是当前正在执行的代码所在的段的特权级,存在于cs寄存器的低两位。
          • DPL:描述符特权(Descriptor Privilege Level) 存储在描述符中的权限位,用于描述代码的所属的特权等级,也就是代码本身真正的特权级。一个程序可以使用多个段(Data,Code,Stack)也可以只用一个code段等。正常的情况下,当程序的环境建立好后,段描述符都不需要改变——当然DPL也不需要改变,因此每个段的DPL值是固定。
          • RPL:请求特权级RPL(Request Privilege Level) ,RPL保存在选择子的最低两位。RPL说明的是进程对段访问的请求权限,意思是当前进程想要的请求权限。RPL的值由程序员自己来自由的设置,并不一定RPL>=CPL,但是当RPL<CPL时,实际起作用的就是CPL了,因为访问时的特权检查是判断:EPL=max(RPL,CPL)<=DPL是否成立,所以RPL可以看成是每次访问时的附加限制,RPL=0时附加限制最小,RPL=3时附加限制最大。所以你不要想通过来随便设置一个rpl来访问一个比cpl更内层的段。
    • 用户态到内核态切换途径

      1. 系统调用
      2. 中断
      3. 异常
    • 用户态进入内核态后进程栈如何切换

      • 详细代码参考这里:https://www.cnblogs.com/justcxtoworld/p/3155741.html
      • 读取TSS段(保存有用户栈顶指针和内核栈顶指针)读取 sp0, ss0
        // TSS 结构定义(参考)
        
        #ifdef CONFIG_X86_32
        /* This is the TSS defined by the hardware. */
        struct x86_hw_tss {
            unsigned short          back_link, __blh;
            unsigned long           sp0;              //当前进程的内核栈顶指针
            unsigned short          ss0, __ss0h;       //当前进程的内核栈段描述符
            unsigned long           sp1;
            /* ss1 caches MSR_IA32_SYSENTER_CS: */
            unsigned short          ss1, __ss1h;
            unsigned long           sp2;
            unsigned short          ss2, __ss2h;
            unsigned long           __cr3;
            unsigned long           ip;
            unsigned long           flags;
            unsigned long           ax;
            unsigned long           cx;
            unsigned long           dx;
            unsigned long           bx;
            unsigned long           sp;            //当前进程用户态栈顶指针
            unsigned long           bp;
            unsigned long           si;
            unsigned long           di;
            unsigned short          es, __esh;
            unsigned short          cs, __csh;
            unsigned short          ss, __ssh;
            unsigned short          ds, __dsh;
            unsigned short          fs, __fsh;
            unsigned short          gs, __gsh;
            unsigned short          ldt, __ldth;
            unsigned short          trace;
            unsigned short          io_bitmap_base;
        } __attribute__((packed));
  • 相关阅读:
    C++ and OO Num. Comp. Sci. Eng.
    C++ and OO Num. Comp. Sci. Eng.
    C++ and OO Num. Comp. Sci. Eng.
    C++ and OO Num. Comp. Sci. Eng.
    C++ and OO Num. Comp. Sci. Eng.
    C++ and OO Num. Comp. Sci. Eng.
    WPF 应用程序使用程序的模型视图 ViewModel 设计模式 WVVM
    穿透Session 0 隔离(二)(How to use Windows service run a GUI application.)
    穿透Session 0 隔离(一)(how to use Windows service run a GUI application.)
    .Net 远程路径权限访问。
  • 原文地址:https://www.cnblogs.com/varXinYuan/p/10865443.html
Copyright © 2011-2022 走看看