A ‘protected-mode’ exploration

advertisement
A ‘protected-mode’ exploration
A look at the steps needed to build
segment-descriptors for displaying a
message while in protected-mode
Segment-Descriptor Format
63
32
Base[31..24]
RA
D
CR
Limit
GDSV
P P SX / / A
[19..16]
VL
L
DW
Base[15..0]
Base[23..16]
Limit[15..0]
31
0
Legend:
DPL = Descriptor Privilege Level (0..3)
G = Granularity (0 = byte, 1 = 4KB-page)
P = Present (0 = no, 1 = yes)
D = Default size (0 = 16-bit, 1 = 32-bit)
S = System (0 = yes, 1 = no)
X = eXecutable (0 = no, 1 = yes)
A = Accessed (0 = no, 1 = yes)
code-segments: R = Readable (0 = no, 1 = yes) C = Conforming (0=no, 1=yes)
data-segments: W = Writable (0 = no, 1 = yes) D = expands-Down (0=no, 1=yes)
RSV = Reserved for future use by Intel
AVL = Available for user’s purposes
Example: the ‘vram’ segment
• The video display-memory for color text
occupies a 32KB physical address-range
from 0x000B8000 to 0x000BFFFF
• It’s segment-limit can be described with
‘byte’ granularity as equal to 0x07FFF
(or with ‘page’ granularity as 0x00007 )
• It needs to be a ‘writable’ data-segment
• It’s privilege-level ought to be 0 (restricted)
Descriptor Implementations
00
0
0
92
0B
8000
7FFF
Using ‘byte’ granularity
00
8
8000
0
92
0B
0007
Using ‘page’ granularity
# vram-segment descriptor using ‘byte’ granularity
.word
0x7FFF, 0x8000, 0x920B, 0x0000
# vram-segment descriptor using ‘page’ granularity
.word
0x0007, 0x8000, 0x920B, 0x0080
Code and data segments
• Our program’s code and data will reside at
the base memory-address: 0x00010000
• For simplicity when returning to real-mode,
we can keep segment-limits as: 0x0FFFF
• Both segments can retain privilege-level 0
• Code-segment: ‘readable’ + ‘executable’
• Data-segment: ‘writable’ + ‘readable’
Descriptors implemented
data-segment descriptor
code-segment descriptor
00
00
0
0
92
01
0000
FFFF
Using ‘byte’ granularity
0
0000
0
9A
01
FFFF
Using ‘byte’ granularity
# data-segment descriptor using ‘byte’ granularity
.word
0xFFFF, 0x0000, 0x9201, 0x0000
# code-segment descriptor using ‘byte’ granularity
.word
0xFFFF, 0x0000, 0x9A01, 0x0000
Global Descriptor Table
• We can put all of our segment-descriptors
into the Global Descriptor Table
• Our program executes at privilege-level 0
• Every GDT must have a ‘null’ descriptor
• Thus our GDT will need four descriptors
.align
theGDT: .word
.word
.word
.word
8
# the Pentium requires ‘quadword’ alignment
0x0000, 0x0000, 0x0000, 0x0000 # ‘null’ descriptor
0xFFFF, 0x0000, 0x9A01, 0x0000 # code-descriptor
0xFFFF, 0x0000, 0x9201, 0x0000 # data-descriptor
0x7FFF, 0x8000, 0x920B, 0x0000 # vram-descriptor
GDTR register-format
47
16 15
0
Segment Base-Address
Segment
Limit
32 bits
16 bits
The register-image (48-bits) is prepared in a memory-location…
regGDT: .word
0x001F, theGDT, 0x0001
# register-image for GDTR
… then the register gets loaded from memory via a special instruction
lgdt
regGDT
# initializes register GDTR
segment-selector format
15
INDEX
3 2 1 0
T
RPL
I
16 bits
Legend:
RPL = Requested Privilege Level (0..3)
TI = Table Indicator (0 = GDT, 1 = LDT)
INDEX * 8 = number of bytes in table that precede the descriptor
segment-selectors defined
• Assembly language source-code is easier
for humans to read if meaningful symbols
are used as names for ‘magic’ numbers
# These ‘equates’ provide symbolic names for our segment-selectors
.equ
.equ
,equ
sel_cs0, 0x0008
sel_ds0, 0x0010
sel_es0, 0x0018
# code-segment selector
# data-segment selector
# vram-segment selector
Our ‘pmhello.s’ demo
• Use these commands to assemble, link,
and install our ‘demo’ program (in class):
$ as pmhello.s –o pmhello.o
$ ld pmhello.o -T ldscript -o pmhello.b
$ dd if=pmhello.b of=/dev/sda4 seek=1
• It also needs a ‘boot-sector’ program that
can ‘load’ it at the proper memory-address
and then transfer control to its ‘entry-point’
Our ‘quikload.s’ loader
• We have provided a ‘boot-sector’ program
that you can use in our classroom or labs
(it’s not designed to work at other places),
or you can use your own ‘loader’ program
• Here’s how to assemble, link, and install
our ‘quikload.s’ example:
$ as quikload.s -o quikload.o
$ ld quickload.o -T ldscript -o quikload.b
$ dd if=quikloab.b of=/dev/sda4
In-class exercise-set #1
• Find out what will happen if you modify the
segment-descriptor for video memory so it
uses ‘page’ granularity for its limit-field
• Find out what will happen if you do NOT
set the ES-register’s segment-limit to 64K
before clearing the PE-bit in register CR0
• Find out what will happen if you change
the DPL and/or RPL to values other than 0
In-class exercise-set #2
• Redesign the ‘pmhello.s’ program so that it
expects to be loaded at a higher address:
– Say at address: 0x00040000 (i.e., at 256KB)
– Say at address: 0x01000000 (i.e., at 16MB)
• You will need to change the ‘disk-address
packet’ in our ‘quikload.s’ program so that
it will transfer your ‘pmhello.b’ code from
the disk to your higher memory address
Download