Chinaunix首页 | 论坛 | 博客
  • 博客访问: 56220
  • 博文数量: 47
  • 博客积分: 2095
  • 博客等级: 大尉
  • 技术积分: 560
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-01 18:42
文章分类

全部博文(47)

文章存档

2011年(1)

2008年(46)

我的朋友

分类: LINUX

2008-04-02 23:56:57

Segmentation in Linux

Segmentation has been included in 80x86 microprocessors to encourage programmers to split their applications into logically related entities, such as subroutines or global and local data areas. However, Linux uses segmentation in a very limited way. In fact, segmentation and paging are somewhat redundant, because both can be used to separate the physical address spaces of processes: segmentation can assign a different linear address space to each process, while paging can map the same linear address space into different physical address spaces. Linux prefers paging to segmentation for the following reasons:

x86的段式内存管理鼓励程序员将他们的应用程序分成逻辑上关联的实体,比如子程序或者全局/局部数据区。然而Linux有限地利用了这种方式。事实上,段式管理和页式管理有一点重复,两种方式都是将进程的物理空间划分成若干独立的部分:段式管理分配一个不同的线形地址空间给每一个进程,而页式管理可以映射相同的线形地址空间到不同的物理地址空间上。Linux采用页式管理是因为如下的原因:

·         Memory management is simpler when all processes use the same segment register values that is, when they share the same set of linear addresses.

           当所有进程都使用同样的段寄存器的内存时,也就是说它们共享同一个线形地址空间,内存管理更加简单,

·         One of the design objectives of Linux is portability to a wide range of architectures; RISC architectures in particular have limited support for segmentation.

           Linux的一个设计目标是可以移植到不同架构的平台上,RISC架构对段式管理的提供了很局限的支持。

The 2.6 version of Linux uses segmentation only when required by the 80x86 architecture.

Linux2.6只在x86架构上使用段式管理(因为它没法避开)

All Linux processes running in User Mode use the same pair of segments to address instructions and data. These segments are called user code segment and user data segment , respectively. Similarly, all Linux processes running in Kernel Mode use the same pair of segments to address instructions and data: they are called kernel code segment and kernel data segment , respectively. Table 2-3 shows the values of the Segment Descriptor fields for these four crucial segments.

所有运行在用户模式的Linux进程都是用同样的段来寻址指令和数据,它们分别被称为用户代码段和用户数据段。同样地,所有运行在内核模式的Linux进程也都分别使用同样的内核代码段和内核数据段来寻址指令和数据。表2-3展现了这四个关键段的段描述的内容:
 
Table 2-3. Values of the Segment Descriptor fields for the four main Linux segments
Segment      Base       G   Limit   S   Type   DPL   D/B   P
user code    0x00000000 1   0xfffff 1   10     3     1     1
user data    0x00000000 1   0xfffff 1   2      3     1     1
kernel code  0x00000000 1   0xfffff 1   10     0     1     1
kernel data  0x00000000 1   0xfffff 1   2      0     1     1

The corresponding Segment Selectors are defined by the macros _ _USER_CS, _ _USER_DS, _ _KERNEL_CS, and _ _KERNEL_DS, respectively. To address the kernel code segment, for instance, the kernel just loads the value yielded by the _ _KERNEL_CS macro into the cs segmentation register.

对应的段选择子分别用宏_ _USER_CS, _ _USER_DS, _ _KERNEL_CS_ _KERNEL_DS定义。比如,当要寻址内核代码段时,内核只需将宏_ _KERNEL_CS代表的值放入CS段寄存器中。

Notice that the linear addresses associated with such segments all start at 0 and reach the addressing limit of 232 -1. This means that all processes, either in User Mode or in Kernel Mode, may use the same logical addresses.

注意与这些段对应的线形地址都是从0开始而且地址空间长度为2^321。这意味着所有的进程,不管在用户模式还是在内核模式,都使用同样的线形地址空间。

Another important consequence of having all segments start at 0x00000000 is that in Linux, logical addresses coincide with linear addresses; that is, the value of the Offset field of a logical address always coincides with the value of the corresponding linear address.

另外,Linux所有的段都从0x00000000开始产生的一个重要的结果就是:逻辑地址与线形地址对应;也就是说,逻辑地址的offset字段总是与对应的线形地址的值是相等的。

As stated earlier, the Current Privilege Level of the CPU indicates whether the processor is in User or Kernel Mode and is specified by the RPL field of the Segment Selector stored in the cs register. Whenever the CPL is changed, some segmentation registers must be correspondingly updated. For instance, when the CPL is equal to 3 (User Mode), the ds register must contain the Segment Selector of the user data segment, but when the CPL is equal to 0, the ds register must contain the Segment Selector of the kernel data segment.

CPU的当前执行权限CPL,由存储在段寄存器CS的段选择子的RPL字段指明,指示了处理器是否是处在内核模式。无论何时CPL发生了变化,一些段寄存器必须相应地更新。比如,当CPL等于3时(用户模式),DS寄存器必须存放用户数据段的段选择子,而当CPL等于0时,DS寄存器必须存放内核数据段的段选择子。

A similar situation occurs for the ss register. It must refer to a User Mode stack inside the user data segment when the CPL is 3, and it must refer to a Kernel Mode stack inside the kernel data segment when the CPL is 0. When switching from User Mode to Kernel Mode, Linux always makes sure that the ss register contains the Segment Selector of the kernel data segment.

SS寄存器也存在相同的情形。当CPL等于3时,它必须指向用户数据段内的一个用户模式栈,而当CPL等于0时,它必须指向内核数据段内的一个内核模式栈。当从用户模式切换当内核模式时,Linux总是保证SS段寄存器存放内核数据段的段选择子。

When saving a pointer to an instruction or to a data structure, the kernel does not need to store the Segment Selector component of the logical address, because the ss register contains the current Segment Selector. As an example, when the kernel invokes a function, it executes a call assembly language instruction specifying just the Offset component of its logical address; the Segment Selector is implicitly selected as the one referred to by the cs register. Because there is just one segment of type "executable in Kernel Mode," namely the code segment identified by __KERNEL_CS, it is sufficient to load __KERNEL_CS into cs whenever the CPU switches to Kernel Mode. The same argument goes for pointers to kernel data structures (implicitly using the ds register), as well as for pointers to user data structures (the kernel explicitly uses the es register).

当保存一个指向指令或数据结构的指针时,内核不需要保存其逻辑地址的段选择子成分,因为SS寄存器包含了当前的段选择子。例如,当内核调用一个函数时,它会执行一条仅指明该函数逻辑地址的offset字段的汇编指令call,段选择子默认由CS寄存器决定。因为只存在一个“内核模式下可执行”的段,也就是_ _KERNEL_CS表示的代码段,当CPU从用户模式切换到内核模式时,将_ _KERNEL_CS放入CS寄存器中就足够了。同样的情况也适合于指向内核数据结构的指针(默认使用DS寄存器),指向用户数据结构的指针(内核清楚表明使用ES寄存器)。

Besides the four segments just described, Linux makes use of a few other specialized segments. We'll introduce them in the next section while describing the Linux GDT.

除了刚才描述的4个段外,Linux还使用了一些其他特殊的段,将在下面介绍。

阅读(369) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~