Getting Ready to Enter x86 Protected Mode

advertisement
Understanding POST and
ROM-BIOS service functions
Numerous low-level services are
available to real-mode programs
(include boot-loaders)
Power-On Self-Test (POST)
• When computer is first turned on, the CPU
starts executing instructions in ROM-BIOS
• Reset-address: CS=0xF000, EIP=0xFFF0
• Initial routines perform vital functions:
– Verify amount of installed read/write memory
– Setup the table of real-mode interrupt-vectors
– Detect and initialize the peripheral equipment
– Setup parameters in the BIOS DATA AREA
• Read in, and transfer to, the ‘boot-loader’
Memory Layout during POST
Beginning…
ROM-BIOS
1MB
The POST creates the
Interrupt Vector Table
and fills in parameters
of the Bios Data area
…Finished
ROM-BIOS
VRAM
VRAM
RAM
RAM
Boot-loader
BIOS DATA
IVT
POST finishes up
by reading in the
boot-loader from
a storage device
Two demo-programs
• The program ‘showivt.cpp’ lets you look at
the table of (real-mode) interrupt vectors
(addresses 0x00000000 to 0x00000400)
• The program ‘showrbda.cpp’ lets you see
the parameter-values that the ROM-BIOS
has stored in its ROM-BIOS DATA-AREA
(addresses 0x00000400 to 0x00000500)
• A special device-driver (named ‘dos.o’) is
needed for accessing these memory areas
ROM-BIOS service-functions
• During POST, the startup routines need to
use various low-level system-services:
– To show diagnostic messages on the display
– To accept keystroke-commands from a user
– To query the real-time clock/calendar device
– To optionally send important data to a printer
– To read in a data-sector from the boot device
• The actions are performed as subroutines
Space in ROM is ‘tight’
• Size of a typical ROM-BIOS chip is 64KB
• Needs to store the instructions and data
for several hundred different functions
• So cannot afford to waste precious space
• Routines are written in assembly language
• Clever coding is used to optimize storage
usage (e.g., ROM functions get invoked by
software-interrupt instructions (2-bytes) as
an alternative to subroutine-calls (3-bytes)
Services remain available
• All of the low-level ROM-BIOS services
remain available to Real-Mode programs
• This includes ‘boot-loader’ programs
• If we’re going to write our own boot-loader,
we will benefit by knowing what low-level
services are already available in ROM (as
we will face tight space limitations, too:
namely, the 512-byte disk sector-size)
Catalog of ROM-BIOS services
•
•
•
•
•
•
int 0x10: video display services
int 0x11: equipment-list service
int 0x12: memory-size service
int 0x13: disk input/output services
int 0x14: serial communications services
int 0x15: system software services
ROM-BIOS services (continued)
•
•
•
•
•
int 0x16: keyboard input/control services
int 0x17: parallel-port printer services
int 0x18: diskless bootstrap service
int 0x19: system reboot service
int 0x1A: real-time clock services
Example: Get Memory Size
• When it’s time to load an operating system
the ‘OS-loader’ will need to know where it
can place the OS code and data so as to
efficiently fit within the system’s memory
• So the question will be: How much actual
ram is available?
• One of the simplest ROM-BIOS services
can be invoked to get the answer.
Calling ‘Get Memory Size’
• No service-parameters are required
• Just execute an ‘int 0x12’ instruction
• Size of the available ram is returned in AX
(expressed in kilobytes: 1KB=1024 bytes)
• Program-code looks like this:
int 0x12
; call BIOS service
mov kb_ram, ax
; save return-value
How does it work?
• Executing ‘int 0x12’ transfers control to an
Interrupt Service Routine within the ROM
• The CPU gets the entry-point for this ISR
from the Interrupt Vector Table (IVT)
• The IVT has enough room for 256 ‘vectors’
(all vectors use a doubleword of storage)
• The number 0x12 is an array-index for IVT
• Example: vector 0x12 equals 0xF000F841
Here’s the ISR’s code
isr_0x12:
push ds
; preseve DS
mov ax, #0x40 ; address BD area
mov ds, ax
; using DS register
mov ax, [0x0013] ; get POST param
pop ds
; restore DS
iret
; return from ISR
Demo Program: ‘memsize.s’
• We wrote a simple boot-sector program to
illustrate the ‘Get Memory Size’ service
• It executes ‘int 0x12’ to obtain the amount
of usable real-mode memory (in kilobytes)
• It converts the binary value obtained in AX
to its decimal representation as a string of
ascii characters, and ‘int 0x10’ functions to
display the information in readable form
In-Class Exercise #1
• Write a similar boot-sector demo program
that will display the Equipment-Check List
(a bitmap showing some installed devices
that’s returned in AX if ‘int 0x11’ executes)
• You can look at our ‘showmsw.s’ demo as
a guide to writing your assembler code
Equipment List Bitmap
15 14 13 12
11 10
9
8
7
6
5
4
3
2
1
0
Internal modem
(1=yes, 0=no)
Number of printer-ports
Number of serial-ports
Number of diskette drives (if bit 0 is set)
(00=1 drive, 01=2 drives, etc)
Initial video-display mode (11=80x25 monochrome,
10=80x25 color, 01=40x25 color, 00=EGA/VGA/SVGA)
PS/2-type pointing-device is installed (1=yes, 0=no)
External math-coprocessor installed (1=yes, 0=no)
Diskette available for booting (1=yes, 0=no)
In-Class Exercice #2
• Enhance the ‘showmem.s’ demo-program
by showing additional information about
the amount of physical memory installed:
use ROM-BIOS system-services int 0x15
function 0xE8, subfunction 0x01 (see Ralf
Brown’s online Interrupt-List for details)
Extended Memory Areas
mov
int
ax, #0xE801
0x15
Number of 64KB blocks
Is reported by ROM-BIOS
(in register BX)
Pentium’s
Memory-area
(4GB)
Number of 1KB blocks
Is reported by ROM-BIOS
(in register AX)
80286 memory-area
(16MB)
8086 memory-area (1MB)
Download