译:深入Linux内核架构(第一章)1.3.3

来源:互联网 发布:交大知行 编辑:程序博客网 时间:2024/06/18 17:41

译:深入Linux内核架构(第一章)

注:选择性翻译原文。

1.3.3地址空间和权限级别

在我们开始讨论虚拟地址空间之前,先指定一些符号约定。贯穿本书,分别用KiBMiB,和GiB来代表大小单位。那些传统的单位:KBMB,和GB在信息技术很不合适。因为他们代表十进制(103,106,和109 ),而二进制系统在计算机系统中无处不在。因此KiBMiB,和GiB分别代表着210,220,和230byte

因为内存区域是通过指针来处理,CPU的位数决定了最大的可寻址地址空间范围。在32位系统,如IA-32PPC、和m68k,这些都是232 = 4GiB而更多的现代64位处理器如 Alpha, Sparc64, IA-64,以及AMD64,寻址范围达到264byte。

最大尺寸的地址空间与可用物理RAM之间没有依赖关系,因此它被称为虚拟地址空间。这个称呼一个原因是,每一个系统的进程有映像,并仅仅运行在这个地址空间。并且从进程本身的角度来看,其他进程不复存在。应用程序不需要关心其他应用程序,就好像其实工作中计算机中唯一的程序一样。

Linux虚拟地址空间划分成两个部分,分别称为内核空间和用户空间见图1-3

系统每一个用户进程都有它自己的虚拟地址范围,从0扩展到TASK_SIZE。以上区域(TASK_SIZE到232或264)是专属于内核,可能拒绝用户进程访问。TASK_SIZE 是一个特定于体系结构的常数,将地址空间划分在一个指定的比例——IA-32的系统,地址空间划分在3GiB,以致每个进程的虚拟地址空间是3GiB1GiB内核可用,因为总的虚拟地址空间大小是4GiB。

这个章节不取决于有多少内存可用。由于地址空间的虚拟化,每个用户进程都有3 GiB内存(寻址范围)。私人系统进程的用户空间完全与其他进程间独立开来。内核空间的初始与终结地址空间总是相同的,尽管当前进程正在运行。

注意,上图在64位机上更为复杂,因为这些趋向于使用少于64bits来实际管理他们巨大的主要虚拟地址空间。他们雇佣一个较小的数字,如,4247bits来代替64bits。因此,有效可寻址的部分地址空间是小于最大尺寸范围。然而,它仍然是出现在这台机器的大于 RAM大小的内存,以此完全够用。 作为一个优势,CPU可以节省一些资源,因为较少的bits被用在管理有效的地址空间空间,而不是需要完整的虚拟地址空间大小的bits在这种情况下,虚拟地址空间将包含不被寻址到的地址空间的漏洞,所以简单的情况如图1-3不是完全有效的。我们将会在第四章更详细地讨论这个问题。


特权级别

内核虚拟地址空间划分成两部分,这样就能从系统各个进程中保护私人进程。所有现代的cpu都提供几个让进程归属特权级别。有各种各样的禁令包括在每个级别里面,例如,执行一定的集合语言指令或访问特定部分的虚拟地址空间。IA-32架构使用一个有四个可以可视化为环状的特权级别的系统。内部环能够访问更多的函数,外环逐渐减少,如图1-4

而英特尔区分四个不同的水平,Linux只使用两个不同的模式——内核模式及用户模式。两者的主要区别是访问TASK_SIZE内存区以上,那是,内核空间——在用户模式下被禁止访问。用户进程不能够在内核空间中操作或读数据。他们也不能把执行代码存储存在那里。这是内核唯一的领域。这种机制可以防止进程互相之间由于无意识的影响彼此的数据而产生的干扰。

从用户切换到内核模式是由特殊的转换的方法称为系统调用。这些执行动作的不同取决于系统。如果一个正常的进程要进行影响整个系统的任何形式的动作(如操纵的I / O设备),它只需要在系统调用的帮助下向内核发出一个请求。内核首先检查进程是否被允许执行所需的操作,然后代替进程执行。最后返回到用户模式。

