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)