home *** CD-ROM | disk | FTP | other *** search
-
-
- A CRASH COURSE IN PROTECTED MODE
-
-
- By Adam Seychell
-
-
- After my release of DOS32 V1.2 a lot of people were asking for basic
- help in protected mode programming. If you already know what a selector is
- then there is probably no need for you to read this file.
-
- Ok you know all about the 8086 ( or a 386 in real mode ) architecture
- and what to know about this fantastic protected mode stuff. I'll start off
- saying that I think real mode on the 386 is like driving a car that is stuck
- in first gear. There is the potential of a lot of power but it is not being
- used. It really degrades the 386 processor and was not designed to normally
- operate in this mode. Even the Intel data book states "Real mode is required
- primarily to set up the processor for Protected Mode operation".
-
-
-
-
- SEGMENTATION OF THE INTEL 80x86
-
- A segment is a block of memory that starts at a fixed base address and
- has a set length. As you should already know that *every* memory reference
- by the CPU requires both a SEGMENT value and a OFFSET value to be specified.
- The OFFSET value is the location relative to the base address of the segment.
- The SEGMENT value contains the information for the segment. I am going to
- explain very basically how this SEGMENT value is interpreted by the 80386 to
- give the parameters of segments.
-
-
- In protected mode this SEGMENT value is interpreted completely different
- than in real mode and/or Virtual 86 mode. The SEGMENT values are now called
- "selectors". You'll see why when finished reading this file. So whenever you
- load a segment register you are loading it with a selector.
-
-
-
- The Selector is word length and contains three different fields.
-
- Bits 0..1 Request Privilege level ( just set this to zero )
-
- Bit 2 Table Indicator 0 = Global Descriptor Table
- 1 = Local Descriptor Table
-
- Bits 3..15 The INDEX field value of the desired descriptor in the GDT
- This index value points to a descriptor in the table.
-
-
-
-
-
-
-
-
-
- The GLOBAL DESCRIPTOR TABLE (GDT)
-
- The Global Descriptor Table ( GDT ) is a table of DESCRIPTORS and it is
- stored in memory. The address of this table is given in a special 386
- register called the global descriptor table register. There always must be a
- GDT when in protected mode because it is in this table where all of the
- segments are defined.
- Each DESCRIPTOR ( stored in the GDT ) contains the complete information
- about a segment. It is a description of the segment. Each Descriptor is 64
- bits long and contains many different fields. I'll explain the fields later.
- The INDEX field ( stored in bits 3..15 of any segment register ) selects a
- descriptor to use for the type of segment wanted. So the only segments the
- programmer can use are the available descriptors in the GDT.
-
-
- Example:
- Suppose you what to access location 012345h in your data segment and
- you were told that the descriptor for your data segment is descriptor
- number 6 in the Global Descriptor Table. Assume that the Global Descriptor
- Table has already been set up and built for you ( example, as in DOS32).
-
- Solution:
- We need to load a segment register (SS,DS,FS,GS,ES) with a value so
- that it will select (or index ) descriptor number 6 of the GDT. Then
- reference the address with a instruction that will use this loaded
- segment register.
-
- One of the segment registers (FS,DS,GS,SS,CS or ES) must be loaded with the
- following three fields,
-
- Request Privilege level ( Bits 0..1 ) = 0 (always)
- Table Indicator ( bit 2 ) = 0
- Index ( bits 3..15 ) = 6
-
-
- mov ax,0000000110000b ;load DS with the selector value
- mov ds,ax
- mov byte ptr DS:[ 012345h ],0 ; Using the DS segment register
-
-
-
- The 386 has hardware for a complete multitasking system. There are
- several different types of descriptors available in the GDT for managing
- multitasking. You don't need to know about all the different descriptors just
- to program in protected mode. Just the info above is enough. All you need to
- know to program in protected mode is what descriptors are available to you
- and what are the selector values to these descriptors. The base address of
- the segment may also be known. See the file DOS32.DOC for obtaining the
- selector values.
-
- There are two groups of descriptors
- 1) CODE/DATA descriptors which are used for any code and data segments.
-
- 2) SYSTEM descriptors are used for the multitasking system of the 386. These
- type of descriptors will never need to be used for programming applications.
-
-
-
- Format of a code and data descriptor
-
- BITS description if the field
- ----------------------------------------------------------------
- 0..15 SEGMENT LIMIT 0...15
- 16..39 SEGMENT BASE 0..23
- 40 (A) accessed bit
- 41..43 (TYPE) 0 = SEE BELOW
- 44 (0) 0 = code/data descriptor 1 = system descriptor
- 45..46 (DPL) Descriptor Privilege level
- 47 (P) Segment Present bit
- 48..50 SEGMENT LIMIT 16..19
- 51..52 (AVL) 2 bits available for the OS
- 53 zero for future processors
- 54 Default Operation size used by code descriptors only
- 55 Granularly: 1 = segment limit = limit field *1000h
- 0 = segment limit = limit field
- 56..63 SEGMENT BASE 24..31
-
- format of TYPE field
- bit 2 Executable (E) 0 = Descriptor is data type
- 1 Expansion Direction (ED) 0 = Expand up
- 1 = Expand up
- 0 Writeable (W) W = 0 data segment is read only
- W = 1 data segment is R/W
-
-
- bit 2 Executable (E) 1 = Descriptor is code type
- 1 Conforming (C) ( I don't understand )
- 0 Readable (R) R = 0 Code segment execute only
- R = 1 Code segment is Readable
-
-
- I'd better stop here, I am confusing myself. As you can see there is
- more to a segment that just it's base address and limit.
- The three descriptors that are available in DOS32 all have limits of
- 0ffffffffh (4GB). This means that the offsets can be any value.
- For example, the instruction XOR EAX,ES:[0FFFFFFFFh] is allowed.
- If you happen to load an invalid selector value into one of the segment
- registers then the 386 will report an General Protection exception
- ( interrupt 13 ). In protected mode this exception is also used for many
- other illegal operations.
-
-
-
- The LINEAR ADDRESS and PHYSICAL ADDRESS
-
- All the address translations described above is done by the 386
- segmentation unit. The segmentation unit looks up the descriptor tables,
- segment selectors, offsets and then outputs a 32bit linear address. This
- linear address is calculated by the segmentation unit in the following
- manner.
-
- Linear address = base address of segment + offset.
- The segment base address is found in the Base address field ( bits 16..39 &
- 56..63 ) of a descriptor which is located in the Global Descriptor Table.
- The index field ( bits 3..15) of the segment register selects the descriptor
- to use.
-
-
- An example of the linear address of the instruction.
-
- MOV EAX, ES:[EDX*8+012345678h]
-
- where EDX = 100h and ES equals a selector wich points to a descriptor with
- the base field equal to 02000000h.
-
- The linear address = 2000000h + ( 100h*8 + 012345678h ) = 014345E78h
-
-
- Just to make things even more complicated the 386 has an second memory
- managing unit called the Paging Unit. The linear address calculated above may
- still not be the physical RAM location the 386 is addressing. This linear
- address has yet to go through another stage, the paging unit. If you are
- having trouble with what I've said so far then you may want to take a coffee
- break before continuing because this is even worse.
-
- The 32bit linear address is directed to the paging unit. The paging unit
- divides the linear address into three sections.
-
- bits 0..12 Offset in a page
- bits 13..23 Points to the page entry in the page table
- bits 24..31 Points to the directory entry in the page directory table
-
- The page table contains 1024 double word entires. In each of these entries
- is the physical address of a 4KB page. The page directory also contains 1024
- double word entries. Each of these directory entries hold a physical address
- of a page table. See intel Documentation for the exact format of the page
- table entries and directory table entries. The physical base address of the
- DIRECTORY TABLE is in control register 3 ( CR3 )
-
- This means if every entry in the directory table is used then there would
- be 1024 page tables available. Because each page table hold 1024 page
- addresses then there would be a total of 1024*1024 4KB pages.
- The addresses in the page tables are all physical addresses. i.e the output
- of the CPU address bus pins. The paging unit can be enabled or disabled
- depending on wether bit 31 of CR0 is set. If the paging in disabled then the
- linear address simply equals the physical address. If paging is enabled the
- the linear address is translated by the paging unit to form a physical
- address. Please note that it is possible to set up the page tables and
- directory such that the linear address equals the physical address. This is
- what DOS32 does for the first 1MB of linear address space.
- If you can not understand my hopeless attempt of describing the paging unit
- then the diagram below might help.
-
-
-
-
-
-
-
-
-
-
-
-
-
- The 32 bit linear address from the segmentation unit
- -------------------------------------------------------------------------
- | BITS 0..12 | BITS 13..23 | BITS 24..31 |
- | | | |
- -------------------------------------------------------------------------
- | | |
- |------------------------ | |
- | | |
- | | |
- | | |
- A Page in memory (4KB) | | |
- -------------------------- | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | <------- | |
- | | | |
- | | | |
- | | | |
- |---> ------------------------- | |
- | | |
- | | |
- | | |
- | PAGE TABLE Offset | |
- | -------------------------- | |
- | | | 4092 | |
- | -------------------------- | |
- | . . | |
- | . . | |
- | . . | |
- | -------------------------- | |
- | | | 12 | |
- | -------------------------- | |
- |---<| address of page | 8 <--------- |
- -------------------------- |
- | | 4 |
- -------------------------- |
- | | 0 |
- |--> -------------------------- |
- | |
- | |
- | |
- | |
- | |
- | DIRECTORY TABLE Offset |
- | -------------------------- |
- | | | 4092 |
- | -------------------------- |
- | . . |
- | . . |
- | . . |
- | -------------------------- |
- |---<| address of page table | 12 <-----------------------------
- --------------------------
- | | 8
- --------------------------
- | | 4
- --------------------------
- | | 0
- |--> --------------------------
- |
- |
- |
- | ----------------------------------------------
- --------<-| CR3 |
- ----------------------------------------------
-
-
-
-
-
-
-
- This was only meant to be a rough introduction to the protected mode
- segmentation mechanism of the 80386+. I hope I did not make this sound
- too complicated so that you have been put off with the whole idea of
- protected mode programming. If you want to know more then I suggest you buy a
- book on the 80386. The "Intel Programmers Reference guide" is the most
- detailed book around. The info here is only meant to give you an idea of how
- protected mode works.
- Please note that DOS32 does *ALL* of the setting up needed for protected
- mode. Don't worry if you couldn't understand half the stuff I was talking
- about. You don't have to know about any stupid things like the descriptor
- format, selector index fields, privilege levels ,paging, tables, ect , ect.
- What you do need to know are the selector values for all the descriptors that
- are available to your program. Then the segment registers can simply be
- loaded with these known selector values. DOS32 uses only 3 descriptors ( or
- segments ) as described in DOS32.DOC.
-