除了用户程序执行代码的动作之外,内核也可以被异步硬件中断激活,然后就运行在中断上下文中。进程运行在上下文中的主要差别在于用户空间部分的虚拟地址空间不能被访问no copy_form_user 、 copy_to_user。因为中断随机地发生,当一个中断发生的时候一个随机的用户空间进程被激活,以及由于中断很可能被其他的中断所打断,内核没有必要与当前用户空间的内容取得联系。当操作在中断上下文内核必须比平时谨慎,例如,禁止进入休眠。这些需要在编写的中断处理程序中进行额外的处理,将回到第二章中详细讲到。图1-5概述了上下文不同的执行情况。 

除了正常的进程,还有在系统上运行的内核线程。内核线程也不与任何特定的用户空间进程相关联所以他们也没有必要去处理用户地址空间的内容。在很多其他方面,内核线程表现得更像普通用户空间应用程序,虽然:跟一个内核操作在中断上下文相比,他们可以进入休眠,也可以像每个普通系统的进程一样被系统调度程序跟踪。内核在数据同步的RAM和块设备帮助的范围下为各种目的使用它们,在不同CPU之间来协助进程的调度,在这本书中我们经常会反复提及。

注意到内核线程可以轻易地ps的输出中识别出,因为他们的名字被放置花括号内:

wolfgang@meitner>  ps  fax

PID  TTY STAT      TIME  COMMAND

     2  ? S< 0:00  [kthreadd]

     3  ? S< 0:00    _  [migration/0]

     4  ? S< 0:00    _  [ksoftirqd/0]

    5  ? S< 0:00    _  [migration/1]

    6  ? S< 0:00    _  [ksoftirqd/1]

    7  ? S< 0:00    _  [migration/2]

    8  ? S< 0:00    _  [ksoftirqd/2]

    9  ? S< 0:00    _  [migration/3]

   10  ? S< 0:00    _  [ksoftirqd/3]

   11  ? S< 0:00    _  [events/0]

  12  ? S< 0:00    _  [events/1]

   13  ? S< 0:00    _  [events/2]

   14  ? S< 0:00    _  [events/3]

   15  ? S< 0:00    _  [khelper]

  ...

  15162  ? S< 0:00    _  [jfsCommit]

   15163  ? S< 0:00    _  [jfsSync]

在多处理器系统中,许多线程开始每个基础和限制上运行,并且只能运行在一个特定的处理器。这是代表一个斜杠和CPU的数量,附加在内核线程名称的后面。


虚拟和物理地址空间

大部分情况下,一个单一的虚拟地址空间比一个可适用于系统的物理RAM要大。并且当每个进程有自己独立的虚拟地址空间的时候,这种情况得不到改善。因此内核和CPU必须考虑实际可用的物理内存如何可以映射到虚拟内存的地址区域。原理如图1-6所示。

在图显示虚拟地址空间的两个进程由内核分成大小相等的部分。这些部分被称为页。物理内存也分为同样大小的页。    

1中的箭头指示在虚拟地址空间的页面是如何分布在整个物理页面的。例如,进程A虚拟第1被映射到物理第4页,而进程B的虚拟第1被映射到物理的第5页。这表明,虚拟地址改变他们从进程到进程间的含义。

物理页通常被称为页帧。相比之下,术语页面则说的是虚拟地址空间的页面。

虚拟地址空间和物理内存之间的映射也使进程间的严格分离被解除。我们的示例包括一个明确被两个进程所共享的页框。A进程的5和B进程的1页都指向物理页框5。这是有可能的,因为两个虚拟地址空间中的条目(尽管在不同的位置)指向同一个页面。由于内核负责映射虚拟地址空间到物理地址空间,所以能够决定哪些内存区域可以用作进程间共享,哪些不可以。

该图还显示,并非所有页的虚拟地址空间都对应一个页框。这可能是因为要么其他也没被用上或因为数据因为不需要而没有被加载到内存。也有可能在页面被换出到硬盘,并在需要的时候交换回来。

最后,注意到,有两个相等的条款,以解决代表用户运行的应用程序。其中之一是用户空间(userland),这命名法通常优选由BSD社区包揽所有的东西,不属于的内核本身。另一种是说运行在用户空间一个应用程序。它应该指出的是,userland这个词总是这样意味着应用程序,而术语userspace可以另外不仅表示应用程序,同时也代表他们正在执行于此的部分虚拟地址空间,相比于内核空间来说。

原创粉丝点击