venturing into protected-mode a first look at the cpu registers and instructions which provide the...
Post on 19-Dec-2015
226 views
TRANSCRIPT
Venturing into protected-mode
A first look at the CPU registers and instructions which provide the essential supporting infrastructure
A need for Diagnostics
• Upon entering protected-mode, the “rules” change regarding the allowed CPU actions
• Memory-addresses are computed using a different set of circuitry within the CPU
• Restrictions are enforced by generating a variety of “exceptions” which interrupt the CPU’s normal fetch-execute cycle
• We will need to “diagnose” their causes
Memory-addresses
• The first change programmers encounter when the CPU is switched into Protected Mode concerns the way in which the CPU constructs its memory-addresses (i.e., the segment registers play a different role)
• Some formerly “hidden” aspects of those segment-registers will come to the fore!
• (Some terminology also gets revised)
Real-Mode Addresses
segmentLogical Address: offset
Operand’s effective addressPhysical Address:
+ x16
While in Real-Mode, the memory-segments are all 64-kilobytes in size (and readable/writable)
Protected-Mode Addresses
segment-selectorLogical Address: segment-offset
Operand’s effective addressPhysical Address:
descriptor
descriptor
descriptor
descriptor
Segment Descriptor Table
+Segment Base-address
(also Segment-Limit and Access Rights)
Validity is checked by CPU
Segment-Descriptor Format
Base[31..24] G DRSV
AVL
Limit[19..16]
PDPL
S XC/D
R/
WA Base[23..16]
Base[15..0] Limit[15..0]
63 32
31 0
Several instances of this basic ‘segment-descriptor’ data-structure will occur in the Global Descriptor Table (and maybe also in some Local Descriptor Tables)
“Hidden” part of segment-registers
selector segment base segment limitaccessrights
The programmer-visible part of a segment-register
The “invisible” parts of a segment-register
Segment-Register “cache”
• The “hidden” portions of any segment-register will automatically be modified whenever any instruction places a new value in a segment-register’s visible part
• Examples (some obvious, some not):
mov %ax, %ds # new value from a general registerpop %es # new value from a word in memorylss tos, %esp # new value from a memory-pointerljmp $0x07C0, $main # new value from “immediate” dataint $0x13 # new value from interrupt vector tablelret # new value from the stack’s memory
Illegal segment-values
• In Real-Mode, any 16-bit value was ‘legal’ to be loaded into any segment-register
• But in Protected-Mode, the CPU doesn’t allow certain 16-bit values to be placed in certain particular segment-registers
• For example: the selector for a descriptor that isn’t ‘executable’ cannot go into CS, and one that’s legal for CS can’t go in SS
Special ‘system’ registers
• In protected-mode the CPU needs quick access to its important data-structures: – Memory-Segment Descriptors– Interrupt-Gate Descriptors– Call-Gate Descriptors– Task-State Descriptors– Page-Directory and Page-Table Descriptors
• So special CPU registers exist which are dedicated to locating those crucial items
GDT and IDT
• The two most vital system registers for protected-mode execution are:– GDTR (Global Descriptor Table Register)– IDTR (Interrupt Descriptor Table Register)
• Each of these is 48-bits wide and contains the base-address and segment-limit for an array of descriptors (the GDT and the IDT)
• Special instructions allow access to these registers: SGDT/LGDT and SIDT/LIDT
Addendum: The widths of these registers are larger if cpu supports ia32e.
IA-32: 48-bit Register-Format
Segment Base-AddressSegment
Limit
47 16 15 0
16 bits32 bits
System Relationships
descriptordescriptordescriptordescriptordescriptordescriptordescriptor
descriptordescriptordescriptordescriptordescriptordescriptordescriptor
descriptordescriptordescriptordescriptordescriptordescriptor
Interrupt Descriptor Table
Global Descriptor Table
GDTR
IDTR
LDT and TSS
• For protected-mode multitasking, the CPU needs to access two other data-structures:– The current Local Descriptor Table (LDT)– The current Task-State Segment (TSS)
• Again, special registers tell the CPU where to find these data-structures in memory (assuming protected-mode is enabled)
• And special instructions afford access to them: SLDT/LLDT and STR/LTR
Indirection
• Registers LDTR and TR are like segment-registers: they have a visible part (16-bits) and a “hidden” descriptor-cache part
• The programmer-visible portion of these two registers holds a “segment-selector” (i.e., an array-index into the GDT array)
• The hidden portion is updated from the GDT whenever these register get loaded
System Relationships
TaskState
Segment
descriptordescriptordescriptordescriptordescriptordescriptorGDTR
descriptordescriptordescriptordescriptordescriptordescriptor
Local Descriptor Table
descriptordescriptordescriptordescriptordescriptordescriptor
LDTR
TR
Global Descriptor Table
Reading LDTR and TR
• The LDTR and TR registers are not able to be accessed while executing in real-mode
• An “Undefined Opcode” exception (INT-6) will be generated if SLDT or STR opcodes are encountered in a “real-mode” program
• So to obtain the values in these registers, any bootsector program must temporarily enable protected-mode
Control Register 0
• Register CR0 is the 32-bit version of the MSW register (Machine Status Word)
• It contains the PE-bit (Protection Enabled)– when PE=0 the CPU is in real-mode – when PE=1 the CPU is in protected-mode
PG
CD
NW
AM
WP
NE
ET
TS
EM
MP
PE
Machine Status Word
Using the LMSW instruction
• You can use the LMSW instruction to turn on the PE-bit (enabling ‘protected-mode’)
• But you cannot use LMSW to turn off PE (i.e., PE was a “sticky bit” in the 80286)
• The Intel 80386 processor introduced a new name and enlarged size for the MSW
• Special version of the ‘MOV’ instruction can either enable or disable the PE-bit
How to enter protected-mode
This instruction-sequence turns on PE-bit:
Warning: you have to do this with interrupts
temporarily disabled -- since the real-mode
Interrupt Vector Table won’t work any more
mov %cr0, %eax # get current machine status bts $0, %eax # set the image of its PE-bitmov %eax, %cr0 # now enter protected mode
How to leave protected-mode
This instruction-sequence turns off PE-bit
Warning: you need to make sure that all of the segment-registers have proper access-rights and segment-limits in their caches tofunction correctly once back in real-mode!
mov %cr0, %eax # get current machine status btr $0, %eax # set the image of its PE-bitmov %eax, %cr0 # now leave protected mode
An observation
• If we can enter protected-mode, but NOT do anything to alter any segment-register, then we won’t need to construct Tables of Segment-Descriptors
• The left-over ‘real-mode’ descriptor-values will still be in any segment-register’s cache
• Let’s pursue this idea in a program ‘demo’
In-class exercises
• Can you modify the ‘ourfirst.s’ program so it will display the following register-values (in hexadecimal format, showing names)?– The 32-bit control-register CR0– The 48-bit system-register IDTR– The 16-bit segment-register TR