Booting Windows using coreboot

From coreboot
Jump to navigation Jump to search

The wiki is being retired!

Documentation is now handled by the same processes we use for code: Add something to the Documentation/ directory in the coreboot repo, and it will be rendered to Contributions welcome!

Creative Commons License
Creative Commons Attribution iconCreative Commons Share Alike icon
This file is licensed under the Creative Commons Attribution ShareAlike 3.0 License.
In short: you are free to share and make derivative works of the file under the conditions that you appropriately attribute it, and that you distribute it only under a license identical to this one.

Why Windows?

LinuxBIOS itself has many positive aspects that should be made widely available. In order to make LinuxBIOS a very strong alternative firmware for PC's we cannot afford not considering support for windows since it owns about 90% in the PC market.

Project Overview

This projects was accepted for the Google Summer Of Code 2007 and its main goal to figure out how to boot Windows Vista/XP/2003. There is not a chosen approach to achieve that. Having a dedicated LinuxBIOS loader is the most desired solution but since some success has been reported using ADLO, it has been chosen in this phase of understanding better the problem.

Instead of a real hardware, QEMU emulator will be used since it is easily available for anyone who wishes to contribute.

I intend to describe in a detailed all the steps taken up to now and some the problems faced. My first goal is to repeat the stages to boot windows 2000 described in the paper entitled Flexibility in ROM: A Stackable Open Source BIOS. After that, we will focus on windows XP and Vista that require a more complicated support.

Any suggestion is welcome, please use the LinuxBIOS mailing list or email Augusto Pedroza.


The following software packages are needed:

plus a working development environment (make, gcc, etc.). gcc verions 4.0.x and 4.1.x work fine except for QEMU, which requires gcc 3.x.

Installing Qemu

In order to build QEMU from source gcc 3.x. is required. If you use a different version of gcc, take a look at the following section.

Building gcc 3.x

$ wget
$ tar zxvf gcc-3.4.6.tar.gz
$ cd gcc-3.4.6/
$ ./configure --prefix=/opt/gcc34 
$ make bootstrap
$ make install (as root)

Building QEMU

Download QEMU source code (I used qemu-0.9.0.tar.gz) and extract it.

$ tar -xzvf qemu-0.9.0.tar.gz
$ cd qemu-0.9.0/

Configure and make QEMU (use the --cc option if your default gcc is newer than version 3.4):

If you need some bios debug messages from qemu add --extra-cflags="-DDEBUG_BIOS" to the configuration line below. 
Since LinuxBIOS already outputs debug messages without this option, turning it on will mess Qemu output error 
messages. It is useful for some situations though.
$ ./configure --cc=/opt/gcc34/bin/gcc --target-list=i386-softmmu && make
$ make install

The QEMU binary is stored in the i386-softmmu directory.

Creating an Appropriate Disk Image

Installing Windows

There are few options to create an image, I chose to use the qemu-img tool. Create an image no smaller than 1.2GB to avoid any kind of problems during windows installation. The qcow format is very appropriate because will only take up as much space as is really needed. Since I wanted to install a small version of linux, I created an image of 2GB.

$ qemu-img create -f qcow /path/to/win2k.cow 2000M

Insert the installation CD, and install Windows 2000 in the QEMU image:

$ qemu -hda /path/to/win2k.cow -boot d -cdrom /dev/cdrom -m 384 -localtime

You can test the image running the following:

$ qemu -hda /path/to/xp.cow  

Installing GRUB

I repeated the steps above to install a small version of linux so grub was installed together with the distro I chose. I will soon post a way of installing grub without the need of installing Linux.

Building ADLO payload

First, download LinuxBIOSv2 source code.

$ svn co svn:// 

Go to the ADLO directory:

$ cd LinuxBIOSv2/util/ADLO

Check the README file to see some information about installing as86 + patch in order to compile bochs' bios. You can also get a prepatched version of as86. I downloaded the newest version and patched it. After that just type make at ADLO's main directory. A file named payload will be generated.

Building LinuxBIOS

Now it is time to build linuxBIOS.

$ cd LinuxBIOSv2/targets/emulation/qemu-i386

You should edit the file, where it says payload put the path of the file generated by ADLO. It should look like this:

  • payload path/to/adlo/payload

Return to targets directory and execute:

$ ./buildtarget emulation/qemu-i386 

Go to targets/emulation/qemu-i386/qemu-i386 and execute:

$ make 

This creates the LinuxBIOS image (qemu-bios.rom). Copy this file to a specific folder and rename it to bios.bin.

Booting Windows

Before trying to run everything together, we should copy a file named vgabios-cirrus.bin to the same folder where the bios.bin file is. This file can be found in the qemu directory at qemu-0.9.0/pc-bios. Let's try to boot everything. Just execute this:

$ qemu -L path/to/bios.bin -hda win2k.cow -serial stdio

The -L option allows us to inform the path for BIOS, VGA BIOS and keymaps.

Unfortunately it hangs as soon as the progress bar finishes. I get the following errors due to interrupt calls from MBR code, in our case GRUB.

int13_harddisk: function 41, unmapped device for ELDL=81
int13_harddisk: function 08, unmapped device for ELDL=81
*** int 15h function AX=00C0, BX=0000 not yet supported!
*** int 15h function AX=5300, BX=0000 not yet supported!
int13 function 41 -> (with BX = 55AAh) is a check for the "Installation of the INT 13 
                     BIOS Extensions" in Memory.                                     
int13 function 08 -> Get Drive Parameters

I also notice a problem with the keyboard even one I set the keymaps in qemu with the -k option:

KBD: int09h_handler(): unknown scancode read: 0x72!
KBD: int09h_handler(): unknown scancode read: 0x75!
KBD: int09h_handler(): unknown scancode read: 0x74!

While doing few tests, I found out the errors mentioned above are not responsible for boot failure since QEMU plus its original bios (bochs bios) also outputs them while booting windows (to enable QEMU bios debug messages check building Qemu section above). Since QEMU is able to boot windows 2000 and windows XP I have been focusing on the bios it uses. Qemu uses a full bochs bios, which consists of some initialization code found in a file named rombios32.c and a set emulated DOS interrupts. LinuxBIOS/ADLO uses bochs bios partially, since all the initialization code is found in LinuxBIOS and ADLO. Now we have to find out what is misssing in LinuxBIOS/ADLO initialization.

These are some of my results. Now, I am trying to determine the specific point where windows 2000 hangs and appreciate any help. Hope we can boot windows 2000/XP/Vista very soon.