Transcript lesson27
Venturing into the x86’s
System Management Mode
An introduction to concepts
needed for writing and testing an
interrupt-handler for SMIs
The x86 operating ‘modes’
Virtual
8086
mode
64-bit
mode
Power
on
Real
mode
Protected
mode
System
Management
mode
IA-32e
mode
Compatibility
mode
Some purposes of SMM
• Provide a ‘transparent’ mechanism for the
hardware to perform various maintenance
functions related to conservation of power
or regulation of component temperatures
• Allow ‘emulation’ of hardware behaviors
when actual hardware is not installed or
not functioning (e.g., keyboard-input via
the network if a real keyboard is absent)
SMM ‘transparency’
• To function without any operating system
software being aware, the x86 processor
enters System Management Mode when
an external signal is delivered:
NMI
SMI
INTR
INIT
x86
processor
Using IPI messages
• It is also possible to trigger an SMI using
an Inter-Processor Interrupt (IPI) sent by
one of the Local-APICs, by writing to its
Interrupt Command Register
ICR (upper 32-bits)
destination
0xFEEE0310
ICR (lower 32-bits)
short
hand
01000 010
vector
0xFEEE0300
Delivery Mode = SMI
A ‘private’ address-space
• In response to an SMI signal, the CPU will
switch to a otherwise inaccessible memory
address-space, where it saves its current
register-values and from which it fetches
its subsequent machine-instructions
• The usual protection-mechanisms, such
as privilege-restrictions and limit-checks,
are disabled (operates as in ‘real mode’)
The CS and IP registers
• Upon entry to SMM, the CS register gets
modified (both its visible and hidden parts)
and the IP register gets set to 0x00008000
• Initially, after a system-reset, the value of
the SMBASE will be 0x00030000, but the
SMI interrupt-handler can setup another
value for any subsequent SMM entries –
an essential step in multiple-CPU systems
Initialization
EBDA
This arena must be
relocated to private
memory-space that
doesn’t overlap any
other processor’s
SMM memory area
Initial
SMM
segment
BOOT_LOCN
RBDA
IVT
0x30000
0x07C00
0x00400
0x00000
Classroom’s machines
one megabyte of the
4G physical memory
is carved out for use
only while a CPU is
executing in System
Management Mode
and is not accessible
during normal use
The ROM-BIOS decides
where to ‘relocate’ each
processor’s SMRAM on
a particular platform
(not a ‘standard’, and not
generally ‘documented’)
CPU 0
CPU 1
CPU 2
CPU
\ 3
0xDFFF0000
0xDFFE0000
0xDFFD0000
0xDFFC0000
System
Management
memory
0xDFF00000
4 GB
physical
memory
We wrote our own
‘smlayout.cpp’
application to learn
where the BIOS has
placed these arenas in
classroom’s machines
‘smram.c’
• We wrote this Linux device-driver module
to provide our application-programs with a
way to access the normally ‘inaccessible’
System Management Memory (details on
this are from Intel’s MCH Data Sheet)
• Some machines use a BIOS that ‘locks’
access to System Management Memory
(such as the DELL machines in CS Labs)
Using ‘fileview’
• Once you have compiled and installed our
‘smram.c’ device-driver, you can use the
familiar ‘fileview’ utility to view the current
contents of System Management Memory
• You can also use ‘fileview’ to look at the
graphics controller’s frame-buffer memory
once you have compiled and installed our
‘vram.c’ device-driver
System overview
user space
standard
runtime
libraries
kernel space
Linux
operating system
kernel
file subsystem
application
program
device driver module
physical memory
The code-structure for ‘smram.c’
smram.c
some header-files
some global data
#include <linux/module.h>
#include <linux/highmem.h>
…
char modname[ ] = “smram”;
int my_major = 87;
…
my_read()
my_write()
my_llseek()
…
my_fops
required module
administration
functions
module_init()
module_exit()
MODULE_LICENSE(“GPL”);
this module’s
‘payload’
(its ‘method’
functions
and its
‘file_operations’
structure)
‘smidemo.s’
• We wrote our own ‘interrupt-handler’ code
for any System Management Interrupts
• We wanted it to do something simple that
we would be able to perceive -- such as
displaying a message on the screen
• We encountered a number of obstacles,
requiring an understanding of the MCH,
the CRTC, the VRAM, and x86’s SMM
Text-mode console
• We normally use Linux’s graphical desktop
environment – but a drawing message for
the graphics display is quite complicated
• So we can use Linux’s text-mode console
• But Linux uses ‘hardware scrolling’ and the
MCH blocks accesses to the usual VRAM
in System Management Mode
• So we had to overcome these obstacles
The ATI frame-buffer
The manufacturer’s of video display controllers do not always follow the
same design-scheme for the arrangement of character-cells in text mode
Our classroom machines have ATI (Advanced Technology, Incorporated)
graphics hardware, where each character-cell is specified by a quadword
(i.e., 8 bytes) from the frame-buffer memory.
Byte 0
Byte 1
Byte 2
Byte 3
Byte 4
Byte 5
Byte 6
Byte 7
color
ASCII
attribute
code
byte
These are the
two bytes we
normally see
in the legacy
VRAM space
These bytes are not normally ‘mapped’ to the
legacy memory-addresses 0xB8000-0xBFFFF
but are used for storing the text-font bitmaps
which the ASCII-codes reference in text-mode
‘hardware scrolling’
• Linux normally disregards the ROM-BIOS
way of dividing text-mode display-memory
into ‘pages’ which each correspond to one
full text-mode screen-image – instead the
Linux scheme moves a ‘window’ over the
continuous segment of video memory
32-killobytes
of text-mode
video memory
currently
‘visible’
screen
current CRTC Start-Address (varies)
Where to draw?
• If we want to draw a message that will be
visible on the current text-mode console,
we need to use the current CRTC window
and we need to draw each character (and
color-attribute byte) to the first 2-bytes of
quadword-sized frame-buffer locations
0
8
16
24
32
H
E
L
L
O
Source-code ‘labels’
• Another obstacle we face is that assembly
language labels are assigned their values
based on the assumption that our code is
residing at offset zero in the CS-segment,
but in fact our SMI code will reside at the
offset 0x8000 from the CS segment-base
• So we either have to write a new ‘linkerscript’ or else adjust all offsets at runtime
Avoid long jumps/calls/interrupts
• If the BIOS has relocated the memory for
System Management Mode to an address
above the 1MB boundary, then we can’t
freely allow instructions that modify the CS
segment-register, since that will alter the
‘base-address’ field within the hidden part
of the CS segment-register in a way that
can’t be recovered using ‘real-mode’ style
segment-register loads (20-bit addresses)
Nevertheless…
• We’ve overcome the numerous obstacles
to a classroom demonstration of System
Management Mode from within Linux:
– Switch to a text console (CTRL-ALT-Fn)
– Execute the Linux ‘setfont’ command
– Install our ‘smram.ko’ kernel-module
– Load our ‘smidemo.b’ (using ‘smiload’)
– Execute our ‘issuesmi’ application
In-class exercise
• The Intel ‘SM Save State’ data-structure is
described in Intel’s programmer manuals
• Among the register-values automatically
saved on entering System Management
Mode is Control Register CR3 (used by
the CPU to find the Level4 Page-Table)
• It is saved at offset 0xfff0 from SMBASE
• Can you display its (64-bit) value?
Important!
DON’T FORGET TO DO A
‘COLD RESTART’
BEFORE YOU GO HOME TONIGHT