《Understanding the Linux kernel》学习笔记 Chapter 2: Memory Addressing

Memory Addresses

When dealing with 80x86 microprocessor, we have to distinguish three kinds of addresses: logical address, linear address (also known as virtual address) and physical address.


Segmentation in Hardware

Segment Selectors and Segmentation Registers

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.


Segment Descriptors

Each segment is represented by an 8-byte Segment Descriptor that describe 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.

There are several types of segments, and thus several types of Segment Descriptors (Code Segment Descriptor, Data Segment Descriptor, Task State Segment Descriptor, and Local Descriptor Table Descriptor).


Fast Access to Segment Descriptors

Every time a Segment Selector is loaded in a segment register, the corresponding Segment Descriptor is loaded from memory into the matching nonprogrammable CPU register.


Segmentation Unit

The segmentation unit performs the following operations:

  • Examines the TI field of the Segment Selector to determine which Descriptor Table stores the Segment Descriptor.
  • Computes the address of the Segment Descriptor from the index field of the Segment Selector.
  • Adds the offset of the logical address to the Base field of the Segment Descriptor, thus obtaining the linear address.
Notice that, thanks to the nonprogrammable registers associated with the segmentation registers, the first two operation need to be performed only when a segmentation register has been changed.

Segmentation in Linux

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 space 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 space.

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 segement and kernel data segment, respectively.


The Linux GDT

In uniprocessor systems there is only one GDT, while in multiprocessor systems there is one GDT for every CPU in the system.

Each GDT includes 18 segment descriptors and 14 null, unused, or reserved entries.

The 18 segment descriptors included in each GDT point to the following segments:

  • Four user and kernel code and data segments.
  • A Task State Segment (TSS), different for each processor in the system.
  • A segment including the default Local Descriptor Table (LDT), usually shared by all processes.
  • Three Thread-Local Storage (TLS) segments.
  • Three segments related to Advanced Power Management (APM).
  • Five segments related to Plug and Play (PnP) BIOS services.
  • A special TSS segment used by the kernel to handle "Double fault" exceptions.

The Linux LDTs

Most Linux User Mode applications do not make use of a Local Descriptor Table, thus the kernel defines a default LDT to be shared by most processes.

Call gates are a mechanism provided by 80x86 microprocessors to change the privilege level of the CPU while invoking a predefined function.


Paging in Hardware

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 uint.


Regular Paging

Starting with the 80386, the paging unit of Intel processors handles 4KB pages.

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).

The translation of linear addresses is accomplished in two steps, each based on a type of translation table. The first translation table is called the Page Directory, and the second is called the Page Table.

The entries of Page Directories and Page Tables have the same structure. Each entry includes the following fields: Present flag, Field containing the 20 most significant bits of a page frame physical address, Accessed flag, Dirty flag, Read/Write flag, User/Supervisor flags, PCD and PWT flags, Page Size flag, Global flag.


Extended Paging

Starting with the Pentium model, 80x86 microprocessors introduce extended paging, which allows page frames to be 4 MB instead of 4 KB in size.


Hardware Protection Scheme

Only two privilege levels are associated with pages and Page Tables.

Only two types of access rights (Read and Write) are associated with pages.


The Physical Address Extension (PAE) Paging Mechanism

PAE is activated by setting the Physical Address Extension (PAE) flag in the cr4 control register. The Page Size (PS) flag in the page directory entry enables large page sizes (2 MB when PAE is enabled).


Paging for 64-bit Architectures

Two-level paging is not suitable for computers that adopt a 64-bit architecture.


Hardware Cache

Hardware cache memories were introduced to reduce the speed mismatch between CPU and RAM. They are based on the well-known locality principle, which holds both for programs and data structures.


Translation Lookaside Buffers (TLB)

Besides general-purpose hardware caches, 80x86 processors include another cache called Translation Lookaside Buffers (TLB) to speed up linear address translation.


Paging in Linux

Linux's handling of processes relies heavily on paging. In fact, the automatic translation of linear addresses into physical ones makes the following design objectives feasible:

  • Assign a different physical address space to each process, ensuring an efficient protection against addressing errors.
  • Distinguish pages (groups of data) from page frames (physical addresses in main memory).

The Linear Address Fields

PAGE_SHIFT Specifies the length in bits of the Offset field; when applied to 80x86 processors, it yields the value 12.

PMD_SHIFT The total length in bits of the Offset and Table fields of a linear address; in order words, the logarithm of the size of the area a Page Middle Directory entry can map.

PUD_SHIFT Determines the logarithm of the size of the area a Page Upper Directory entry can map.

PGDIR_SHIFT Determines the logarithm of the size of the area that a Page Global Directory entry can map.

PTRS_PER_PTE, PTRS_PER_PMD, PTRS_PER_PUD, and PTRS_PER_PGD Computer the number of entries in the Page Table, Page Middle Directory, Page Upper Directory, and Page Global Directory.


Page Table Handling

Physical Memory Layout

As a general rule, the Linux kernel is installed in RAM starting from the physical address 0x00100000 -- i.e., from the second megabyte.

A typical configuration yields a kernel that can be loaded in less than 3 MB of RAM.


Process Page Tables

The linear address space of a process is divided into two parts:

  • 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.

Kernel Page Tables

Provisional kernel Page Tables

A provisional Page Global Directory is initialized statically during kernel compilation, while the provisional Page Tables are initialized by the startup_32() assembly language function defined in arch/i386/kernel/head.S.


Final kernel Page Table when RAM size is less than 896 MB

Final kernel Page Table when RAM size is between 896 MB and 4096 MB

Final kernel Page Table when RAM size is more than 4096 MB

Fix-Mapped Linear Addresses

Basically, a fix-mapped linear address is a constant linear address like 0xffffc000 whose conrresponding physical address does not have to be the linear address minus 0xc0000000, but rather a physical address set in an arbitrary way.


Handling the Hardware Cache and the TLB

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值