Kernel Linux内核空间和用户空间

Kernel Linux内核空间和用户空间,kernel,space,Kernel,Space,我对内核和用户空间的具体结构以及内存的哪些部分感到困惑。 我目前(可能是错误的)理解是: 创建一个进程,该进程的虚拟内存被分成用户空间和内核空间区域,其中用户空间区域包含进程的数据、代码、堆栈、堆等,内核空间区域包含进程和内核代码的页表等内容。我不确定内核代码是什么…驱动程序代码还是类似的东西 此外,系统调用表是否始终映射到进程内核空间中的同一区域?(说“进程的内核空间”是否正确 如果我编写自己的驱动程序/模块并将其插入,那么驱动程序代码是否会自动复制到创建的每个新进程的内核空间中?如果不是,这

我对内核和用户空间的具体结构以及内存的哪些部分感到困惑。 我目前(可能是错误的)理解是:

  • 创建一个进程,该进程的虚拟内存被分成用户空间和内核空间区域,其中用户空间区域包含进程的数据、代码、堆栈、堆等,内核空间区域包含进程和内核代码的页表等内容。我不确定内核代码是什么…驱动程序代码还是类似的东西

  • 此外,系统调用表是否始终映射到进程内核空间中的同一区域?(说“进程的内核空间”是否正确

  • 如果我编写自己的驱动程序/模块并将其插入,那么驱动程序代码是否会自动复制到创建的每个新进程的内核空间中?如果不是,这到底是如何工作的

  • 提前感谢您的任何输入,可以帮助澄清我问题的文献/链接也可以

    干杯,
    Brick

    进程的虚拟内存映射中没有内核空间区域。虚拟内存映射有:文本、bss、数据、堆、加载程序的堆栈和共享libs。在Linux上,您可以查看任何用户空间进程的/proc/$PID/映射以获取示例

    当用户空间进程通过系统调用访问某些内核域代码时,内核代码将代表其堆栈中的进程执行。显然,从系统调用返回后,所有内核/驱动程序代码都将退出堆栈。为了进一步澄清,如果某一时刻,内核代码的某一部分没有被任何进程使用,它将不是任何进程的虚拟内存映射的一部分


    如果您使用的是Linux,我建议您阅读Robert Love的《Linux内核开发》一书。

    您的总体思路基本正确,但要做如下调整:整个机器只有一个“内核空间”,所有进程都共享它

    当进程处于活动状态时,它可以在“用户模式”或“内核模式”下运行

    在用户模式下,CPU执行的指令位于内存映射的用户空间一侧。程序运行自己的代码,或来自用户空间库的代码。在用户模式下,进程的能力有限。CPU中有一个标志,告诉它不允许使用特权指令和内核内存,尽管它存在进程内存映射中的ts是不可访问的(您不希望让任何程序只读取和写入内核内存-所有安全性都将消失)

    当一个进程想做一些事情而不是在它自己的(用户空间)虚拟内存中移动数据时,比如打开一个文件,它必须进行系统调用。每个CPU体系结构都有自己独特的奇怪的系统调用方法,但它们都归结为:执行一条神奇的指令,CPU打开“特权模式”标记,并跳转到内核空间中的特殊地址,即“syscall入口点”

    现在进程以内核模式运行。正在执行的指令位于内核内存中,它们可以读取和写入任何想要的内存。内核检查进程刚刚发出的请求,并决定如何处理它

    open
    示例中,内核接收与
    intopen(const char*filename,int flags[,int mode])
    参数对应的2或3个参数。第一个参数提供了内核空间何时需要访问用户空间的示例。您说
    open(“foo”,O_RDONLY)
    因此字符串
    “foo”
    是用户空间中程序的一部分。系统调用机制只传递指针,而不是字符串,因此内核必须从用户内存中读取字符串

    为了找到请求的文件,内核可以咨询文件系统驱动程序(找出文件的位置)和块设备驱动程序(从磁盘加载必要的块)或网络设备驱动程序和协议(从远程源加载文件)。所有这些东西都是内核的一部分,即在内核空间中,无论它们是内置的还是作为模块加载的

    如果无法立即满足请求,内核可能会将进程置于睡眠状态。这意味着在从磁盘或网络收到响应之前,进程将从CPU上退出。另一个进程现在可能有机会运行。稍后,当响应到来时,您的进程将再次开始运行(仍处于内核模式)。现在找到了文件,
    open
    syscall可以完成(检查权限,创建文件描述符)并返回到用户空间

    返回用户空间是一个简单的问题,将CPU恢复到非特权模式,并将寄存器恢复到用户->内核转换之前的状态,指令指针指向magic syscall指令之后的指令

    除了系统调用之外,还有其他一些因素会导致从用户模式过渡到内核模式,包括:

  • 页面错误-如果进程访问的虚拟内存地址没有分配物理地址,CPU将进入内核模式并跳转到页面错误处理程序。然后,内核将决定虚拟地址是否有效,并创建物理页面,然后在用户空间中它停止的位置恢复进程,or发送一个SIGSEGV
  • 中断-某些硬件(网络、磁盘、串行端口等)通知CPU需要注意。CPU进入内核模式并跳转到处理程序,内核对此作出响应,然后恢复中断前运行的用户空间进程
  • 加载模块是通过一个系统调用完成的,该系统调用要求内核将模块的代码和数据复制到内核空间,并在内核模式下运行其初始化代码

    这相当长,所以我要停下来。我希望关注用户内核转换的演练已经提供了足够的示例来解决这个问题