This paper describes an extensive analysis of the BIOS Services. The BIOS Services in question are: (a) "BIOS Interrupts", (b) BIOS32 Services, (c) Plug and Play BIOS Services, (d) BIOS Data Area and Extended BIOS Data Area, (e) Advanced Configuration and Power Interface (ACPI). In the above "BIOS Interrupts" means the subset of interrupts that are implemented by the BIOS. This study has been done to find out which of the BIOS Services are used by Microsoft's operating system. Advanced analysis has been performed on each BIOS Service's usage by said operating system. The operating systems analyzed are Windows 2000 and Windows XP.
This paper describes an extensive analysis of the BIOS Services. The BIOS Services in question are: (a) "BIOS Interrupts", (b) BIOS32 Services, (c) Plug and Play BIOS Services, (d) BIOS Data Area and Extended BIOS Data Area, (e) Advanced Configuration and Power Interface (ACPI). In the above "BIOS Interrupts" means the subset of interrupts that are implemented by the BIOS. This study has been done to find out which of the BIOS Services are used by Microsoft's operating system. Advanced analysis has been performed on each BIOS Service's usage by said operating system. The operating systems analyzed are Windows 2000 and Windows XP.
As we will find out, Interrupt-based BIOS Services make up the core part of the communication between BIOS and Windows. Consequently, they make up the bulk of the paper. This paper describes an extensive analysis of a subset of the interrupts. When we study interrupts, the interrupts we are interested most in are the ones that are implemented by the BIOS. The study of the BIOS interrupts analyze how each BIOS Interrupt is used by Windows 2000 and Windows XP. Advanced analysis has been performed on each interrupt's usage by said operating systems.
Said work will help us facilitate running Windows OS on top of LinuxBIOS [18] . It is also relevant for our work on SEBOS [20] [33] . At the present time, the idea is to implement an extra stage module, which would be loaded by LinuxBIOS. This module would add support for some subset of "classic" PC-style BIOS Services. Said module in turn would load the next stage which in our case would be Microsoft Windows.
This paper is a superset of my earlier paper titled: " LinuxBIOS: A Study of BIOS Interrupts as used by Microsoft Windows 2000" [32] .
This paper is a subset of my forthcoming paper titled: " LinuxBIOS: How LinuxBIOS boots Windows" [XX] .
Most of the work was done by me, Adam Sulmicki (adam[at]cfar.umd.edu) , with help from Adam Agnew (agnew[at]cs.umd.edu). Lots of thanks go to William A. Arbaugh (waa[at]cs.umd.edu) who made all this work possible. Finally, for list of other people who contributed to the paper, please, see Acknowledgments section.
Before we go into details on BIOS Services, first let's go briefly over our setup.
Some more details about our hardware setup.
The system consisted of:
It all was set up on a local LAN, where In-Target Probe , Host, Target and Laptop all shared the same subnet.
In our Target System I disabled everything in BIOS that was unnecessary. It turned out to be quite a bit, given the numerous things built into the SIS630 chipset. The end result was that these things were disabled:
NOTE: The below interrupt list (in Section 3.1.2. BIOS Interrupts Overview), which lists how many times each interrupt is called, was done with everything enabled in BIOS. It was also done using a different BIOS, thus the number of calls will be different than what is in the detailed analysis below.
The motherboard normally comes with Award/Phoenix BIOS [35] [36] (the two companies have merged). First I used release 05/08/2001, later I upgraded to 05/02/2001. However, during the debugging process, the system developed some unexplained problems, possibly a hardware failure. Since I discovered that switching to AMI BIOS [34] cures the problems, I stuck with AMI BIOS and the same motherboard for the duration of the experiment in order to preserve all addressing used in the study. The BIOS I ended up using:
BIOS: AMIBIOS 03/08/01 686 AMIBIOS (c) 1999 AR75 1666
The next issue was where to start our debugging. In our system BIOS would load LILO, which in turn would boot up either Microsoft Windows 2000/XP or Red Hat Linux 7.1. Studying LILO sources and docs, it seems that it will load the client into the area starting at 0x7C00 then make a jump to this address to start the client.
The LILO as shipped with RedHat 7.1 is lilo-21.4.4-13 which can be found here [13] . Of particular interest will be this Technical Overview [12] which gives a brief description on how LILO jump-starts the client, pages 1-2. To quote:
address where LILO loads "OS" and passes control
The chain loader moves [..] the boot sector to 0x7C00. After that it passes control to the boot sector.
That is pretty good, but the source is where the ultimate proof lies :-) Hopefully the code below is self explanatory (On a curious note, older versions of the code would just use a far jump in the form "jmpi #BOOTSEG*16,0"). Thus:
bootsect.S:33 BOOTSEG = 0x07C0 ! original address of boot-sector chain.S:143-169 xor ax,ax ! clear AX register mov bx,#BOOTSEG*16 push ax push bx retfAnother issue that came to my attention is that LILO is using interrupts for its own needs so we need to be careful not to pollute our results with interrupts from LILO. The three interrupts that came to our attention were:
Address 0x7C00 is used in several places (two: a) start of LILO, and b) start client) before the final passing of control to the client. In the end the way I decided to pin-point the start of the client (Microsoft Windows) was as follows:
I would let the Target computer start normally, and wait until the LILO command prompt came up. Then, using the Host system, I would put the Target system into Stopped Mode (Alt-F5), activate a breakpoint at 0x7C00, and let it Continue (F5). Then I would wait for the Target system to reach the instruction at 0x7C00, at which point the debugger's "Execute"-style breakpoint would be triggered. Once it hit this breakpoint I would start from that point on to record activity of whichever interrupt I was working on.
Another way to start debugging:It is based on fact that 0x7C00 is used only TWICE. First time during starting LILO, and second time during starting Windows.
Our study focuses on "Windows" series of "operating systems" from Microsoft Corporation [30] . The two versions of the said operating system we have analyzed in this study are:
Start -> Settings -> Control Panel -> System -> General System: Microsoft Windows 2000 Professional Version 5.00.2195
Start -> Control Panel -> System -> General System: Microsoft Windows XP Professional Version 2002
During the debugging process it was sometimes necessary to modify one or more of the following items for certain interrupts: a) the vector table, b) Windows code, c) BIOS code. This was necessary in order to see what was going on when some routine was used an excessive number of times, clouding our view of the other parts of the code.
Points a and b were pretty easy to deal with, but c was more difficult. We considered a number of different solutions:
0000:E2AA OUT DX,AXThis is the address where I would wait for Target to be about to write 0 to the port 0xCFF (that's about the 5th execution of the said line). At that point I would modify the BIOS code and let it execute the instruction which would make Shadow BIOS R/O. However, the problem with the AMI BIOS is that it copies parts of BIOS in the ROM over to the Shadow RAM a few times (at least three times), overwriting old BIOS code each time. So some parts of BIOS would change and some parts of BIOS would not change before control is passed over to LILO. The bottom line is that for some interrupts it would work, but for some it would not.
The area of interest is the "Core-Logic" of the "Host to PCI Bridge" of the SIS630 chipset, and the area of particular interest within that is Bus:0, Device:0, Function:0, Register:70. This particular Address, fed to CONFIG_ADDR at 0CF8h, will let us access bits responsible for control of Shadow RAM (registers 70h-73h).
We then want to access CONFIG_DATA (0CFChh,0CFCEh,0CFEh,0CFCFh) at 0CFEh. There we want to flip bit 12 (1000h) on. This will make Area F0000h-FFFFFh of Shadow RAM Read-Write. Turning the same bit back to 0 will make the RAM Read-Only once again.
Of all the three method mentioned above, the third one (c) is the best. The whole description of the third (c) method basically boils down to the executing the two simple commands as shown below:
dport 0CF8h = 80000070h wport 0CFEh = 1000hThis is the syntax as used with the Source Point debugger, and is for the SIS630 chipset.
The relevant references here are PCI Hardware and Software Architecture and Design [4], and WinDB user's Guide by American Arium [5].
In the Source Point debugger, you might want to go to:
Options-> Emulator-Configuration-> Switches-> SW1: 0x00Then you might want to replace the SW1 current value 0x00 with 0x08.
This will cause the emulator to execute the equivalent of CLI after stopping at a breakpoint. This makes a difference when trying to use F8 (Step Into) or F10 (Step Over) to step over the code; since otherwise, if the interrupt code does not execute a CLI instruction, you might have some other interrupts pending, and trying to step code will cause that interrupt routine to execute instead. The net result would be getting the impression that F8 and F10 do not work at all.
(thanks to American Arium tech support for helping to nail this down)
View -> BreakPoints -> Edit
This breakpoint lets us pin-point exactly where LILO ends and where Windows code starts.
Once you stop at this break-point, a) unselect the breakpoint and b) select/activate i) the Vector Table breakpoint, ii) the Start of Interrupt Routine breakpoint, and iii) the End of Interrupt Routine breakpoints.
This will be an "Execute" style breakpoint as opposed to the "Data Access" breakpoint used in the Vector Table.
For more details on setting up breakpoints see the "Vector Table" section just below.
In the Vector Table I set up breakpoints in the area corresponding to the interrupt I am debugging. For example, if I am debugging interrupt 10, I set up a breakpoint at physical address 40h (as shown on picture below):
Basically: Break-On is "Data Access", Resource is "Processor" and Location (for int 10) is 40p (p=physical memory, as opposed to offset in current segment). I set Length for "Byte", though I suppose "Word" could be more appropriate in order to account for both segment and offset, not just offset alone.
For paranoia's sake you might want to set up a breakpoint at the address which the entry for the vector at the vector table refers to. It will allow you to detect jumps to the interrupt service routine via direct call or jump, as opposed to the "classic" interrupt call going through the interrupt Vector Table. It will also allow us to detect calls to the Interrupt Service Routine via different interrupts, which would use a different cell in the the interrupt vector table (ex: when I rewrite BIOS for interrupt 13 and 1c).
You can find this address by looking up the contents of the corresponding Vector Table "cell".
When you are at this break-point take note of arguments being passed to the function.
This will be an "Execute" style breakpoint as opposed to the "Data Access" breakpoint used in the Vector Table.
There might be several exits, depending on the complexity of the Interrupt Service Routine. In general as long as the argument(s) to the ISR (content of register AH most of the times) is the same, the place where it exists from interrupt routine will be the same as well.
It is useful when you want to fast-track through interrupt to see where it came from (another way to do this would be to decode stack as soon as you enter routine, and see where Segment:Offset (CS:IP) on top of stack (SS:SP) points to ... but that will not give you return arguments :-).
This will be an "Execute" style breakpoint as opposed to the "Data Access" breakpoint used in the Vector Table.
As "Resource" you probably want to use "Software" instead of "Processor" as there is a limit on only 4 Processor-style breakpoints as opposed to 32 Software-style breakpoints.
This layout has been heavily influenced by Phoenix's Manual description of BIOS Services [7]. Since I probably couldn't come up with anything better I decided to follow it as well. However, it is expanded by ACPI Chapter which is not present in the said manual.
We do an extensive analysis of a subset of interrupts. The interrupts we are interested in are the ones that are implemented by BIOS. We attempt find out which of the BIOS interrupts are used by Microsoft's operating system. We do advanced analysis on each interrupt's usage by said operating system. We do analysis of both Windows 2000 (red tables below), and Windows XP (orange fields below).
The first question was "Which interrupts are of interest to us?". That is, "Which interrupts are serviced by BIOS?". As a reference I have used "PhoenixBIOS 4.0, Revision 6, User's Manual" from Phoenix Technologies Ltd. [7], available from Phoenix's Web site ( local copy ). There is also "Ralf Brown's Interrupt List" [6] which is available from here and here and here which I have used as an auxiliary reference when something was not documented in Phoenix's manual. Overall Phoenix's manual is a pretty good resource which documents BIOS and BIOS-supported interrupts, and lists the function of each interrupt with a short description.
On page 80 of Phoenix's BIOS manual there is this list:
ADDR INT Description Status |
0 00 Divide by zero Not Supported 4 01 Single step Not Supported 8 02 Non-Maskable interrupt Supported C 03 Breakpoint Not Supported 10 04 Overflow Not Supported 14 05 Print Screen Interrupt Supported 18 06 286 LoadAll Handler Supported 1C 07 Reserved Not Supported 20 08 IRQ0 - System Timer Interrupt Supported 24 09 IRQ1 - Keyboard Interrupt Supported 28 0A IRQ2 - Reserved Not Supported 2C 0B IRQ3 - COM2: Interrupt Supported 30 0C IRQ4 - COM1: Interrupt Supported 34 0D IRQ5 - LPT2: Interrupt Supported 38 0E IRQ6 - Floppy Disk Interrupt Supported 3C 0F IRQ7 - LPT1: Interrupt Supported |
40 10 BIOS Video Interface Supported 44 11 BIOS Equipment Check Supported 48 12 BIOS Memory Request Supported 4C 13 BIOS Fixed Disk/Diskette Interface Supported 50 14 BIOS Serial Interface Supported 54 15 BIOS System Functions Interface Supported 58 16 BIOS Keyboard Interface Supported 5C 17 BIOS Parallel Printer Interface Supported 60 18 BIOS Secondary Boot Request Supported 64 19 BIOS Primary Boot Request Supported 68 1A BIOS System Timer Interface Supported 6C 1B BIOS Control Break Interrupt Supported 70 1C BIOS User System Timer Interrupt Supported 74 1D BIOS Video Init Parameters Supported 78 1E BIOS Diskette Parameters Supported 7C 1F BIOS Video Graphic Characters Supported 100 40 BIOS Diskette (when fixed disk present) Supported 104 41 BIOS Fixed disk 0 parameters Supported 118 46 BIOS Fixed disk 1 parameters Supported |
1C0 70 IRQ8 - Real time clock interrupt Supported 1C4 71 IRQ9 - IRQ2 redirection Supported 1C8 72 IRQ10 - Reserved Not Supported 1CC 73 IRQ11 - Reserved Not Supported 1D0 74 IRQ12 - Available/PS/2 Mouse Supported 1D4 75 IRQ13 - Math coprocessor Supported 1D8 76 IRQ14 - Primary IDE HDD Supported 1DC 77 IRQ15 - Available/Secondary IDE HDD Supported |
In the above list all interrupts with the word "BIOS" in the Description field were considered as implemented and supported by BIOS. The entries in the blue box above were the subject of further study.
The ADDR field was calculated by multiplying each interrupt by 4.
For the next step we set up the ECM-20 In-Target Probe by American Arium [37] [38] . Using two computers ('Host' and 'Target'), each interrupt was analyzed to determine how many times it was being called while Microsoft Windows was starting up. The results were as follows (shown in the "NT" column):
ADDR NT INT Description Status |
0 00 Divide by zero Not Supported 4 01 Single step Not Supported 8 02 Non-Maskable interrupt Supported C 03 Breakpoint Not Supported 10 04 Overflow Not Supported 14 05 Print Screen Interrupt Supported 18 06 286 LoadAll Handler Supported 1C 07 Reserved Not Supported 20 08 IRQ0 - System Timer Interrupt Supported 24 09 IRQ1 - Keyboard Interrupt Supported 28 0A IRQ2 - Reserved Not Supported 2C 0B IRQ3 - COM2: Interrupt Supported 30 0C IRQ4 - COM1: Interrupt Supported 34 0D IRQ5 - LPT2: Interrupt Supported 38 0E IRQ6 - Floppy Disk Interrupt Supported 3C 0F IRQ7 - LPT1: Interrupt Supported |
40 ~4 10 BIOS Video Interface Supported 44 2 11 BIOS Equipment Check Supported 48 1 12 BIOS Memory Request Supported 4C lots 13 BIOS Fixed Disk/Diskette Interface Supported 50 1 14 BIOS Serial Interface Supported 54 lots 15 BIOS System Functions Interface Supported 58 ~40 16 BIOS Keyboard Interface Supported 5C 3 17 BIOS Parallel Printer Interface Supported 60 1 18 BIOS Secondary Boot Request Supported 64 1 19 BIOS Primary Boot Request Supported 68 ~14 1A BIOS System Timer Interface Supported 6C 1 1B BIOS Control Break Interrupt Supported 70 lots+ 1C BIOS User System Timer Interrupt Supported 74 1 1D BIOS Video Init Parameters Supported 78 2+ 1E BIOS Diskette Parameters Supported 7C 8 1F BIOS Video Graphic Characters Supported 100 6 40 BIOS Diskette (when fixed disk present) Supported 104 1 41 BIOS Fixed disk 0 parameters Supported 118 1 46 BIOS Fixed disk 1 parameters Supported |
1C0 70 IRQ8 - Real time clock interrupt Supported 1C4 71 IRQ9 - IRQ2 redirection Supported 1C8 72 IRQ10 - Reserved Not Supported 1CC 73 IRQ11 - Reserved Not Supported 1D0 74 IRQ12 - Available/PS/2 Mouse Supported 1D4 75 IRQ13 - Math coprocessor Supported 1D8 76 IRQ14 - Primary IDE HDD Supported 1DC 77 IRQ15 - Available/Secondary IDE HDD Supported |
Where:
"~" means approximate number of interrupt calls,
"N+" means more than N interrupt calls,
"lots" means a large number of interrupt calls.
This was pretty good, but it still did not give us the details we wanted. I had set access-breakpoints for each vector in the vector table, so it was not clear if the vector in the vector table was just being read off or if it was an actual vector call. By the same token it was not clear if the interrupt was used by Windows or if it was used internally by the BIOS. Thus, I did the work again, this time analyzing each interrupt call in detail to see exactly what was happening.
Below is a detailed description of what happens to each BIOS interrupt from (a) when LILO passes control to Windows until (b) Windows sets up its own interrupt vector table elsewhere in memory. It will set up its own interrupt vector table by means of switching to protected mode and then using LIDT and SIDT instructions.
ADDR NT INT Description Status 40 13/11 10 BIOS Video Interface Supported |
VECTOR TABLE: 0000:0040 C000:07CB BIOS (AMI): start C000:07CB FB STI end C000:07F5 CF IRET |
WINDOWS 2000: ["LILO boot:\r\nLoading winblows" text still visible] [real mode] 2000:000002E4 CD10 INT 10 one, AH=12 - BIOS Window Extension v1.1 - GET BLANKING ATTRIBUTE AL=02 BX=0301 two, AH=00 - Set Video Mode AL=03 - = T 80x25 9x16 720x400 16 8 B800 VGA [screen cleared up, cursor at left-top corner] three, AH=20, ????? AL=00 what the heck is that. some very simple function. it must be for some other systems. it is not implemented on my system. the function just falls through. four AH=0A - VIDEO - WRITE CHARACTER ONLY AT CURSOR POSITION AL=20 - space SEE NOTE4 2000:00000980 CD10 INT 10 AH=02 - VIDEO - SET CURSOR POSITION DH=7F = row 127, bottom-most row DL=00 = column 00 ,left-most column hide cursor [cursor disappears from screen, all blank screen] 1000:00004EF1 268B0F MOV CX,word ptr ES:[BX] reads INT 10 vector table entry (7CB) into CX 1000:00001C88 CD10 INT 10 one AX=1130 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA) BH=02 - 02h ROM 8x14 character font pointer two AX=1130 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA) BH=03 - 03h ROM 8x8 double dot font pointer three AX=1130 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA) BH=04 - 04h ROM 8x8 double dot font (high 128 characters) four AX=1130 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA) BH=05 - 05h ROM alpha alternate (9 by 14) pointer (EGA,VGA) five AX=1130 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA) BH=06 - 06h ROM 8x16 font (MCGA, VGA) six AX=1130 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA) BH=07 - 07h ROM alternate 9x16 font (VGA only) [still text mode] [text banner "Starting Windows"] [the bar below ALL white.] [protected mode] 0008:80063C31 8B048D00000000 MOV EAX,dword ptr [00000000][ECX*4] reads INT 10 vector table entry (7CB) into EAX ECX=10 [screen all blank again] [Virtual86 mode] 2000:000001C8 CD10 INT 10 AH=00 - VIDEO - SET VIDEO MODE AL=12 - 12h = G 80x30 8x16 640x480 16/256K.A000 VGA,ATI VIP Virtual86 mode! I have caught this interrupt via EXIT routine! it must be using alternate vector table! [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+40h (ESI+40) [screen is blank again] 1000:00000000 CD10 INT 10 AH=00 - VIDEO - SET VIDEO MODE AL=12 - 12h = G 80x30 8x16 640x480 16/256K . A000 VGA,ATI VIP [windows fully running, with "Start" button] [no more interrupt 10h] |
WINDOWS XP: ["LILO boot:\r\nLoading winblows" text still visible] [real mode] 2000:000002E4 CD10 INT 10 one, AH=12 - BIOS Window Extension v1.1 - GET BLANKING ATTRIBUTE AL=02 BX=0301 two, AH=00 - Set Video Mode AL=03 - = T 80x25 9x16 720x400 16 8 B800 VGA [screen cleared up, cursor at left-top corner] three, AH=20, ????? AL=00 what the heck is that. some very simple function. it must be for some other systems. it is not implemented on my system. the function just falls through. four AH=0A - VIDEO - WRITE CHARACTER ONLY AT CURSOR POSITION AL=20 - space SEE NOTE4 2000:00000970 CD10 INT 10 AH=02 - VIDEO - SET CURSOR POSITION DH=7F = row 127, bottom-most row DL=00 = column 00 ,left-most column hide cursor [cursor disappears from screen, all blank screen] 1000:6A1C 268B07 MOV DX,word ptr ES:[BX] reads INT 10 vector table entry (7CB) into DX 1000:2828 CD10 INT 10 one AX=1130 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA) BH=02 - 02h ROM 8x14 character font pointer two AX=1130 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA) BH=03 - 03h ROM 8x8 double dot font pointer three AX=1130 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA) BH=04 - 04h ROM 8x8 double dot font (high 128 characters) four AX=1130 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA) BH=05 - 05h ROM alpha alternate (9 by 14) pointer (EGA,VGA) five AX=1130 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA) BH=06 - 06h ROM 8x16 font (MCGA, VGA) six AX=1130 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA) BH=07 - 07h ROM alternate 9x16 font (VGA only) [windows fully running, with "Start" button] [no more interrupt 10h] |
NOTE0: windows shutting down: [blank screen] 1000:00000000 CD10 INT 10 AH=00 - VIDEO - SET VIDEO MODE AL=03 - = T 80x25 9x16 720x400 16 8 B800 VGA [blank screen w/ cursor at left-top corner] 2000:00001C88 CD10 INT 10 AH=00 - VIDEO - SET VIDEO MODE AL=12 [all blank screen] [a bit of delay] ["it is now safe to turn off computer"] NOTE1: video BIOS This is Actually VIDEO BIOS, not "MAIN" BIOS. The Interrupt code is located at segment C000 which is video BIOS. NOTE2: LILO does use interrupt 10 as well 0B00:000008EC CD10 INT 10 // write "\r" [and so on until text below shows] "LILO boot:\r\nLoading winblows\r\n" NOTE3: "map" of int 10. it is for Award/Phoenix BIOS and NOT for AMI BIOS on which most stuff is done. this shows how int 10/vector table for 10 is used/setup inside of the BIOS. BIOS: F000:0000E919 AA STOS byte ptr [DI] 40hP = C0000712 40hP = C0001212 instruction called twice F000:0000C100 67F366AB REP STOS dword ptr [EDI] 40hP 5AA5A55A F000:0000E2CD : zero vector table F000:0000E2E1 : test zeroing VT was successful F000:00001B1B : set all interrupts to F000:E816 F000:00001B35 : set kbd interrupt to F000:F065 F000:00001B35 : set kbd interrupt to F000:FF53 F000:00002A6A : load all vector table into single reg ????? 1st BIOS screen shows up F000:0000BC58 : some memory comparison/verification repeats 4 times total NOTE4: weird code: -lots of interrupt calls grouped together. grouped interrupts are : interrupts 10-19 -int 10 is called repeatedly from here with varying arguments NOTE5: 2000 vs XP The visible changes are in green. minor "standard" differences: - small differences of offset in a segment. - does not save vector table anymore. minor differences: - use different registers for return value. - does not do one vector table read anymore. major differences: - does not do two interrupt calls anymore. - 4 less "calls" at end. |
ADDR NT INT Description Status 44 1/1 11 BIOS Equipment Check Supported |
VECTOR TABLE: 0000:0044 F000:F84D BIOS (AMI): start F000:F84D E855B2 CALL near16 ptr 0000aaa5 end F000:F858 CF IRET |
WINDOWS 2000: [blank screen] 1000:00002A8C CD11 INT 11 return: AX = 22h = 100010b (FPU, 80x25 CGA) [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+44h (ESI+44) [windows fully running, with "Start" button] [no more interrupt 11h] |
WINDOWS XP: [blank screen] 1000:0000403C CD11 INT 11 return: AX = 22h = 100010b (FPU, 80x25 CGA) [windows fully running, with "Start" button] [no more interrupt 11h] |
NOTE0: windows shutdown [reboot] NOTE1: in the above the int 11 was called so that later windows could check for mouse. test for mouse (4h-> 100b) 1000:00002A8C CD11 INT 11 1000:00002A8E A90400 TEST AX,0004 NOTE2: 2000 vs XP The visible changes are in green. minor "standard" differences: - small differences of offset in a segment. - does not save vector table anymore. |
ADDR NT INT Description Status 48 0/0 12 BIOS Memory Request Supported |
VECTOR TABLE: 0000:0048 F000:F841 BIOS (AMI): start F000:F841 FB STI end F000:F84A CF IRET |
WINDOWS 2000: [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+48h (ESI+48) [windows fully running, with "Start" button] [no more interrupt 12h] |
WINDOWS XP: [windows fully running, with "Start" button] [no more interrupt 12h] |
NOTE0: windows shutdown [reboot] NOTE1: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
ADDR NT INT Description Status 4C lots 13 BIOS Fixed Disk/Diskette Interface Supported |
VECTOR TABLE: 0000:004C F000:EED2 BIOS (AMI): start F000:EED2 E961FF JMP near16 ptr 0000ee36 end F144:03E4 CF IRET end2 F144:03F1 CA0200 RETF 0002 |
WINDOWS 2000: ["LILO boot:\r\nLoading winblows" text still visible] [real mode] 0000:00007C70 CD13 INT 13 AH=08, DISK - GET DRIVE PARAMETERS (PC,XT286,CONV,PS,ESDI,SCSI) DL=80h ,10000000(b) -> bit 7 on -> hard disk return: CX = FEFF, max 255 sectors, max 254 cylinders DX = FE01, max 254 heads, 1 drive 0000:00007D07 CD13 INT 13 AH = 41,IBM/MS INT 13 Extensions - INSTALLATION CHECK BX = 55AAh, The Magic Number DL=80h ,10000000(b) -> bit 7 on -> hard disk return: BX = AA55h, extension installed AH = 21, 2.1 / EDD-1.1 CX = 5 = 101(b), extended disk *access* functions SUPPORTED *removable* functions NOT supported *EDD* functions SUPPORTED SEE NOTE0 [ # 0000:00007D26 CD13 INT 13 # AH = 42, IBM/MS INT 13 Extensions - EXTENDED READ # DL=80h ,10000000(b) -> bit 7 on -> hard disk # return: # DS:SI = 0000:7BC2 # 10 - size of packet # 00 - reserved # 0001 - number of blocks read # one, two, three ... LOTS .. #SEE *IMPORTANT* NOTE1 ] [ # 2000:0000061F CD13 INT 13 # AH=08, DISK - GET DRIVE PARAMETERS (PC,XT286,CONV,PS,ESDI,SCSI) # DL=80h ,10000000(b) -> bit 7 on -> hard disk # return: # CX = FEFF, max 255 sectors, max 254 cylinders # DX = FE01, max 254 heads, 1 drive # 2000:00000FE1 CD13 INT 13 # AH = 41,IBM/MS INT 13 Extensions - INSTALLATION CHECK # BX = 55AAh, The Magic Number # DL=80h ,10000000(b) -> bit 7 on -> hard disk # return: # BX = AA55h, extension installed # AH = 21, 2.1 / EDD-1.1 # CX = 5 = 101(b), # extended disk *access* functions SUPPORTED # *removable* functions NOT supported # *EDD* functions SUPPORTED # SEE NOTE0 # 2000:00001010 CD13 INT 13 # AH = 48,IBM/MS INT 13 Extensions - GET DRIVE PARAMETERS # DL=80h ,10000000(b) -> bit 7 on -> hard disk # result # DS:SI = 609C:000C # 609C:000C 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # 609C:001C 80 A7 54 02 00 00 00 00 00 02 00 00 00 00 00 00 # 2000:0000061F CD13 INT 13 # AH = 02, DISK - READ SECTOR(S) INTO MEMORY # AL = 1, number of sectors to read (must be nonzero) # CH = 00, low eight bits of cylinder number # CL = 01, sector number 1-63 (bits 0-5) # high two bits of cylinder (bits 6-7, hard disk only) # DH = 00 head number # DL = 80, drive number (bit 7 set for hard disk) # 2000:000006F3 CD13 INT 13 # AH = 42, IBM/MS INT 13 Extensions - EXTENDED READ # DL=80h ,10000000(b) -> bit 7 on -> hard disk # return: # DS:SI = 0000:0C0F # 10 - size of packet # 00 - reserved # 0001 - number of blocks read #SEE *IMPORTANT* NOTE2 ] 1000:00003F72 CD13 INT 13 AH=15, DISK - GET DISK TYPE (XT 1986/1/10 or later,XT286,AT,PS) DL=80h ,10000000(b) -> bit 7 on -> hard disk return AH=03h , fixed disk CX:DX = 00FA:0C53F, number of 512b blocks 1000:00003F83 CD13 INT 13 AH=08, DISK - GET DRIVE PARAMETERS (PC,XT286,CONV,PS,ESDI,SCSI) DL=80h ,10000000(b) -> bit 7 on -> hard disk return: CX = FEFF, max 255 sectors, max 254 cylinders DX = FE01, max 254 heads, 1 drive 1000:00003F72 CD13 INT 13 AH=15, DISK - GET DISK TYPE (XT 1986/1/10 or later,XT286,AT,PS) DL=81h ,10000000(b) -> bit 7 on -> hard disk, ????? return AH=00h , no such drive. SEE NOTE3 1000:00003989 CD13 INT 13 AH=15, DISK - GET DISK TYPE (XT 1986/1/10 or later,XT286,AT,PS) DH=00, floppy only????? return AH=00, no such drive. 1000:00003E18 CD13 INT 13 AH = 02, DISK - READ SECTOR(S) INTO MEMORY AL = 1, number of sectors to read (must be nonzero) CH = 00, low eight bits of cylinder number CL = 01, sector number 1-63 (bits 0-5) high two bits of cylinder (bits 6-7, hard disk only) DH = 00 head number DL = 80, drive number (bit 7 set for hard disk) 1000:00003FE5 CD13 INT 13 AH = 41,IBM/MS INT 13 Extensions - INSTALLATION CHECK BX = 55AAh, The Magic Number DL=80h ,10000000(b) -> bit 7 on -> hard disk return: BX = AA55h, extension installed AH = 21, 2.1 / EDD-1.1 CX = 5 = 101(b), extended disk *access* functions SUPPORTED *removable* functions NOT supported *EDD* functions SUPPORTED SEE NOTE0 1000:00004013 CD13 INT 13 AH = 48,IBM/MS INT 13 Extensions - GET DRIVE PARAMETERS DL=80h ,10000000(b) -> bit 7 on -> hard disk result DS:SI = 16F3:0D0A 16F3:00000D0A 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16F3:00000D1A 80 A7 54 02 00 00 00 00 00 02 28 00 00 00 80 00 [ # # 2000:0000061F CD13 INT 13 # AH=08, DISK - GET DRIVE PARAMETERS (PC,XT286,CONV,PS,ESDI,SCSI) # DL=80h ,10000000(b) -> bit 7 on -> hard disk # return: # CX = FEFF, max 255 sectors, max 254 cylinders # DX = FE01, max 254 heads, 1 drive # 2000:00000FE1 CD13 INT 13 # AH = 41,IBM/MS INT 13 Extensions - INSTALLATION CHECK # BX = 55AAh, The Magic Number # DL=80h ,10000000(b) -> bit 7 on -> hard disk # return: # BX = AA55h, extension installed # AH = 21, 2.1 / EDD-1.1 # CX = 5 = 101(b), # extended disk *access* functions SUPPORTED # *removable* functions NOT supported # *EDD* functions SUPPORTED # SEE NOTE0 # 2000:00001010 CD13 INT 13 # AH = 48,IBM/MS INT 13 Extensions - GET DRIVE PARAMETERS # DL=80h ,10000000(b) -> bit 7 on -> hard disk # result # DS:SI = 609C:000C # 609C:000C 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # 609C:001C 80 A7 54 02 00 00 00 00 00 02 00 00 00 00 00 00 # 2000:0000061F CD13 INT 13 # AH = 02, DISK - READ SECTOR(S) INTO MEMORY # AL = 1, number of sectors to read (must be nonzero) # CH = 00, low eight bits of cylinder number # CL = 01, sector number 1-63 (bits 0-5) # high two bits of cylinder (bits 6-7, hard disk only) # DH = 00 head number # DL = 80, drive number (bit 7 set for hard disk) # 2000:000006F3 CD13 INT 13 # AH = 42, IBM/MS INT 13 Extensions - EXTENDED READ # DL=80h ,10000000(b) -> bit 7 on -> hard disk # return: # DS:SI = 0000:0C0F # 10 - size of packet # 00 - reserved # 0001 - number of blocks read #SEE *IMPORTANT* NOTE2 ] [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+4Ch (ESI+4C) [windows fully running, with "Start" button] [no more interrupt 13h] |
WINDOWS XP: ["LILO boot:\r\nLoading winblows" text still visible] [real mode] 0000:00007C81 CD13 INT 13 AH=08, DISK - GET DRIVE PARAMETERS (PC,XT286, ONV,PS,ESDI,SCSI) DL=80h ,10000000(b) -> bit 7 on -> hard disk return: CX = FEFF, max 255 sectors, max 254 cylinders DX = FE01, max 254 heads, 1 drive 0000:00007D42 CD13 INT 13 AH = 02, DISK - READ SECTOR(S) INTO MEMORY AL = 1, number of sectors to read (must be nonzero) CH = 67, low eight bits of cylinder number CL = 81, sector number 1-63 (bits 0-5) high two bits of cylinder (bits 6-7, hard disk only) DH = 00 head number DL = 80, drive number (bit 7 set for hard disk) one,two,three,four,five,six,seven executes around 16 (10h) times It is an loop, which counter stored in DS:000E (07C0:000E). start of function 0000:00007CC7 start of loop: 0000:00007CCB interrupt: 0000:00007D42 INT 13 end of loop: 0000:00007D58 : JNE next line 0000:00007D5C NOTE1XP: make NOTE out of this. 0D00:00000081 CD13 INT 13 AH=08, DISK - GET DRIVE PARAMETERS (PC,XT286,CONV,PS,ESDI,SCSI) DL=80h ,10000000(b) -> bit 7 on -> hard disk return: CX = FEFF, max 255 sectors, max 254 cylinders DX = FE01, max 254 heads, 1 drive [ # 0D00:0000142 CD13 INT 13 # AH = 02, DISK - READ SECTOR(S) INTO MEMORY # AL = 01, number of sectors to read (must be nonzero) # CH = E9, low eight bits of cylinder number # CL = 89, sector number 1-63 (bits 0-5) # high two bits of cylinder (bits 6-7, hard disk only) # DH = 8A head number # DL = 80, drive number (bit 7 set for hard disk) # # # CHANGING D00:00142 TO USE INTERRUPT 33 INSTEAD OF 13 # one, two, three ... LOTS .. # NOTE2XP: make NOTE out of this. # #SEE *IMPORTANT* NOTE1 ] [blank screen] [real mode] [ # 2000:0000062B CD13 INT 13 # AH=08, DISK - GET DRIVE PARAMETERS (PC,XT286,CONV,PS,ESDI,SCSI) # DL=80h ,10000000(b) -> bit 7 on -> hard disk # return: # CX = FEFF, max 255 sectors, max 254 cylinders # DX = FE01, max 254 heads, 1 drive # 2000:00000EBD CD13 INT 13 # AH = 41,IBM/MS INT 13 Extensions - INSTALLATION CHECK # BX = 55AAh, The Magic Number # DL=80h ,10000000(b) -> bit 7 on -> hard disk # return: # BX = AA55h, extension installed # AH = 21, 2.1 / EDD-1.1 # CX = 5 = 101(b), # extended disk *access* functions SUPPORTED # *removable* functions NOT supported # *EDD* functions SUPPORTED # SEE NOTE0 # 2000:00000EEC CD13 INT 13 # AH = 48,IBM/MS INT 13 Extensions - GET DRIVE PARAMETERS # DL=80h ,10000000(b) -> bit 7 on -> hard disk # result # DS:SI = 609C:000C # 609C:000C 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # 609C:001C 80 A7 54 02 00 00 00 00 00 02 00 00 00 00 00 00 # 2000:0000062B CD13 INT 13 # AH = 02, DISK - READ SECTOR(S) INTO MEMORY # AL = 1, number of sectors to read (must be nonzero) # CH = 00, low eight bits of cylinder number # CL = 01, sector number 1-63 (bits 0-5) # high two bits of cylinder (bits 6-7, hard disk only) # DH = 00 head number # DL = 80, drive number (bit 7 set for hard disk) # #lots of repeated calls #or standard "code rewrite" # #13cd -> 33cd # # 62b # ebd # eec # #SEE *IMPORTANT* NOTE2 ] 1000:00005CD2 CD13 INT 13 AH=15, DISK - GET DISK TYPE (XT 1986/1/10 or later,XT286,AT,PS) DL=80h ,10000000(b) -> bit 7 on -> hard disk return AH=03h , fixed disk CX:DX = 00FA:0C53F, number of 512b blocks 1000:00005CE3 CD13 INT 13 AH=08, DISK - GET DRIVE PARAMETERS (PC,XT286,CONV,PS,ESDI,SCSI) DL=80h ,10000000(b) -> bit 7 on -> hard disk return: CX = FEFF, max 255 sectors, max 254 cylinders DX = FE01, max 254 heads, 1 drive 1000:00005CD2 CD13 INT 13 AH=15, DISK - GET DISK TYPE (XT 1986/1/10 or later,XT286,AT,PS) DL=81h ,10000000(b) -> bit 7 on -> hard disk, 2nd hdd. return AH=00h , no such drive. SEE NOTE3 1000:000054CA CD13 INT 13 AH=15, DISK - GET DISK TYPE (XT 1986/1/10 or later,XT286,AT,PS) DL=00, floppy return AH=00, no such drive. xxxxxxxxxxxxxxx different exit? diff bios call? 1000:00005B29 CD13 INT 13 AH = 02, DISK - READ SECTOR(S) INTO MEMORY AL = 1, number of sectors to read (must be nonzero) CH = 00, low eight bits of cylinder number CL = 01, sector number 1-63 (bits 0-5) high two bits of cylinder (bits 6-7, hard disk only) DH = 00 head number DL = 80, drive number (bit 7 set for hard disk) 1000:00005D45 CD13 INT 13 AH = 41,IBM/MS INT 13 Extensions - INSTALLATION CHECK BX = 55AAh, The Magic Number DL=80h ,10000000(b) -> bit 7 on -> hard disk return: BX = AA55h, extension installed AH = 21, 2.1 / EDD-1.1 CX = 5 = 101(b), extended disk *access* functions SUPPORTED *removable* functions NOT supported *EDD* functions SUPPORTED SEE NOTE0 1000:00005D73 CD13 INT 13 AH = 48,IBM/MS INT 13 Extensions - GET DRIVE PARAMETERS DL=80h ,10000000(b) -> bit 7 on -> hard disk result DS:SI = 16F3:0D0A 16F3:00000D0A 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16F3:00000D1A 80 A7 54 02 00 00 00 00 00 02 28 00 00 00 80 00 [ # # 2000:0000062B CD13 INT 13 # AH=08, DISK - GET DRIVE PARAMETERS (PC,XT286,CONV,PS,ESDI,SCSI) # DL=80h ,10000000(b) -> bit 7 on -> hard disk # return: # CX = FEFF, max 255 sectors, max 254 cylinders # DX = FE01, max 254 heads, 1 drive # 2000:00000EBD CD13 INT 13 # AH = 41,IBM/MS INT 13 Extensions - INSTALLATION CHECK # BX = 55AAh, The Magic Number # DL=80h ,10000000(b) -> bit 7 on -> hard disk # return: # BX = AA55h, extension installed # AH = 21, 2.1 / EDD-1.1 # CX = 5 = 101(b), # extended disk *access* functions SUPPORTED # *removable* functions NOT supported # *EDD* functions SUPPORTED # SEE NOTE0 # 2000:00000EEC CD13 INT 13 # AH = 48,IBM/MS INT 13 Extensions - GET DRIVE PARAMETERS # DL=80h ,10000000(b) -> bit 7 on -> hard disk # result # DS:SI = 609C:000C # 609C:000C 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # 609C:001C 80 A7 54 02 00 00 00 00 00 02 00 00 00 00 00 00 # 2000:0000062B CD13 INT 13 # AH = 02, DISK - READ SECTOR(S) INTO MEMORY # AL = 1, number of sectors to read (must be nonzero) # CH = 00, low eight bits of cylinder number # CL = 01, sector number 1-63 (bits 0-5) # high two bits of cylinder (bits 6-7, hard disk only) # DH = 00 head number # DL = 80, drive number (bit 7 set for hard disk) #SEE *IMPORTANT* NOTE2 ] [windows fully running, with "Start" button] [no more interrupt 13h] |
we are using AMI BIOS (3/8/1) for most of the test so some of the description differs from what is said in the manual for the PHOENIX BIOS which I have used as primary reference. Such example is Int 13/AH=41 -- check for extensions. NOTE1:
one, two, three, four... Argh. .stupidity of windows.. First it probes for extended disks read (meaning it can read up to 256 blocks at time), and then ..... READS ONE BLOCK AT TIME!
About the Flow, see Image below (click on it to enlarge).
The outer loop executes approximately 17 times (0x10). Inner loop executes around 1-2 times. If you are going to trace code, once you get to address 7CB2 (top of "green" function) just disable all breakpoints and go to 80D6 (bottom of "green" function") and press F4 (go to cursor). This will just skip all 200+ invocations of this particular interrupt. Then re-enable all breakpoints again. NOTE2: 2000:0000061F CD13 INT 13 AH = 08, DISK - GET DRIVE PARAMETERS (PC,XT286,CONV,PS,E$ AH = 02, DISK - READ SECTOR(S) INTO MEMORY 2000:000006F3 CD13 INT 13 AH = 42, IBM/MS INT 13 Extensions - EXTENDED READ 2000:00000FE1 CD13 INT 13 AH = 41,IBM/MS INT 13 Extensions - INSTALLATION CHECK 2000:00001010 CD13 INT 13 AH = 48,IBM/MS INT 13 Extensions - GET DRIVE PARAMETER$ The above 4 functions are used extensively in Windows to read data off disk, even while in protected mode. What they have done is written 4 wrappers around those 4 functions which will switch from protected mode into real mode, execute 16 bit interrupt in one of those 4 functions, get data and then switch back to protected mode. Since, as I have said, those functions are used extensively they make it difficult to see where else the interrupt line is used outside those 4 places. Thus, it makes sense to rewrite windows and vector table to re-route those 4 functions to call INT13 code via different interrupt. First, we pick some unused interrupt. Here I decided for interrupt 33h (address CCh in vector table). Thus, we are going to change the Vector Table as follows: int # addr contest at the addr INT 13h 4C F00:EED2 INT 33h CC F00:5CB0 replace above with below INT 33h CC F00:EED2 in other words (16 bit-wide view of memory) 0000:00CC 5CB0 replace above with below 0000:00CC EED2 Second we need to update Windows code to call interrupt 33h instead of 13h. That is: 2000:0000061F CD13 INT 13 replace above with below 2000:0000061F CD33 INT 33 2000:000006F3 CD13 INT 13 replace above with below 2000:000006F3 CD33 INT 33 2000:00000FE1 CD13 INT 13 replace above with below 2000:00000FE1 CD33 INT 33 2000:00001010 CD13 INT 13 replace above with below 2000:00001010 CD33 INT 33 This all lets us get those 4 functions out of the way and see where else INT13 is used. Finally like it or not, I will have to disable breakpoints on "start of interrupt" and "end of interrupt", and just leave breakpoint on entry in vector table alone (that is "Data Access" breakpoint at 4ChP). It might potentially make us miss some important data, but hopefully that is not the case. Then press F5 (continue) and as soon as it triggers breakpoint (which will be outside of the scope of the code I have modified) just re-enable all "start" and "end" breakpoints. NOTE3: It is weird interrupt call. Unlike "normal" call its DL argument is set to 81h instead of usual 80h. What I think is going on is that it is trying to probe for 2nd hard disk. Perhaps because of this, it calls itself again from inside of interrupt call. The call occurs at this line: F144:00000341 2EFF1E1901 CALL dword ptr CS:[0119] CS:F144 The bottom line is that, "end of interrupt" line is executed twice. NOTE4: [windows shutdown] [reboot] NOTE5: as per BIOS manual: If not hdd is present. it (int13) is diskette/floppy interrupt. However, if hdd is present it is "fixed disk" interrupt and floppy has been reassigned to int 40. SO.. it is interrupt for HDD/fixed disk. NOTE6: WOW, 16 bit BIOS calls from inside of protected mode... whee! it does jut gazillion times . switch from protected mode to real mode just so that it can make 16 bit BIOS interrupt calls. NOTE7: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
ADDR NT INT Description Status 50 0/0 14 BIOS Serial Interface Supported |
VECTOR TABLE: 0000:0050 F000:E739 BIOS (AMI): start F000:E739 E9D711 JMP near16 ptr 0000f913 end ????? |
WINDOWS 2000: [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+50h (ESI+50) [windows fully running, with "Start" button] [no more interrupt 14h] |
WINDOWS XP: [windows fully running, with "Start" button] [no more interrupt 14h] |
NOTE0: windows shutdown [reboot] NOTE1: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
ADDR NT INT Description Status 54 ??/11 15 BIOS System Functions Interface Supported |
VECTOR TABLE: 0000:0054 F000:F859 BIOS (AMI): start F000:F859 E9247B JMP near16 ptr 00007380 end F000:8739 CA0200 RETF 0002 end2 F000:AC83 CA0200 RETF 0002 end3 F000:8703 CF IRET end4 F000:86FD CA0200 RETF 0002 end5 F000:AECD CA0200 RETF 0002 |
WINDOWS 2000: ["LILO boot:\r\nLoading winblows" text still visible] [real mode] SEE *IMPORTANT* NOTE0 [blank screen, with cursor at left top corner] 2000:00001222 CD15 INT 15 AH = C0, SYSTEM - GET CONFIGURATION (AT mdl 3x9,CONV,XT286,PS) 2000:000004F3 CD15 INT 15 AX = E820h, Newer BIOSes - GET SYSTEM MEMORY MAP EDX = 534D4150h ('SMAP') return EAX = 534D4150h ('SMAP') one, two, three, four, five, six, seven [cursor at left top corner gone, ALL blank screen] 2000:00000E8D CD15 INT 15 AX = E820h, Newer BIOSes - GET SYSTEM MEMORY MAP EDX = 534D4150h ('SMAP') return EAX = 534D4150h ('SMAP') one, two, three, four, five, six 1000:0000448A CD15 INT 15 AH = C0, SYSTEM - GET CONFIGURATION (AT mdl 3x9,CONV,XT286,PS) 1000:00004686 CD15 INT 15 AH = C0, SYSTEM - GET CONFIGURATION (AT mdl 3x9,CONV,XT286,PS) 1000:000044CD CD15 INT 15 AH = C0, SYSTEM - GET CONFIGURATION (AT mdl 3x9,CONV,XT286,PS) one, two 1000:00004518 CD15 INT 15 AH = C0, SYSTEM - GET CONFIGURATION (AT mdl 3x9,CONV,XT286,PS) 1000:0000011B CD15 INT 15 AX = 5300h, Advanced Power Management v1.0+ -INSTALLATION CHECK BX = 0000h, device ID of system BIOS (0000h) return AH = 01, major version (BCD) AL = 02, minor version (BCD) BX = 504Dh ("PM") CX = 3, 11(b) - 0 16-bit protected mode interface supported 1 32-bit protected mode interface supported SEE *IMPORTANT* NOTE1 1000:00001BC4 CD15 INT 15 AH = C0, return system parameters 1000:000050B0 CD15 INT 15 AH = C1, Return Extended BIOS Data Area Address return ES = ???, Segment of EBDA Carry = 1, ERROR AH = 86, Invalid BIOS routine Call (No EBDA) SEE NOTE4 [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+54h (ESI+54) [windows fully running, with "Start" button] [no more interrupt 15h] |
WINDOWS XP: ["LILO boot:\r\nLoading winblows" text still visible] [real mode] SEE *IMPORTANT* NOTE0 [blank screen, with cursor at left top corner] 2000:000004F3 CD15 INT 15 AX = E820h, Newer BIOSes - GET SYSTEM MEMORY MAP EDX = 534D4150h ('SMAP') return EAX = 534D4150h ('SMAP') one, two, three, four, five, six, seven [cursor at left top corner gone, ALL blank screen] 2000:00000D69 CD15 INT 15 AX = E820h, Newer BIOSes - GET SYSTEM MEMORY MAP EDX = 534D4150h ('SMAP') return EAX = 534D4150h ('SMAP') one, two, three, four, five,six 1000:0000011B CD15 INT 15 AX = 5300h, Advanced Power Management v1.0+ -INSTALLATION CHECK BX = 0000h, device ID of system BIOS (0000h) return AH = 01, major version (BCD) AL = 02, minor version (BCD) BX = 504Dh ("PM") CX = 3, 11(b) - 0 16-bit protected mode interface supported 1 32-bit protected mode interface supported 1000:0000011B CD15 INT 15 AX = 5301h, Advanced Power Management v1.0+ - CONNECT REAL-MODE INTERFACE BX = 0000h, device ID of system BIOS (0000h) 1000:0000011B CD15 INT 15 AX = 530Eh, Advanced Power Management v1.1+ - DRIVER VERSION BX = 0000h, device ID of system BIOS (0000h) CH = 01, APM driver major version (BCD) CL = 02, APM driver minor version (BCD) (02h for APM v1.2) Return: CF = 00 ,clear if successful AH = 01, APM connection major version (BCD) AL = 02, APM connection minor version (BCD) 1000:0000011B CD15 INT 15 AX = 5300h, Advanced Power Management v1.0+ -INSTALLATION CHECK BX = 0000h, device ID of system BIOS (0000h) return AH = 01, major version (BCD) AL = 02, minor version (BCD) BX = 504Dh ("PM") CX = 3, 11(b) - 0 16-bit protected mode interface supported 1 32-bit protected mode interface supported 1000:0000011B CD15 INT 15 AX = 5304h, Advanced Power Management v1.0+ - DISCONNECT INTERFACE BX = 0000h, device ID of system BIOS (0000h) 1000:0000011B CD15 INT 15 AH = 5302h, Advanced Power Management v1.0+ - CONNECT 16-BIT PROTMODE INTERFACE BX = 0000h, device ID of system BIOS (0000h) Return: CF = 00,clear if successful AX = F000h, real-mode segment base address of protected-mode 16-bit code segment BX = EF4Dh, offset of entry point CX = 0040h, real-mode segment base address of protected-mode 16-bit data segment ---APM v1.1--- SI = 0E22h, APM BIOS code segment length DI = 0100h, APM BIOS data segment length 1000:0000011B CD15 INT 15 AX = 530Eh, Advanced Power Management v1.1+ - DRIVER VERSION BX = 0000h, device ID of system BIOS (0000h) CH = 01, APM driver major version (BCD) CL = 02, APM driver minor version (BCD) (02h for APM v1.2) Return: CF = 00 ,clear if successful AH = 01, APM connection major version (BCD) AL = 02, APM connection minor version (BCD) 1000:00002764 CD15 INT 15 AH = C0, SYSTEM - GET CONFIGURATION (AT mdl 3x9,CONV,XT286,PS) 1000:00006D0B CD15 INT 15 AH = C1, SYSTEM - RETURN EXTENDED-BIOS DATA-AREA return ES = ????, Segment of EBDA Carry = 1, ERROR AH = 86, Invalid BIOS routine Call (No EBDA) SEE NOTE4 [windows fully running, with "Start" button] [no more interrupt 15h] |
NOTE0:
Interrupt 15 is used internally by Interrupt 13. That is BIOS is using Interrupt 15 internally for its own needs. This means that we have to rewrite c) Vector Table and d) BIOS, so that they use a different interrupt for communication. It is sort of similar to "fix-up" we used in Interrupt 13 except that the "other end" is BIOS and not Windows source. This makes necessary for us to perform one extra step before we can go about and fix code. We have to make BIOS code Read-Write. By the default it is read only. In order to do that we need to: a) Make sure that BIOS is shadowed into RAM, and then b) setup that portion of RAM Read/Write.
Now interrupt is rerouted. :-) For record: here is structure of the Internal call as used by BIOS: F144:000009CB CD15 INT 15 AH = 90, device busy AL = 00, fixed disk by the way of interrupt 13/AH=42, disk read 0000:00007D26 CD13 INT 13 repeats 5++ times. need to rewrite int 13 handler. F000:0000E861 CD15 INT 15 AH=91, interrupt complete AL=00, fixed disk NOTE1: NOTE: this comment only applies to windows 2000. I believe I got APM stuff right in the Windows XP. NOTE: those stuff in regards of APM are just approximate. APM code is weird and confused my debugger to hell requiring *EVERYTHING* (Host,Target,and In-Target Probe) to be hard reset. so the list of APM interrupts/calls might be wrong. there is lots of callback or direct calls. There is lots of internal BIOS calls going on there. for one thing you probably want to disable ALL breakpoints when stepping through the interrupt. some calls I saw: AH=53 AL = 00, AL = 01, Interface connect AL = 02, AL = 04, AL = 0E, APM Driver Version (APM 1.1 only) There will be even more different calls when APM is enabled. NOTE2: when you *ENABLE* APM there will extra APM calls take place. Perhaps it will include this one as well. 1000:0000011B CD15 INT 15 AH=F0, ?????, engage/disengage power management NOTE3: windows shutdown [reboot] NOTE4: This Interrupt/Function (15/C1) is used to query Extended BIOS Data Area (EBDA). You can check out section 3.4 for more details. In our case the interrupt seems to return error that this function is not supported. This is most likely because we have disabled PS/2 mouse in BIOS. The EBDA is used pretty much exclusively for PS/2 mouse only, so once it is disabled there's not much of point having EDBA in use. NOTE5: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. - small differences of offset in a segment. major differences: - does not do one interrupt call at beginning anymore. - does far less interrupt calls with arg AH=C0 and AH=C1 |
ADDR NT INT Description Status 58 12/5 16(22d) BIOS Keyboard Interface Supported |
VECTOR TABLE: 0000:0058 F000:E82E BIOS (AMI): start F000:E82E E9C3B2 JMP near16 ptr 00009af4 end F000:9BBC CA0200 RETF 0002 end2 F000:9B28 CF IRET AH=02 |
WINDOWS 2000: [blank screen, real mode] 2000:0000075D CD16 INT 16 AH=01, KEYBOARD - CHECK FOR KEYSTROKE return ZF=1, no keystroke available 1000:00001C59 CD16 INT 16 AH=01, KEYBOARD - CHECK FOR KEYSTROKE return ZF=1, no keystroke available 1000:00001D74 CD16 INT 16 AH=02, KEYBOARD - GET SHIFT FLAGS return AL=20 = 10100(b) = flags 5= Num Lock on, 3=Alt pressed (?????) 1000:00001C59 CD16 INT 16 AH=01, KEYBOARD - CHECK FOR KEYSTROKE return ZF=1, no keystroke available ["Starting Windows", real mode] [stripe is "4" full] 2000:0000075D CD16 INT 16 AH=01, KEYBOARD - CHECK FOR KEYSTROKE return ZF=1, no keystroke available one, two, three, four, five, six, seven, eight [windows graphic screen shows up (the "window flag"), protected mode] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+58h (ESI+58) [windows fully running, with "Start" button] [no more interrupt 16h] |
WINDOWS XP: [blank screen, real mode] 2000:00000769 CD16 INT 16 AH=01, KEYBOARD - CHECK FOR KEYSTROKE return ZF=1, no keystroke available 1000:000027F9 CD16 INT 16 AH=01, KEYBOARD - CHECK FOR KEYSTROKE return ZF=1, no keystroke available 1000:00002914 CD16 INT 16 AH=02, KEYBOARD - GET SHIFT FLAGS return AL=20 = 10100(b) = flags 5= Num Lock on, 3=Alt pressed (?????) 1000:000027F9 CD16 INT 16 AH=01, KEYBOARD - CHECK FOR KEYSTROKE return ZF=1, no keystroke available [again] 2000:00000769 CD16 INT 16 AH=01, KEYBOARD - CHECK FOR KEYSTROKE return ZF=1, no keystroke available [again] [windows fully running, with "Start" button] [no more interrupt 16h] |
NOTE0: [windows shutdown] [reboot] NOTE1: for reference, here is example how Int 16 is used/setup inside of bios/lilo/win this example/roadmap is for Phoenix BIOS BIOS: F000:0000E2CD : zero vector table F000:0000E2E1 : test zeroing VT was successful F000:00001B1B : set all interrupts to F000:E816 F000:00001B35 : set kbd interrupt to F000:E82E F000:00002A6A : load all vector table into single reg ????? first BIOS screen shows up F000:0000BC58 : some memory comparison/verification after HDD probe after PCI probe repeats 4 times total LILO: structure of interrupt call to KBD when LILO starts vector 0000:00000040 C00007CB code F000:0000E82E EB01 - JMP - short ptr 0000e831 end F000:0000E891 CA0200 - RETF 0002 first interrupt call : "LI" 0B00:0000008A CD16 INT 16 second interrupt call : "LILO boot: _", press enter 0B00:00000918 CD16 INT 16 repeats 3 times windows blank screen 2000:0000075D CD16 INT 16 1000:00001C59 CD16 INT 16 1000:00001C59 CD16 INT 16 //1000:00001D74 CD16 INT 16 4 unmodified interrupt calls NOTE2: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. - small differences of offset in a segment. major differences: - does six less interrupt calls with arg AH=01 |
ADDR NT INT Description Status 5C 0/0 17 BIOS Parallel Printer Interface Supported |
VECTOR TABLE: 0000:005C F000:D08B BIOS (AMI): start F000:D08B 3D0002 CMP AX,0200 end ????? |
WINDOWS 2000: [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+5Ch (ESI+5C) [windows fully running, with "Start" button] [no more interrupt 17h] |
WINDOWS XP: [windows fully running, with "Start" button] [no more interrupt 17h] |
NOTE0: [windows shutdown] [reboot] NOTE1: Since parallel port is disabled,in BIOS, this interrupt is "used" only one time (read) instead of three times before. NOTE2: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
ADDR NT INT Description Status 60 0/0 18 BIOS Secondary Boot Request Supported |
VECTOR TABLE: 0000:0060 F000:E000 BIOS (AMI): start F000:E000 EA05E000F0 JMP far16 ptr f000:0000e005 end ????? |
WINDOWS 2000: [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+60h (ESI+60) [windows fully running, with "Start" button] [no more interrupt 18h] |
WINDOWS XP: [windows fully running, with "Start" button] [no more interrupt 18h] |
NOTE0: [windows shutdown] [reboot] NOTE1: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
ADDR NT INT Description Status 64 0/0 19 BIOS Primary Boot Request Supported |
VECTOR TABLE: 0000:0064 F000:881E BIOS (AMI): start F000:881E 2E833EDEF600 CMP word ptr CS:[f6de],0000 end ????? |
WINDOWS 2000: [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+64h (ESI+64) [windows fully running, with "Start" button] [no more interrupt 19h] |
WINDOWS XP: [windows fully running, with "Start" button] [no more interrupt 19h] |
NOTE0: [windows shutdown] [reboot] NOTE1: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
ADDR NT INT Description Status 68 12/13 1A BIOS System Timer Interface Supported |
VECTOR TABLE: 0000:0068 F000:FE6E BIOS (AMI): start F000:FE6E E91B5F JMP near16 ptr 00005d8c end F000:9C28 CA0200 RETF 0002 end2 F000:5DAA CF IRET |
WINDOWS 2000: [blank screen, real mode] 2000:000007C4 CD1A INT 1a AH=00h, TIME - GET SYSTEM TIME return: CX:DX = number of clock ticks since midnight AL = midnight flag, nonzero if midnight passed since time last read one,two 1000:00005671 CD1A INT 1a AX = B101h, PCI BIOS v2.0c+ - INSTALLATION CHECK EDI = 00000000h return: AH = 00h,installed EDX = 20494350h (' ICP') EDI = 0h, physical address of protected-mode entry point (see #00731) AL = 01h, PCI hardware characteristics (see #00730) 0 - configuration space access mechanism 1 supported BH = 02h, PCI interface level major version (BCD) BL = 10h, PCI interface level minor version (BCD) CL = 01h, number of last PCI bus in system 1000:000056EB CD1A INT 1a AX = B10Eh, PCI BIOS v2.1+ - GET IRQ ROUTING INFORMATION BX = 0000h DS = F000h, segment/selector for PCI BIOS data one, return: BX = 00h, CF = 1 AH = 89h, buffer too small two return: BX = 00h, bit map of IRQ channels permanently dedicated to PCI CF = 0 AH = 00h, Successful 2000:000007C4 CD1A INT 1a AH=00h, TIME - GET SYSTEM TIME return: CX:DX = number of clock ticks since midnight AL = midnight flag, nonzero if midnight passed since time last read ["Starting Windows", real mode] [stripe is "4" full] 2000:000007C4 CD1A INT 1a AH=00h, TIME - GET SYSTEM TIME return: CX:DX = number of clock ticks since midnight AL = midnight flag, nonzero if midnight passed since time last read one,two,three,four,five,six????? [windows graphic screen shows up (the "window flag"), protected mode] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+68h (ESI+68) [windows fully running, with "Start" button] [no more interrupt 1Ah] |
WINDOWS XP: [blank screen, real mode] 2000:000007D0 CD1A INT 1a AH=00h, TIME - GET SYSTEM TIME return: CX:DX = number of clock ticks since midnight AL = midnight flag, nonzero if midnight passed since time last read one,two 1000:00007661 CD1A INT 1a AX = B101h, PCI BIOS v2.0c+ - INSTALLATION CHECK EDI = 00000000h return: AH = 00h,installed EDX = 20494350h (' ICP') EDI = 0h, physical address of protected-mode entry point (see #00731) AL = 01h, PCI hardware characteristics (see #00730) 0 - configuration space access mechanism 1 supported BH = 02h, PCI interface level major version (BCD) BL = 10h, PCI interface level minor version (BCD) CL = 01h, number of last PCI bus in system 1000:000076DB CD1A INT 1a AX = B10Eh, PCI BIOS v2.1+ - GET IRQ ROUTING INFORMATION BX = 0000h DS = F000h, segment/selector for PCI BIOS data one, return: BX = 00h, CF = 1 AH = 89h, buffer too small two return: BX = 00h, bit map of IRQ channels permanently dedicated to PCI CF = 0 AH = 00h, Successful 2000:000007D0 CD1A INT 1a AH=00h, TIME - GET SYSTEM TIME return: CX:DX = number of clock ticks since midnight AL = midnight flag, nonzero if midnight passed since time last read one,two,three,four,five,six,seven,eight [windows fully running, with "Start" button] [no more interrupt 1Ah] |
NOTE0: [windows shutdown] [reboot] NOTE1: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. - more streamlined start. |
ADDR NT INT Description Status 6C 0/0 1B BIOS Control Break Interrupt Supported |
VECTOR TABLE: 0000:006C F000:FF53 BIOS (AMI): start F000:FF53 CF IRET end F000:FF53 CF IRET |
WINDOWS 2000: [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+6Ch (ESI+6C) [windows fully running, with "Start" button] [no more interrupt 1Bh] |
WINDOWS XP: [windows fully running, with "Start" button] [no more interrupt 1Bh] |
NOTE0: [windows shutdown] [reboot] NOTE1: **Important** Both Interrupt 1C and Interrupt 1B share the same "Interrupt Service Routine" (ISR). Yes, it just happen to be an one-liner which does only one thing. Just calls "IRET". However, an important implication of this is that If I will try to trace interrupt 1B by setting breakpoints on Entry and Exit from Interrupt Routine, I will instead trip on interrupt calls to Interrupt 1C. NOTE2: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
ADDR NT INT Description Status 70 0/0 1C BIOS User System Timer Interrupt Supported |
VECTOR TABLE: 0000:0070 F000:FF53 BIOS (AMI): start F000:FF53 CF IRET end F000:FF53 CF IRET |
WINDOWS 2000: ["LILO boot:\r\nLoading winblows" text still visible] [real mode] SEE *IMPORTANT* NOTE1 2000:00000D22 8B0D MOV CX,word ptr [DI] 2000:00000D24 8B5502 MOV DX,word ptr [DI]+2 CX = FF53h DX = F000h DI = 70h save vector for Int 1C into CX register 2000:00000D2A 8905 MOV word ptr [DI],AX 2000:00000D2E 894502 MOV word ptr [DI]+02,AX DI = 70h, AX = 0D73h, AX = 2000h, setup new interrupt handler 2000:00000D63 890D MOV word ptr [DI],CX 2000:00000D65 895502 MOV word ptr [DI]+02,DX DI = 70h, CX = FF53h, DX = F000h, restore old interrupt handler [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+70h (ESI+70) [windows fully running, with "Start" button] [no more interrupt 1Ch] |
WINDOWS XP: ["LILO boot:\r\nLoading winblows" text still visible] [real mode] SEE *IMPORTANT* NOTE1 2000:0BFE 8B0D MOV CX,word ptr [DI] 2000:0C00 8B5502 MOV DX,word ptr [DI]+2 CX = FF53h DX = F000h DI = 70h save vector for Int 1C into CX register 2000:0C06 8905 MOV word ptr [DI],AX 2000:0C0A 894502 MOV word ptr [DI]+02,AX DI = 70h, AX = 0C4Fh, AX = 2000h, setup new interrupt handler 2000:0C3F 890D MOV word ptr [DI],CX 2000:0C41 895502 MOV word ptr [DI]+02,DX DI = 70h, CX = FF53h, DX = F000h, restore old interrupt handler [windows fully running, with "Start" button] [no more interrupt 1Ch] |
NOTE0: [windows shutdown] [reboot]NOTE1: Interrupt 1C is being called from inside of System Timer Interrupt (Interrupt 08) on every clock tick. In other words huge number of times :-) Interrupt 08: F000:0000FEA5 E9C7E1 JMP near16 ptr 0000e06f F000:0000E0B7 CD1C INT 1c F000:0000E0C1 CF IRET It means we have to rewrite BIOS code once again. See for details on how to make Shadow RAM Read/Write. Next. Since the "code handler" for Interrupt 1C seems to be just one-liner "IRET" we can assume it is probably safe to simply "eliminate" this call from inside of Interrupt Service Routine (ISR) for Interrupt 8. Thus we would be replacing code for "INT 1C" with two NO-OP instructions. That is: F000:0000E0B7 CD1C INT 1c replace above with the two below F000:0000E0B7 90 NOP F000:0000E0B8 90 NOP If I do above change, it seems to get stuck in this loop 2000: 2000:00000D4F 6683FB00 CMP EBX,00000000 2000:00000D53 74FA JE short ptr 00000d4f XP: 2000:00000C2B 6683FB00 CMP EBX,00000000 2000:00000C2F 74FA JE short ptr 00000d4f Setting EBX to 01h gets it out of this loop. Then it stars-up, but more slowly than usual (there is at least one loop, in windows code, that needs to time out). Overall works, but slower. I'm not sure of the reason for slow-down. Experiment trying to reroute the call from interrupt 08 to "IRET" at F000:FF53 via Interrupt CCh (in similar way as we did for Interrupt 15 , for example) does not seem to work. it seems to hang somewhere in BIOS. I am not sure what to make out of this. Perhaps there's going on some dirty magic in background which implicitly makes it depend on 1C. NOTE2:As start/end [of interrupt] show it is just "dummy" interrupt. Thus the only "implementation requirement" is that it is be called from int 8 every tick, and then just execute IRET. NOTE3:**Important** Both Interrupt 1C and Interrupt 1B share the same "Interrupt Service Routine" (ISR). Yes, it just happen to be an one-liner which does only one thing. Just calls "IRET". However, an important implication of this is that If I will try to trace interrupt 1B by setting breakpoints on entry and exit from the routine, I will instead trip on interrupt calls to Interrupt 1C. On the same token, attempts to trace interrupt 1C might get polluted by use of interrupt 1B (thought it does not seem to be case) NOTE2: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
ADDR NT INT Description Status 74 0/0 1D BIOS Video Init Parameters Supported |
VECTOR TABLE: 0000:0074 F000:F0A4 BIOS (AMI): start F000:F0A4 3828 CMP byte ptr [BX+SI],CH end ????? |
WINDOWS 2000: [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+74h (ESI+74) [windows fully running, with "Start" button] [no more interrupt 1Dh] |
WINDOWS XP: [windows fully running, with "Start" button] [no more interrupt 1Dh] |
NOTE0: [windows shutdown] [reboot] NOTE1: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
ADDR NT INT Description Status 78 0/0 1E BIOS Diskette Parameters Supported |
VECTOR TABLE: 0000:0078 F000:EFC7 BIOS (AMI): start F000:EFC7 DF02 FILD word ptr [BP+SI] end F000:F138 CF IRET ????? |
WINDOWS 2000: [blank screen, real mode] 2000:00001ED2 BB7800 MOV BX,0078 2000:00001ED5 268B07 MOV AX,word ptr ES:[BX] 2000:00001ED8 268B5702 MOV DX,word ptr ES:[BX]+02 ES=00h, AX=EFC7h, DX=F000h, load vector table entry for int 1E into DX:AX [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+78h (ESI+78) [windows fully running, with "Start" button] [no more interrupt 1Eh] |
WINDOWS XP: [windows fully running, with "Start" button] [no more interrupt 1Eh] |
NOTE0: [windows shutdown] [reboot] NOTE1: LILO: F144:00001CC2 C5367800 LDS SI,word ptr [0078] ????? NOTE1: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. - much simpler start. does not even do that extra save. |
ADDR NT INT Description Status 7C 0/0 1F BIOS Video Graphic Characters Supported |
VECTOR TABLE: 0000:007C C000:7931 BIOS (AMI): start C000:00007931 78CC JS short ptr 000078ff end ????? |
WINDOWS 2000: [blank screen, real mode] SEE *IMPORTANT* NOTE1 [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+7Ch (ESI+7C) [windows fully running, with "Start" button] [no more interrupt 1Fh] |
WINDOWS XP: [blank screen, real mode] SEE *IMPORTANT* NOTE1 [windows fully running, with "Start" button] [no more interrupt 1Fh] |
NOTE0: [windows shutdown] [reboot] NOTE1: The vector table entry is READ by the way of interrupt 10 call. 1000:00001C88 CD10 INT 10 C000:00006546 C43E7C00 LES DI,word ptr [007c] one, two, three, four, five, six NOTE2: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
ADDR NT INT Description Status 100 0/0 40 BIOS Diskette (when fixed disk present) Supported |
VECTOR TABLE: 0000:0100 F000:EC59 BIOS (AMI): start F000:EC59 E9DF01 JMP near16 ptr 0000ee3b end F144:1C40 CF IRET |
WINDOWS 2000: [blank screen, real mode] SEE *IMPORTANT* NOTE2 [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+100h (ESI+100) [windows fully running, with "Start" button] [no more interrupt 40h] |
WINDOWS XP: [blank screen, real mode] SEE *IMPORTANT* NOTE2 [windows fully running, with "Start" button] [no more interrupt 40h] |
NOTE0: [windows shutdown] [reboot] NOTE1: LILO: an call by the way of interrupt 13 once, twice NOTE2: This interrupt was called once by the way of interrupt 13. See Interrupt 13 for more details on this call. 1000:00003989 CD13 INT 13 AH=15, DISK - GET DISK TYPE (XT 1986/1/10 or later,XT286,AT,PS) DL=00, A: floppy (?????) return: AH=00, no such drive. F144:000003EF CD40 INT 40 AH=15, DISK - GET DISK TYPE (XT286,AT,PS) DL=00 return AH=00, no such drive. F144:00001C40 CF IRET F144:000003F1 CA0200 RETF 0002 NOTE3: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
ADDR NT INT Description Status 104 0/0 41 BIOS Fixed disk 0 parameters Supported |
VECTOR TABLE: 0000:0104 F144:0040 BIOS (AMI): start F144:0040 0004 ADD byte ptr [SI],AL end ????? |
WINDOWS 2000: ["LILO boot:\r\nLoading winblows" text still visible] [real mode] SEE *IMPORTANT* NOTE2 [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+74h (ESI+74) [windows fully running, with "Start" button] [no more interrupt 41h] |
WINDOWS XP: ["LILO boot:\r\nLoading winblows" text still visible] [real mode] SEE *IMPORTANT* NOTE2 [windows fully running, with "Start" button] [no more interrupt 41h] |
NOTE0: [windows shutdown] [reboot] NOTE1: SYSTEM DATA - HARD DISK 0 PARAMETER TABLE ADDRESS [NOT A VECTOR!] It supposedly is not as much ISR as pointer to data storage area for the first disk parameter table. For that matter, you might want to use "Data Access" breakpoint instead of usual "Execute" breakpoint at the address pointed by the entry in the Vector Table (F144:40h here). NOTE2: It is being read many times (each time) by the way of Interrupt 13 call. The two relevant lines in ISR 13 are as shown below: (a) F144:000008FB 26C41F LES BX,word ptr ES:[BX] before: BX=0104h, ES=0000h after: BX=0040h, ES:F144h (b) F144:00000931 26AC LODS byte ptr ES:[SI] ES=F144h SI=0041h In regards of (a): To get around the first line (the one with LES instruction), we pick our favorite vector 33h (CCh in the Vector Table) int # addr contest of the cell INT 33h CCh F000:5CB0 replace above with below INT 33h CCh F144:0040 INT 41h 104 F144:0040 Next we edit BIOS code to use vector 33h instead of 41h. See Interrupt 15 and Shadow BIOS for details on how to make Shadow RAM Read/Write. The magic line is few lines before the LES instruction. F144:000008E7 BB0401 MOV BX,0104 Thus we do: F144:000008E7 BB0401 MOV BX,0104 replace above with below F144:000008E7 BBCC00 MOV BX,00CC In regards of (b): In similar way we could get around second line (the one which uses "LODS" instruction). However this one being triggered only when we set up "Data Access" breakpoint on F144:0040h instead of usual "Execute" breakpoint on the said address. Thus we can get around this line by simply not setting that breakpoint. Furthermore, unlike the vector table changes, it would be not as easy to setup alternative place where the LOAD instruction could refer to, so unselecting this break points is the best way to deal with it. NOTE3: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
ADDR NT INT Description Status 118 0/0 46 BIOS Fixed disk 1 parameters Supported |
VECTOR TABLE: 0000:0118 F144:0050 BIOS (AMI): start F144:0050 3201 XOR AL,byte ptr [BX+DI] end ????? |
WINDOWS 2000: [blank screen,real mode] SEE *IMPORTANT* NOTE2 [windows graphic screen shows up (the "window flag")] [blue "Staring up" bar is full"] [protected mode] 0008:80401E22 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] saves vector table to ~ 360000+118h (ESI+118) [windows fully running, with "Start" button] [no more interrupt 46h] |
WINDOWS XP: [blank screen,real mode] SEE *IMPORTANT* NOTE2 [windows fully running, with "Start" button] [no more interrupt 46h] |
NOTE0: [windows shutdown] [reboot] NOTE1: SYSTEM DATA - HARD DISK 1 DRIVE PARAMETER TABLE ADDRESS [NOT A VECTOR!] It supposedly is not as much ISR as pointer to data storage area for the second disk parameter table. For that matter, you might want to use "Data Access" breakpoint instead of usual "Execute" breakpoint at the address pointed by the entry in the Vector Table (F144:50h here). NOTE2: It is being read ONCE by the way of Interrupt 13 call. It is most likely query for the 2nd hard disk. 2000: 1000:00003F72 CD13 INT 13 XP: 1000:00005CD2 CD13 INT 13 AH=15, DISK - GET DISK TYPE (XT 1986/1/10 or later,XT286,AT,PS) DL=81h ,10000000(b) -> bit 7 on -> hard disk, ????? return AH=00h , no such drive. SEE NOTE3 for Interrupt 13 F000:EED2 E961FF JMP near16 ptr 0000ee36 F144:000008FB 26C41F LES BX,word ptr ES:[BX] before: BX=0118h, ES=0000h after: BX=0050h, ES:F144h F144:0000035E CA0200 RETF 0002 NOTE3: If you setup "Data Access" breakpoint at F144:0050h (instead of the usual "Execute" style breakpoint), you will get some more hits. For 2000: Among other this one. Repeats around 5 times. 1000:000045B2 26663B05 CMP EAX,dword ptr ES:[DI] ES=F000 DI=1490 For XP: All of the below are some access to area pointed by the vector table entry (disk param area) and not the vector table itself. With the sole exception of indirect access via int 13 call. 1000:00006F82 268A4707 MOV AL,byte ptr ES:[BX]+07 1000:00007FC2 268A07 MOV AL,byte ptr ES:[BX] 1000:00005CD2 CD13 INT 13 F144:0000035E CA0200 RETF 0002 1000:0000840E 268A07 MOV AL,byte ptr ES:[BX] [start of protected mode] 001B:77F52DA8 8908 MOV dword ptr [EAX],ECX 001B:77F52CBF 8B08 MOV ECX,dword ptr [EAX] 001B:77F520EB F3AB REP STOS dword ptr [EDI] 001B:77F81198 F3A5 REP MOVS dword ptr [EDI],dword ptr [ESI] [windows up with a sand-clock user on screen] 001B:77F56D1D 668B06 MOV AX,word ptr [ESI] multiple hits... However, since there was no use of the vector table to ascertain that this particular region of memory is used for fixed disk, it does not seem likely those data accesses are related to hard disk. NOTE4: 2000 vs XP The visible changes are in green. minor "standard" differences: - does not save vector table anymore. |
This table summarizes Interrupts usage for both Windows XP as well as Windows 2000. Results here are presented in tabular form which lists a) total number of times given address was accessed, then b) Total number times given address as used in form of interrupt call (as opposed to data read/write from given address), and finally total number of unique functions which had been used with given interrupt. What you really care for are just entries in RED.
Int |
BIOS Interrupt Description |
Total Interrupt Uses |
Total Interrupts Calls |
Total Unique Interrupt Calls |
|||
---|---|---|---|---|---|---|---|
2000 |
XP |
2000 |
XP |
2000 |
XP |
||
10 |
Video Interface |
16 |
12 |
13 |
11 |
12 |
11 |
11 |
Equipment Check |
2 |
1 |
1 |
1 |
1 |
1 |
12 |
Memory Request |
1 |
0 |
0 |
0 |
0 |
0 |
13 |
Fixed Disk Interface |
lots+1 |
lots |
lots |
lots |
6 |
5 |
14 |
Serial Interface |
1 |
0 |
0 |
0 |
0 |
0 |
15 |
System Functions Interface |
~22+1 |
22 |
~22 |
22 |
~4+ |
8 |
16 |
Keyboard Interface |
13 |
5 |
12 |
5 |
2 |
2 |
17 |
Parallel Printer Interface |
1 |
0 |
0 |
0 |
0 |
0 |
18 |
Secondary Boot Request |
1 |
0 |
0 |
0 |
0 |
0 |
19 |
Primary Boot Request |
1 |
0 |
0 |
0 |
0 |
0 |
1A |
System Timer Interface |
13 |
13 |
12 |
13 |
3 |
3 |
1B |
Control Break Interrupt |
1 |
0 |
0 |
0 |
0 |
0 |
1C |
User System Timer Interrupt |
4 |
3 |
0 |
0 |
0 |
0 |
1D |
Video Init Parameters |
1 |
0 |
0 |
0 |
0 |
0 |
1E |
Diskette Parameters |
4 |
0 |
0 |
0 |
0 |
0 |
1F |
Video Graphic Characters |
1 |
0 |
0 |
0 |
0 |
0 |
40 |
Diskette Interface |
1 |
0 |
0 |
0 |
0 |
0 |
41 |
Fixed disk 0 parameters |
1 |
0 |
0 |
0 |
0 |
0 |
46 |
Fixed disk 1 parameters |
1 |
0 |
0 |
0 |
0 |
0 |
"~" means approximate number
"+" means than there's more than given number of interrupts.
Windows 2000 and XP have very similar interrupt usage pattern. Thus there's no big difference in description/summary of them here. The notable differences are that XP won't use those Interrupt/Functions:
1000:00000000 CD10 INT 10 AH=00 - VIDEO - SET VIDEO MODE AL=12 - 12h = G 80x30 8x16 640x480 16/256K . A000 VGA 2000:000006F3 CD13 INT 13 AH = 42, IBM/MS INT 13 Extensions - EXTENDED READ DL=80h ,10000000(b) -> bit 7 on -> hard diskAnother benefit of XP over 2000 would be that it's APM implementation seems to be more sane/reasonable. I didn't have much of trouble trying to trace out XP's interaction with APM, while for 2000 it would hard-crash my whole testing system.
Having said it all, let's go over interrupts which are used by both versions of windows, and have similar pattern of usage.
We start off with the full vector table.
Next we nail it down to a list of 19 "BIOS Supported" interrupts.
Of that list we can eliminate around 11 interrupts which are not used at all (thanks in part to our disabling many external devices in BIOS before). By "not used at all" I mean that the only access to them is read-style access that is at address 0008:80401E22 where every single vector from the Vector Table is being saved, presumably before Windows switches to its own Vector Table. The only other kind of access would be the internal use by BIOS itself, both in the form of calling the interrupt and in reading off the Vector Table entry for the interrupt of the ISR itself. That allows us to exclude 11 interrupts total from the list of 19 "BIOS Supported" interrupts, which leaves us with 8 "BIOS Supported" interrupts.
Also "use" of interrupt 1E consists only of a few extra reads by Windows (to set up its own ISR), and it is not executed, so it can be eliminated as well. This lets us exclude one more interrupt.
This leaves us with 7 "BIOS Supported" interrupts which are used in some way. Those are the following interrupts:
IRQ # Name # of Uniq Uses 10 Video Interface 11 11 Equipment Check 1 13 Fixed Disk/Diskette Interface 5 15 System Functions Interface 8 16 Keyboard Interface 2 1A System Timer Interface 3 1C User System Timer Interrupt 0
Let's go over each of them:
All we care about is the final screen when Windows is up, so issues like setting text modes are not important. It would be OK to just return dummy+static+valid data.
However, Windows will use this interrupt to query about text font information, so we have to support this particular feature in some way or another.
Easy to implement, our function will just need to return static data which lists the supported hardware. For example, AX=22h would work out nicely as a return value for our system.
This is probably the first of the two more complicated, and most used interrupts. Might be hard to get supported. We have to support functions: AH=02,08,15,41,42,48
This is probably the second of the most complicated interrupts.
Some of the support probably will be fairly easy and just require the return of static data (ex: memory map), Other functions like APM queries might present more difficulty, as such queries occur even if APM is supposed to be disabled.
It is sort of similar to Interrupt 10. We do not care much about it; all we care about is the end result when Windows is fully running and at that time Windows has its own ISR. Probably easy to implement, just return dummy+static+valid data.
Hard to say. Timer part might be easy.
However, this interrupt also doubles as ISR for PCI stuff. The data being returned for PCI seems be fairly static, so it might be not that hard to get it to work.
Our implementation requirement will be that it is to be called from Interrupt 8 every clock tick. Windows will attach its own ISR to it, so it will expect it to be functional.
For this interrupt there is some weird interaction going on in the background. I am not sure if this interaction is hardware or "bios-ware" related, but it might potentially foretell some issues with this interrupt during implementation it.
Overall Interrupt 1C is just a very simple ISR. Its code consists of just a one-liner : "IRET" instruction. Its implementation is that it is being called from inside of Interrupt 8.
Of all above, 1C should be one of the easiest to implement (just "IRET"+ call from int 8).
According to my tests it does not appear as if either Windows 2000 or Windows XP make any use of either "BIOS32" Service Routines.
On our system BIOS32 seems to be implemented. The magic head ("_32_") seems to be located at address 0xFD950h. This BIOS32 Service Directory Header seems in turn to point to BIOS32 Service Directory Calling Interface located at 0xFD960 (just right after the header). This Calling Interface seems to implement two functions going by the names : a) "$PCI" and b) "$BLK.".
In our memory we have implemented Plug and Play BIOS. So in theory it would seem like BIOS32 could be a convenient gateway to this as well. However, it does not seem as if BIOS32 is implementing a "$PnP" function (which would just refer to the PnP BIOS).
I also could not find what is the function with argument "$BLK". There's code for it, but it does not seem to be documented anywhere on the Internet.
More details on BIOS32 can be found in the Phoenix BIOS Manual [7] , pages 39 and 40. Another source of information is in Standard BIOS 32-bit Service Directory Proposal [15]. Here's provided local copy of the said standard proposal. .
Details: 1) The BIOS32 Service Directory Header Location: 0xFD950 _ 3 2 _ : Magic ID (0x5F 0x33 0x32 0x5F) 00 0F D9 60 : ptr to BIOS32 Service Directory Calling Interface 00 : Version 01 : Len of Hdr in paragraphs.; 1*paragraph=16 bytes 94 : checksum, sums to 0x300. + 00 00 00 00 00 : Reserved, all set to 0. ----------------------------------------------------- Total : 16 bytes 2) The BIOS Service Directory Calling Interface Location: 0xFD960 Component Existence Function: Input: BL = 0; EAX = Component ID. Possible arguments : $PCI,$BLK,$PnP Output: AL = Status 00 = success 80 = function not supported 81 = service does not exist EBX/ECX/EDX = Location/Length/Entry 3) 32-bit BIOS Service Code BIOS32 Components: $PCI Location: F000:D9F8 Length : Entry : $BLK Location: F000:D992 Length : Entry : $PnP (not really bios32 function) Location: F000:7030 Length : Entry :
Summary : BIOS32 is not used by either Windows 2000 or Windows XP.
In regards to "PnP BIOS", it seems that Windows 2000 is making extensive use of it while in real mode, while it does not use it anymore while in protected mode. Windows XP is pretty much similar in that regard.
Documentation on the Plug and Play BIOS can be found in the Phoenix BIOS Manual [7] Pages 70 to 76.
Further "documentation" can be found at Microsoft's web site where they have Plug and Play BIOS Technology [16] web page. In there you should be able to go to "Industry Standards". There you should find two, zipped, papers titled: a) "Plug and Play BIOS Specification, Version 1.0A" and b)"Plug and Play BIOS CLARIFICATION Paper for V1.0A". Having said this, going there is not a good idea. For one thing they have this brain-dead web page which does not work with Mozilla, then you will find out that documents are in RTF (Rich Text Document) instead of PS or PDF. And once you finally convert it to readable format (OpenOffice.org [31] becomes useful here), you will find 55 pages of useless information. To save all the pain I have put local copies here, already converted into PDF format: LOCAL COPY:Plug and Play BIOS Specification, v1.0A and LOCAL COPY:Plug and Play BIOS CLARIFICATION, for v1.0A
The main point of PnP from our viewpoint would be APM. There are other services of PnP like "MultiBoot III", "SMBIOS", "PnP ISA", "Docking Station Information" etc.
On our system Plug And Play BIOS is located at 0xF7030. At that point we have a rather sizable magic header 21 bytes long.
Details: 1) PnP BIOS Support Installation Check Location: 0xF7030 $ P n P : Magic ID (0x24, 0x50, 0x6E, 0x50) 10 : Version 21 : Length, in bytes. 00 00 : Control Field 04 : CheckSum (sums to 0x500h) 00 00 00 00 : Event-notification Flag Address DC 5D 00 F0 : Real Mode; Entry Point; IP:CS=F000:5DDC 04 5E : Protected Mode; Entry Point; IP=5E04) 00 00 0F 00 : Protected Mode; Code Segment; CS=F00 00 00 00 00 : OEM Device Identifier 00 F0 : Real Mode; Data Segment; DS=F000 + 00 00 0F 00 : Protected Mode; Data Segment; DS=F00 ----------------------------------------------------- Total : 21 bytes long
Doing experiments by "erasing" the magic line "$PnP" from Shadow RAM (that is just replacing the string "24506E50" with "00000000") and starting Windows will not prevent it from running. Thus we can probably safely conclude that Plug and Play BIOS is not required in order to run Windows.
BIOS Implements both basic BIOS Data Area as well as Extended BIOS Data Area. The two are described below.
Our analysis seems to boil down to the fact that we probably don't have to have either of the BIOS Data Areas for MS Windows to start.
This is the oldest one is and is located at static location at address 400h-501h. On our system it looks as follows:
Contents of basic BIOS Data Area at 400h-501h:
000000400P 0000 0000 0000 0000 0000 0000 0000 9FC0 ................ 000000410P 0022 7FFE 9102 2010 0000 001E 001E 0000 ....... ........ 000000420P 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000430P 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000440P 2025 0000 0000 0000 0300 0050 1000 0000 % ........P..... 000000450P 1800 0000 0000 0000 0000 0000 0000 0000 ................ 000000460P 0D0E D400 2903 8030 0002 FF09 03F1 0009 .....)0......... 000000470P 0000 0000 0100 0008 1414 1414 0101 0101 ................ 000000480P 001E 003E 1018 6000 1109 000B 0058 0000 ..>....`....X... 000000490P 0000 0000 0000 1210 0000 0000 0000 0000 ................ 0000004A0P 0000 0000 0000 0000 39E8 C000 0000 0000 .........9...... 0000004B0P 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000004C0P 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000004D0P 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000004E0P 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000004F0P 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000500P 0000 0000 0000 0000 0000 0000 0000 0000 ................
Having it all zeroed will not prevent Windows from starting. However, we have to kick BIOS into head, since otherwise it will just loop forever inside of Interrupt 16 (keyboard). To get BIOS back on track just replace the conditional jump at F000:E2DB with two NOP's (90h's).
At offset 0xEh, we have a pointer to the Extended BIOS Data Area, currently set, in our case, to 0x9FC0h. Windows will make interrupt 15/C1 call to query for Extended Data Area (3.4.2) which would be superset of the basic BIOS Data Area. Since I would assume that that interrupt call just uses the contents of 0x0Eh, I could further speculate that the Extended BIOS Data Area is not necessary either.
I would assume it is used by Windows on the basis that Windows does test for Extended Data Area (3.4.2) which is sort of a superset of the basic Data Area.
The Extended BIOS Data Area does not have fixed location and has to be queried via Int 15/C1.
Checking out Interrupt call 15/AH=C1, returns Carry Flag set to 1 and Register AH=86, which means "Invalid BIOS Routine Call (no EBDA)". That is sort of expected given the fact that EBDA is only for PS/2 mouse and we had disabled this in BIOS. The bottom line is that we probably don't need to implement EBDA to get Windows up.
There is a second way to find out where EBDA is by using basic BDA, and looking at offset 0xEh which should contain the address of EBDA. In 3.4.1 we have set it to 0 and it didn't prevent Windows from starting, further supporting our argument that we don't need EBDA for Windows to run.
Advanced Configuration and Power Interface - ACPI
BIOS's/Firmware Implementation of ACPI would consist of two (three) elements:
ACPI's web site :
http://www.acpi.info
Overview of ACPI :
http://www.acpi.info/papers/ACPI_Overview.pdf
ACPI Specification :
http://www.acpi.info/DOWNLOADS/ACPIspec-2-0a.pdf
Some information about ACPI is being returned via Int 15/AX=E820 - Query System Address Map interrupt call.
ACPI's usage by Windows, and Windows' dependency on BIOS's support of ACPI has not been investigated at the present time. However, in general just like with PNPBIOS and BIOS32, it is highly unlikely Windows would *require* ACPI in order to boot, and it is more likely a "useful", but nevertheless optional component.
Having analyzed both Windows 2000 and Windows XP, we hereby conclude that....
We have some good news. ACPI, BIOS32, PnP BIOS, basic BIOS Data Area, and Extended BIOS Data area do NOT seem to be necessary for Windows to start. And even if they are present, they can be disabled without ill effects on Windows. This leaves us with BIOS interrupts only. See section 3.1.5 For details on Interrupts.
PCI stuff is queried only via the two interrupt calls/functions below, with no BIOS32 involved
1000:00007661 CD1A INT 1a AX = B101h, PCI BIOS v2.0c+ - INSTALLATION CHECK 1000:000076DB CD1A INT 1a AX = B10Eh, PCI BIOS v2.1+ - GET IRQ ROUTING INFORMATIONInteraction with APM seems to be reduced to those five interrupt calls listed below. And while PnP BIOS seems to be involved as well (PnP BIOS takes care of APM too), it can be disabled with no ill effects.
1000:0000011B CD15 INT 15 AX = 5300h, Advanced Power Management v1.0+ -INSTALLATION CHECK 1000:0000011B CD15 INT 15 AX = 5301h, Advanced Power Management v1.0+ -CONNECT REAL-MODE INTERFACE 1000:0000011B CD15 INT 15 AH = 5302h, Advanced Power Management v1.0+ -CONNECT 16-BIT PROTMODE INTERFACE 1000:0000011B CD15 INT 15 AX = 5304h, Advanced Power Management v1.0+ -DISCONNECT INTERFACE 1000:0000011B CD15 INT 15 AX = 530Eh, Advanced Power Management v1.1+ -DRIVER VERSIONFinally there's ACPI stuff which is being queried as shown below. It is not clear to what extent Windows depends on the presence of ACPI tables in order to function properly.
2000:000004F3 CD15 INT 15 AX = E820h, Newer BIOSes - GET SYSTEM MEMORY MAP EDX = 534D4150h ('SMAP')While both Basic and Extended BIOS Data Areas are used, as our experimenting has shown they are optional and thus not necessary for windows to run.
Interrupt usage for Windows 2000 and Windows XP seems very similar with XP being slightly more conservative on BIOS Interrupt usage. That would make it somewhat easier to implement, but the difference is not big.
To summarize, in order for SEBOS [20] and LinuxBIOS [18] to be able to run Windows, we would want to start our task using Windows XP, and trying to implement some subset of BIOS Interrupts. primarily the 6 (7) interrupts listed in sections 3.1.5 and 3.1.4.
Here I list possible issues which could be worked on in the future. Just having them listed here does not mean that any of this will actually happen. There are many *more* interesting projects than this :-)
We would like to thank the following people for help (in no particular order):
Also thanks go to all the people who created all those wonderful programs which helped me create this paper. This includes GNU Emacs [25], which I have used for heavy duty editing. Gnu Nano [26] which was excellent light-weight work. Dia [27]for generating flow charts. The Open Office [31] was used to generate html tables. The Gimp [28]for image processing, and W3C HTML Validation Service [29]for HTML validation.
After complaints that the above pictures in section 2.1 don't show any of the references I have used, I decided to add those two pictures. They show some of the documentation I had been using while writing this paper. It is probably something over 5'000 pages.
Following references were used when writing this paper: