Date post: | 18-Dec-2015 |
Category: |
Documents |
View: | 216 times |
Download: | 1 times |
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’
Realmode
Protectedmode
IA-32e mode
Virtual8086mode
SystemManagement
mode
64-bitmode
Compatibilitymode
Power on
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:
x86 processor
NMI
INTR
INIT
SMI
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
vector01000shorthand
destination 010
Delivery Mode = SMI
0xFEEE0310 0xFEEE0300
ICR (upper 32-bits) ICR (lower 32-bits)
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
IVTRBDA
BOOT_LOCN
InitialSMM
segment0x30000
0x00000
0x00400
0x07C00
EBDA
This arena must be relocated to private memory-space that doesn’t overlap any other processor’s SMM memory area
4 GB physicalmemory
Classroom’s machines
\System
Managementmemory
CPU 0
CPU 1
CPU 2
CPU 3
0xDFFF0000
0xDFFE0000
0xDFFD0000
0xDFFC0000
0xDFF00000
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’)
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
physical memory
device driver module
Linux operating system
kernel
file subsystem
application program
standard runtime libraries
user space kernel space
The code-structure for ‘smram.c’#include <linux/module.h>#include <linux/highmem.h>…char modname[ ] = “smram”;int my_major = 87;…
MODULE_LICENSE(“GPL”);
smram.c
module_init()
module_exit()
my_write()
some header-files
some global data
this module’s ‘payload’ (its ‘method’ functions and its ‘file_operations’ structure)
required module administration functions
my_llseek()
my_fops
my_read()
…
‘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
ASCIIcode
colorattribute
byte
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
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
H E L L O
0 8 16 24 32
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 ‘linker-script’ 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