Understanding the Linux Kernel : Chapter 2, Memory Addressing
以下内容为本人的阅读笔记:注:参照了《Linux 内核源代码情景分析》的第一章和第二章内容。
2.1
(1).In multiprocessor systems or Even uniprocessor systems(with DMA), a hardware circuit called a memory arbiter is inserted between the bus and every RAM chip. Its role is to grant access to a CPU if the chip is free and to delay it if the chip is busy servicing a request by another processor.From the programming point of view, the arbiter is hidden because it is managed by hardware circuits.
硬件 arbiter 确保内存在同一时间只被一个CPU(or DMz)操作.
2.2. Segmentation in Hardware
注:Segmentation in Hardware 指intel微处理器的段方案。
(2)A logical address consists of two parts: a segment identifier and an offset that specifies the relative address within the segment. The segment identifier is a 16-bit field called the Segment Selector, while the offset is a 32-bit field.
逻辑地址由两部分组成:16位的段标识和32位的偏移。注:逻辑地址---(段转换)--->线性地址---(页转换)--->物理地址
(3)To make it easy to retrieve segment selectors quickly, the processor provides segmentation registers whose only purpose is to hold Segment Selectors; these registers are called cs, ss, ds, es, fs, and gs.
CPU的寄存器用来保存各个段的段标识(segment identifier or Segment Selector)。注:对于80 x 86,每个进程都有自己的代码段、堆栈段等等段,只有运行时才把他们的地址加载到cs, ss...
(4)Each segment is represented by an 8-byte Segment Descriptor that describes the segment characteristics. Segment Descriptors are stored either in the Global Descriptor Table (GDT ) or in the Local Descriptor Table(LDT).The address and size of the GDT in main memory are contained in the gdtr control register, while the address and size of the currently used LDT are contained in the ldtr control register.
每个段都有一个8字节长的段描述符(Segment Descriptors),保存在GDT 或 LDT.注:CPU可通过 gdtr/ldtr 找到GDT/LDT, 从而找到Segment Descriptors,最终找到段的内存地址。
(5)To speed up the translation of logical addresses into linear addresses, the 80 x 86 processor provides an additional nonprogrammable register.Every time a Segment Selector is loaded in a segmentation register, the corresponding Segment Descriptor is loaded from memory into the matching nonprogrammable CPU register.
非编程寄存器用于保存Segment Descriptors,因此CPU可快速找到段的内存地址。
2.3. Segmentation in Linux
注:Segmentation in Linux 主要讲分段机制的linux(OS)层控制;而更底层的实现参照Segmentation in Hardware.
(6)The 2.6 version of Linux uses segmentation only when required by the 80 x 86 architecture.Linux prefers paging to segmentation.
linux2.6 只有针对 80 x 86 架构才使用分段机制, 其余架构都用分页机制。
(7)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. The corresponding Segment Selectors are defined by the macros _ _USER_CS, _ _USER_DS, _ _KERNEL_CS, and _ _KERNEL_DS, respectively.
In some cases, however, processes may require to set up their own LDT. This turns out to be useful to applications (such as Wine) that execute segment-oriented Microsoft Windows applications.
Linux中所有用户进程都使用同一个代码段、数据段...,内核进程类似。由于段的数量减少,且这些段的段标识都是宏定义,因此查找速度更快。 而对于一些程序,如MS的wine程序,需要创建LDT,那么linux也支持。
2.4. Paging in Hardware
(8)The paging unit translates linear addresses into physical ones. One key task in the unit is to check the requested access type against the access rights of the linear address.
Paging单元负责将linear(virtual)地址转换为物理地址;同时检查访问权限。
(9)The paging unit thinks of all RAM as partitioned into fixed-length page frames.Each page frame contains a page that is, the length of a page frame coincides with that of a page. A page frame is a constituent of main memory, and hence it is a storage area. It is important to distinguish a page from a page frame; the former is just a block of data, which may be stored in any page frame or on disk.
Paging单元把物理内存看成具有固定长度的page frames(页框),而不是pages.
(10)The data structures that map linear to physical addresses are called page tables ; they are stored in main memory and must be properly initialized by the kernel before enabling the paging unit.
页表(page tables)是地址转换过程中的主要数据结构。
(11)The 32 bits of a linear address are divided into three fields -- Directory:The most significant 10 bits; Table:The intermediate 10 bits; Offset:The least significant 12 bits
linear(virtual)地址由3个字段组成。
(12)Clearly, PAE does not enlarge the linear address space of a process, because it deals only with physical addresses. Furthermore, only the kernel can modify the page tables of the processes, thus a process running in User Mode cannot use a physical address space larger than 4 GB. On the other hand, PAE allows the kernel to exploit up to 64 GB of RAM, and thus to increase significantly the number of processes in the system.
PAE 增加可用内存到64GB,但linear(virtual)地址的长度仍是32位,也即单个进程最多可用4GB内存.
2.5. Paging in Linux
(13)Linux adopts a common paging model that fits both 32-bit and 64-bitarchitectures. Starting with version 2.6.11, a four-level paging model has been adopted.
Linux位32位和64位的架构采用了统一的分页机制模型。从2.6.11版本开始,分页机制采用4级索引。
(14)As we will see in Chapter 9, each process has its own Page Global Directory and its own set of Page Tables.
每个进程都拥有私有的Page Global Directory 和 Page Tables.
(15)As a general rule, the Linux kernel is installed in RAM starting from the physical address 0x00100000 i.e., from the second megabyte. The total number of page frames required depends on how the kernel is configured. A typical configuration yields a kernel that can be loaded in less than 3 MB of RAM.
内核一般需要占用不到3M的内存。内核一般被加载到内存的第二个MB,第一个MB用来加载BIOS信息和其他用途 。
(16)Linear addresses from 0x00000000 to 0xbfffffff can be addressed when the process runs in either User or Kernel Mode.Linear addresses from 0xc0000000 to 0xffffffff can be addressed only when the process runs in Kernel Mode.
小于0xc0000000的3G大小的linear(virtual)地址用于程序的用户空间,而高位的1G用于程序的内核空间。注:0xc0000000这个值是宏,一般在内核编译时确定。
(17)In fact, right after the kernel image is loaded into memory, the CPU is still running in real mode; thus, paging is not enabled.
内核刚刚加载进RAM后,CPU依然工作在实模式(之后进入protected mode)。
(18)Linux Writes the physical address of swapper_pg_dir in the cr3 control register.
CR3存储当前进程的页面目录表.