Você está na página 1de 5

Paging&Segmentation:

Intel Pentium Vs Linux System


System and Device Programming, 2015/2016, Politecnico
di Torino Marilisa Montemurro
Talking about memory management, there are two possible approaches to separate
logical address space and physical address space (so that the user/programmer sees it as
linear, even if it is not):

segmentation

paging

Those are two different techniques, which can be used together but, considering that
they can both provide a different linear address space to each process, in a different
way, if one is used intensively, the other one should be used less. In fact, if segmentation
can allocate different segments to each process, paging can achieve separation by
mapping the same linear address space (one for each process) on different physic
address spaces.
That's why, Linux system, which is paging-oriented, uses segmentation in a very limited
way.
Let's now move on to analyze the mentioned techniques, using as a practical example,
Intel Pentium microprocessor, a 32-bit architecture which provides the possibility to
enable only segmentation or segmentation combined to paging.

Segmentation
Segmentation has been introduced with Intel 8086 cpu and it has become a standard for
Intel microprocessors.
The basic idea is the following: the addressing space is divided into segments with
different purposes. The segments are named as follows:

code segment (cs): it stores instructions

data segment (ds): it stores data

stack segment (ss): it stores the stack

plus some other segments ( i.e. es, fs, gs) which are general purpose.
Each segment has a starting address and a size which are combined in what is called
segment descriptor. A segment descriptor is a 8-byte word which is made of different

parts, but the most important ones are a 32-bit base address, which stores the physic
starting point of the segment, and a 20-bit limit field, which instead stores the size of
the segment.
The so-called Global Descriptor Table (GDT) stores all global segment descriptors of
the system. This table, apart from the just-mentioned segment descriptors, stores also
some other useful descriptors such as a TSS (task segment state) descriptor and a
Local Descriptor Table (LDT) descriptor (which is shared by user processes by default,
even if they can require more of them). The GDT base address is stored within the gdtr
reserved register (i.e. not for user programs) (a similar register is provided for LDT, i.e.
ldtr).

How can the CPU know which segment should be accessed?


The addresses produced by the CPU are called logic addresses. They are made of a 16bit segment selector and a 32-bit offset. Logic addresses are then translated into linear
addresses by the segmentation unit and passed to the paging unit which produces the
physical addresses.

The 16-bits segment selector is made of three parts:

RPL: 2 bits to indicate the requested privileged level

TI: 1 bit to indicate if the segment descriptor should be searched into the GDT or
into the LDT

INDEX: 13 bits to point to the right entry in one of the two mentioned tables.

The translation mechanism proceeds as follows:

the segment selector is stored into the segmentation register and, according to
TI field value, the right table is accessed.

The segment base address is combined with the INDEX field value an the linear
address is produced.

Finally, to avoid accessing the descriptor tables too many times, six
nonprogrammable registers are provided (one for each kind of segment) so that
the segment descriptor is stored on the motherboard and no additional memory
accesses are required.

Now that we have the linear address, we are ready to compute the physical address. If
paging is enabled, this is done by the paging unit.

Paging
Paging is a well-known mechanism that consists in dividing the logical address space into
logical pages which are mapped to portions of physical memory of the same dimension,
called frames. This mechanism allows a non-contiguos allocation of fixed size blocks in
main memory.
Paging mechanism is enabled by setting to 1 the PG flag within the cr0 reserved register.
The page mapping is managed through a hierarchy of tables.
Specifically, Pentium CPU's implement a two-levels paging.
Basically the 32-bits linear addresses are divided in this way:

directory page: 10-bits which point to a table whose entries are the base
addresses of the allocated page tables its base address is stored within cr3
reserved register;

page table: 10 bits used as an offset within the page table pointed by the
directory page;

offset: 12 bits used to move directly to the required offset within the required
page.

Summing up things we can easily understand that:

pages are 4kB large (212 = 4KB)

each page table is made of 1024 entries

1024 page tables can be created.

The reason why a multi-level paging has been adopted is quite easily understandable:
with one single page table, an addressing space of 2 32(i.e. 4GB) and 4kB pages, in order
to address the whole memory the page table should be made of 2 20 entries ( 232/212= 220),
meaning that it would have occupied 4MB in RAM (4 bytes for each entry). With a two-

levels hierarchy, instead, only necessary tables are allocated, so that memory occupation
is reduced.

The page table, apart from the frames base addresses, contains some additional
informations such as the kind of access privileges (write only, read only, execute only,
etc.) so that illegal accesses can be blocked. And also a validity bit: when it's cleared, the
corresponding page is not in main memory and it has to be retrieved from the disk. If a
process tries to access and invalid page a page fault exception is raised, the linear
address of the faulting page is stored into the cr2 register and the disk is accessed to
retrieve the missing page.
This is an overall picture of the described MMU:

Linux system
As I've anticipated, Linux uses segmentation in a limited way, because it uses paging in
an intense way.
In fact, it has only four segments: a code and a data segment for user processes and a
code and a data segment for kernel processes. Plus a Task Segment State for each
process and a LDT segment usually shared by all processes. The required descriptors are,
as usual, stored within a GDT.
As for paging, instead, Linux 32-bits systems implemented a three-levels paging up to
version 2.6.10. Starting with version 2.6.11 a four-levels paging mechanism has been
implemented.
As for the three-levels mechanism, the linear address is splitted in four parts:

global directory entry (pointed by cr3 register)

middle directory entry

page table entry

offset

With the four-levels mechanism, a level has been introduced between the global
directory and the middle directory, the upper directory.
Finally, the system, usually, keeps in memory the values of the first two entries because,
according to the locality principle (it's very likely that a process will access the same page
table that it has just accessed in the close future), the latency required to compute the
physical addresses is reduced.