VGA support: Difference between revisions
No edit summary |
No edit summary |
||
(72 intermediate revisions by 20 users not shown) | |||
Line 1: | Line 1: | ||
== VGA initialization in coreboot == | |||
Since coreboot v4 you can configure VGA initialization in Kconfig. For older versions of coreboot check the history of this page. | |||
First do: | |||
<source lang="bash"> | |||
$ make menuconfig | |||
</source> | |||
Then go | |||
Chipset ---> | |||
[*] Setup bridges on path to VGA adapter | |||
[*] Run VGA option ROMs | |||
Option ROM execution type (Native mode) ---> | |||
Alternatively you can choose the "Secure mode" to run the VGA option rom in a contained environment. | |||
If you have no on-board graphics, you are done configuring coreboot at this point. You may exit configuration, and run make to get your VGA enabled coreboot image. | |||
get | |||
=== On-board Video Devices === | |||
If you run coreboot on a system with on-board graphics, you have to embed a VGA on the top level, enter the file name of your option rom and the PCI ID of the associated graphics device in the form <vendor_id>,<device_id>: | |||
VGA BIOS ---> | |||
[*] Add a VGA BIOS image | |||
(oprom-0.rom) VGA BIOS path and filename | |||
(8086,27a2) VGA device PCI IDs | |||
That's it, exit configuration, and run make to get your VGA enabled coreboot image. | |||
== How to retrieve a good video bios == | |||
There are various ways to get hold of the video bios blob and not all work equally good for all boards (rather the opposite). | |||
The best way is to extract it from the vendor firmware. | |||
In the case of a traditional x86 BIOS this is rather easy and very reliable. | |||
On UEFI systems there does not seem to be a unified way of success but sometimes the steps below work. | |||
Another category is downloading the blobs directly. | |||
Some vendors offer them in graphics driver packages etc. and you might even find them on enthusiasts website dedicated to firmware modding etc. | |||
The most delicate ways are by dumping the blob from a running system. | |||
This might sound like the most reasonable way but the image present after boot might not be the same as it is (to be) stored in flash (e.g. if it is self modifying). | |||
However, in some cases this is the only way and then it is quite comfortable. | |||
=== RECOMMENDED: Extracting from your vendor bios image === | |||
The recommended method is to take your mainboard vendor's BIOS image (if there is one) and extract the VGA BIOS using a tool called [[bios_extract]]. | |||
$ git clone http://review.coreboot.org/p/bios_extract.git | |||
This is the most reliable way: | |||
* You are guaranteed to get an image that fits to your onboard VGA | |||
* Even if your VGA BIOS uses self-modifying code you get a correct image | |||
Decompress your rom image with: | |||
$ ./bios_extract hdmag217.rom | |||
If bios_decode fails with a message like | |||
Using file "hdmag217.rom" (513kB) | |||
Found Phoenix BIOS "Phoenix ServerBIOS 3 Release 6.0 " | |||
Version "DEVEL4E0", created on 03/20/06 at 14:37:39. | |||
Error: Invalid module signature at 0x80581 | |||
then you have to cut the flash chip description off the image. In this case the BIOS image is 512KB, so you do | |||
$ dd if=hdmag217.rom of=hdma.rom bs=512k count=1 | |||
1+0 records in | |||
1+0 records out | |||
524288 bytes transferred in 0.000883 secs (593688784 bytes/sec) | |||
You will get an output similar to this: | |||
Using file "hdma.rom" (512kB) | |||
Found Phoenix BIOS "Phoenix ServerBIOS 3 Release 6.0 " | |||
Version "DEVEL4E0", created on 03/20/06 at 14:37:39. | |||
0x715FC ( 27134 bytes) -> romexec_0.rom | |||
0x6E1CB ( 13338 bytes) -> strings_0.rom (29401 bytes) | |||
0x6D65D ( 2899 bytes) -> display_0.rom (4128 bytes) | |||
0x6B62E ( 8208 bytes) -> update_0.rom | |||
0x6B1E3 ( 1072 bytes) -> decompcode_0.rom [0x5000:0xB6D0] | |||
0x6564F ( 23421 bytes) -> oprom_0.rom (36864 bytes) | |||
0x65608 ( 44 bytes) -> tcpa_H_0.rom (32 bytes) | |||
0x65592 ( 91 bytes) -> acpi_1.rom (116 bytes) | |||
0x65519 ( 94 bytes) -> acpi_2.rom (244 bytes) | |||
0x654ED ( 13 bytes) -> tcpa_*_0.rom | |||
0x64D4F ( 1927 bytes) -> bioscode_0.rom (31382 bytes) [0xF000:0x856A] | |||
0x60020 ( 19728 bytes) -> romexec_1.rom | |||
0x570D9 ( 36656 bytes) -> oprom_1.rom (61440 bytes) | |||
0x4DB9D ( 38177 bytes) -> oprom_2.rom (63488 bytes) | |||
0x46493 ( 30447 bytes) -> oprom_3.rom (65536 bytes) | |||
0x41DAB ( 18125 bytes) -> logo_0.rom (310162 bytes) | |||
0x39CA5 ( 25439 bytes) -> oprom_4.rom (51200 bytes) | |||
0x36005 ( 15493 bytes) -> setup_0.rom (37682 bytes) | |||
0x325D7 ( 14867 bytes) -> template_0.rom (37728 bytes) | |||
0x2FA36 ( 11142 bytes) -> miser_0.rom (16208 bytes) | |||
0x2E63C ( 5087 bytes) -> tcpa_Q_0.rom (16096 bytes) | |||
0x2D7C3 ( 3678 bytes) -> acpi_0.rom (10464 bytes) | |||
0x1FA2A ( 41023 bytes) -> bioscode_1.rom (56080 bytes) [0xE000:0x40F0] | |||
0x14FE0 ( 43567 bytes) -> bioscode_2.rom (62416 bytes) [0x6000:0xCC30] | |||
0x0EB4C ( 25721 bytes) -> bioscode_3.rom (36976 bytes) [0x6000:0x3BC0] | |||
0x0D0A0 ( 6801 bytes) -> bioscode_4.rom (31856 bytes) [0x5000:0xBF50] | |||
Now you can check the option roms (oprom_?.rom) with the tool romheaders which is part of the [http://www.openfirmware.info/FCODE_suite FCode Suite] (in debian-based distros, you can get it by installing the '''fcode-utils''' package): | |||
$ romheaders oprom_0.rom | |||
Image 1: | |||
PCI Expansion ROM Header: | |||
Signature: 0x55aa (Ok) | |||
CPU unique data: 0x48 0xeb 0x7b 0x01 0x76 0x00 0x00 0x00 | |||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 | |||
Pointer to PCI Data Structure: 0x017c | |||
PCI Data Structure: | |||
Signature: 0x50434952 'PCIR' (Ok) | |||
Vendor ID: 0x1002 | |||
Device ID: 0x4752 | |||
Vital Product Data: 0x0000 | |||
PCI Data Structure Length: 0x0018 (24 bytes) | |||
PCI Data Structure Revision: 0x00 | |||
Class Code: 0x030000 (VGA Display controller) | |||
Image Length: 0x0048 blocks (36864 bytes) | |||
Revision Level of Code/Data: 0x0421 | |||
Code Type: 0x00 (Intel x86) | |||
Last-Image Flag: 0x80 (last image in rom) | |||
Reserved: 0x0000 | |||
Platform specific data for x86 compliant option rom: | |||
Initialization Size: 0x48 (36864 bytes) | |||
Entry point for INIT function: 0x80 | |||
Congratulations, that's your option rom (compare PCI IDs and Class Code to find it among the option roms). | |||
=== UEFI Method === | |||
UEFI's format is more structured than that of a traditional flat binary BIOS. In order to extract the VBIOS Option ROM you will need | |||
to parse out the UEFI Volumes and sub-Volumes out the UEFI filesystem using the [https://github.com/LongSoft/UEFITool UEFITool]. | |||
* Look for the " CSMCORE " DXE Driver ? usually having the hash 'a062cf1f-8473-4aa3-8793-600bc4ffe9a8'? | |||
* Search for text "VGA Compatible BIOS" ('''uncheck unicode''') | |||
* Search for text "PCIR" ('''uncheck unicode''') | |||
Double clicking the matching line in the "Messages" section should select the appropriate RAW section. From the menu select "Action -> Section -> Extract Body...". | |||
=== Downloading === | |||
There are sites that have video BIOS ROMs on their website (with all implications of retrieving a binary from an unknown source and executing it...). | |||
For Intel onboard graphics you can download the vbios (vga bios) from Intel's download section. The vbios is included with some versions of the graphics driver. The summary will say something like "NOTE:These materials are intended for use by developers.Includes VBIOS". The actual vbios file is the *.dat file included with the graphics driver. | |||
=== Retrieval via Linux kernel === | |||
Some Linux drivers (e.g. <tt>radeon</tt> for AMD) make option ROMs like the video blob available to user space via sysfs. | |||
To use that to get the blob you need to enable it first. | |||
To that end you need to determine the path within <tt>/sys</tt> corresponding to your graphics chip. | |||
It looks like this: <tt>/sys/devices/pci<domain>:<bus>/<domain>:<bus>:<slot>.<function>/rom</tt>. | |||
You can get the respective information with <tt>lspci</tt>, for example: | |||
# lspci -tv | |||
-[0000:00]-+-00.0 Advanced Micro Devices, Inc. [AMD] Family 16h Processor Root Complex | |||
+-01.0 Advanced Micro Devices, Inc. [AMD/ATI] Kabini [Radeon HD 8210] | |||
... | |||
Here the the needed bits (for the ROM of the Kabini device) are: | |||
* PCI domain: (almost always) 0000 | |||
* PCI bus: (also very commonly) 00 | |||
* PCI slot: 01 (logical slot; different from any physical slots) | |||
* PCI function: 0 (a PCI device might have multiple functions... shouldn't matter here) | |||
To enable reading of the ROM you need to write 1 to the respective file, e.g.: | |||
echo 1 > /sys/devices/pci0000:00/0000:00:01.0/rom | |||
The same file should then contain the video blob and it should be possible to simply copy it, e.g.: | |||
cp /sys/devices/pci0000:00/0000:00:01.0/rom vgabios.bin | |||
<tt>romheaders</tt> should print reasonable output for this file. | |||
Intel Graphics supports this method. See [https://01.org/linuxgraphics/documentation/development/how-dump-video-bios How to dump Video BIOS]. | |||
=== Extraction from mapped memory (if everything else fails) === | |||
However you might be able to retrieve your on-board video BIOS with Linux as well. | |||
* Boot up a machine with a commercial BIOS (not coreboot) with the video card you wish to work under coreboot. | |||
* You can see where and how much your card's bios is using by doing a | |||
<source lang="bash">grep 'Video ROM' /proc/iomem</source> | |||
* From the command line enter:<br /><source lang="bash">dd if=/dev/mem of=vgabios.bin bs=1k count=64 skip=768</source> This assumes you card's BIOS is cached at 0xc0000, and is 64K long. | |||
<br /><source lang="bash">dd if=/dev/mem of=video.bios.bin.4 bs=65536 count=1 skip=12</source> | |||
This works for many of the VIA Epia boards.<br> | |||
Alternatively you can automatically generate it using this nice script from Peter Stuge:<br /> | |||
<source lang="bash"> | |||
cat /proc/iomem | grep 'Video ROM' | (read m; m=${m/ :*}; s=${m/-*}; e=${m/*-}; \ | |||
dd if=/dev/mem of=vgabios.bin bs=1c skip=$[0x$s] count=$[$[0x$e]-$[0x$s]+1]) | |||
</source> | |||
* You (might) have a video BIOS image now. Check it at least with romheaders (as described above). | |||
== YABEL == | |||
* Yabel can be used to trace the VGA option rom. | |||
* However its ability to prevent the option rom to do nasty things is limited: Often the GPU offers a way (e.g. trough an IO BAR) to access arbitrary locations in RAM, so limiting access of the GPU's PCI device to the option rom wouldn't contain it completely. | |||
See [[Coreboot Options]] for more information about the option. | |||
[[Category:Blobs]] |
Latest revision as of 14:47, 12 April 2016
VGA initialization in coreboot
Since coreboot v4 you can configure VGA initialization in Kconfig. For older versions of coreboot check the history of this page.
First do:
<source lang="bash">
$ make menuconfig
</source>
Then go
Chipset ---> [*] Setup bridges on path to VGA adapter [*] Run VGA option ROMs Option ROM execution type (Native mode) --->
Alternatively you can choose the "Secure mode" to run the VGA option rom in a contained environment.
If you have no on-board graphics, you are done configuring coreboot at this point. You may exit configuration, and run make to get your VGA enabled coreboot image.
On-board Video Devices
If you run coreboot on a system with on-board graphics, you have to embed a VGA on the top level, enter the file name of your option rom and the PCI ID of the associated graphics device in the form <vendor_id>,<device_id>:
VGA BIOS ---> [*] Add a VGA BIOS image (oprom-0.rom) VGA BIOS path and filename (8086,27a2) VGA device PCI IDs
That's it, exit configuration, and run make to get your VGA enabled coreboot image.
How to retrieve a good video bios
There are various ways to get hold of the video bios blob and not all work equally good for all boards (rather the opposite).
The best way is to extract it from the vendor firmware. In the case of a traditional x86 BIOS this is rather easy and very reliable. On UEFI systems there does not seem to be a unified way of success but sometimes the steps below work.
Another category is downloading the blobs directly. Some vendors offer them in graphics driver packages etc. and you might even find them on enthusiasts website dedicated to firmware modding etc.
The most delicate ways are by dumping the blob from a running system. This might sound like the most reasonable way but the image present after boot might not be the same as it is (to be) stored in flash (e.g. if it is self modifying). However, in some cases this is the only way and then it is quite comfortable.
RECOMMENDED: Extracting from your vendor bios image
The recommended method is to take your mainboard vendor's BIOS image (if there is one) and extract the VGA BIOS using a tool called bios_extract.
$ git clone http://review.coreboot.org/p/bios_extract.git
This is the most reliable way:
- You are guaranteed to get an image that fits to your onboard VGA
- Even if your VGA BIOS uses self-modifying code you get a correct image
Decompress your rom image with:
$ ./bios_extract hdmag217.rom
If bios_decode fails with a message like
Using file "hdmag217.rom" (513kB) Found Phoenix BIOS "Phoenix ServerBIOS 3 Release 6.0 " Version "DEVEL4E0", created on 03/20/06 at 14:37:39. Error: Invalid module signature at 0x80581
then you have to cut the flash chip description off the image. In this case the BIOS image is 512KB, so you do
$ dd if=hdmag217.rom of=hdma.rom bs=512k count=1 1+0 records in 1+0 records out 524288 bytes transferred in 0.000883 secs (593688784 bytes/sec)
You will get an output similar to this:
Using file "hdma.rom" (512kB) Found Phoenix BIOS "Phoenix ServerBIOS 3 Release 6.0 " Version "DEVEL4E0", created on 03/20/06 at 14:37:39. 0x715FC ( 27134 bytes) -> romexec_0.rom 0x6E1CB ( 13338 bytes) -> strings_0.rom (29401 bytes) 0x6D65D ( 2899 bytes) -> display_0.rom (4128 bytes) 0x6B62E ( 8208 bytes) -> update_0.rom 0x6B1E3 ( 1072 bytes) -> decompcode_0.rom [0x5000:0xB6D0] 0x6564F ( 23421 bytes) -> oprom_0.rom (36864 bytes) 0x65608 ( 44 bytes) -> tcpa_H_0.rom (32 bytes) 0x65592 ( 91 bytes) -> acpi_1.rom (116 bytes) 0x65519 ( 94 bytes) -> acpi_2.rom (244 bytes) 0x654ED ( 13 bytes) -> tcpa_*_0.rom 0x64D4F ( 1927 bytes) -> bioscode_0.rom (31382 bytes) [0xF000:0x856A] 0x60020 ( 19728 bytes) -> romexec_1.rom 0x570D9 ( 36656 bytes) -> oprom_1.rom (61440 bytes) 0x4DB9D ( 38177 bytes) -> oprom_2.rom (63488 bytes) 0x46493 ( 30447 bytes) -> oprom_3.rom (65536 bytes) 0x41DAB ( 18125 bytes) -> logo_0.rom (310162 bytes) 0x39CA5 ( 25439 bytes) -> oprom_4.rom (51200 bytes) 0x36005 ( 15493 bytes) -> setup_0.rom (37682 bytes) 0x325D7 ( 14867 bytes) -> template_0.rom (37728 bytes) 0x2FA36 ( 11142 bytes) -> miser_0.rom (16208 bytes) 0x2E63C ( 5087 bytes) -> tcpa_Q_0.rom (16096 bytes) 0x2D7C3 ( 3678 bytes) -> acpi_0.rom (10464 bytes) 0x1FA2A ( 41023 bytes) -> bioscode_1.rom (56080 bytes) [0xE000:0x40F0] 0x14FE0 ( 43567 bytes) -> bioscode_2.rom (62416 bytes) [0x6000:0xCC30] 0x0EB4C ( 25721 bytes) -> bioscode_3.rom (36976 bytes) [0x6000:0x3BC0] 0x0D0A0 ( 6801 bytes) -> bioscode_4.rom (31856 bytes) [0x5000:0xBF50]
Now you can check the option roms (oprom_?.rom) with the tool romheaders which is part of the FCode Suite (in debian-based distros, you can get it by installing the fcode-utils package):
$ romheaders oprom_0.rom Image 1: PCI Expansion ROM Header: Signature: 0x55aa (Ok) CPU unique data: 0x48 0xeb 0x7b 0x01 0x76 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 Pointer to PCI Data Structure: 0x017c PCI Data Structure: Signature: 0x50434952 'PCIR' (Ok) Vendor ID: 0x1002 Device ID: 0x4752 Vital Product Data: 0x0000 PCI Data Structure Length: 0x0018 (24 bytes) PCI Data Structure Revision: 0x00 Class Code: 0x030000 (VGA Display controller) Image Length: 0x0048 blocks (36864 bytes) Revision Level of Code/Data: 0x0421 Code Type: 0x00 (Intel x86) Last-Image Flag: 0x80 (last image in rom) Reserved: 0x0000 Platform specific data for x86 compliant option rom: Initialization Size: 0x48 (36864 bytes) Entry point for INIT function: 0x80
Congratulations, that's your option rom (compare PCI IDs and Class Code to find it among the option roms).
UEFI Method
UEFI's format is more structured than that of a traditional flat binary BIOS. In order to extract the VBIOS Option ROM you will need to parse out the UEFI Volumes and sub-Volumes out the UEFI filesystem using the UEFITool.
- Look for the " CSMCORE " DXE Driver ? usually having the hash 'a062cf1f-8473-4aa3-8793-600bc4ffe9a8'?
- Search for text "VGA Compatible BIOS" (uncheck unicode)
- Search for text "PCIR" (uncheck unicode)
Double clicking the matching line in the "Messages" section should select the appropriate RAW section. From the menu select "Action -> Section -> Extract Body...".
Downloading
There are sites that have video BIOS ROMs on their website (with all implications of retrieving a binary from an unknown source and executing it...).
For Intel onboard graphics you can download the vbios (vga bios) from Intel's download section. The vbios is included with some versions of the graphics driver. The summary will say something like "NOTE:These materials are intended for use by developers.Includes VBIOS". The actual vbios file is the *.dat file included with the graphics driver.
Retrieval via Linux kernel
Some Linux drivers (e.g. radeon for AMD) make option ROMs like the video blob available to user space via sysfs. To use that to get the blob you need to enable it first. To that end you need to determine the path within /sys corresponding to your graphics chip. It looks like this: /sys/devices/pci<domain>:<bus>/<domain>:<bus>:<slot>.<function>/rom.
You can get the respective information with lspci, for example:
# lspci -tv -[0000:00]-+-00.0 Advanced Micro Devices, Inc. [AMD] Family 16h Processor Root Complex +-01.0 Advanced Micro Devices, Inc. [AMD/ATI] Kabini [Radeon HD 8210] ...
Here the the needed bits (for the ROM of the Kabini device) are:
- PCI domain: (almost always) 0000
- PCI bus: (also very commonly) 00
- PCI slot: 01 (logical slot; different from any physical slots)
- PCI function: 0 (a PCI device might have multiple functions... shouldn't matter here)
To enable reading of the ROM you need to write 1 to the respective file, e.g.:
echo 1 > /sys/devices/pci0000:00/0000:00:01.0/rom
The same file should then contain the video blob and it should be possible to simply copy it, e.g.:
cp /sys/devices/pci0000:00/0000:00:01.0/rom vgabios.bin
romheaders should print reasonable output for this file.
Intel Graphics supports this method. See How to dump Video BIOS.
Extraction from mapped memory (if everything else fails)
However you might be able to retrieve your on-board video BIOS with Linux as well.
- Boot up a machine with a commercial BIOS (not coreboot) with the video card you wish to work under coreboot.
- You can see where and how much your card's bios is using by doing a
<source lang="bash">grep 'Video ROM' /proc/iomem</source>
- From the command line enter:
<source lang="bash">dd if=/dev/mem of=vgabios.bin bs=1k count=64 skip=768</source> This assumes you card's BIOS is cached at 0xc0000, and is 64K long.
<source lang="bash">dd if=/dev/mem of=video.bios.bin.4 bs=65536 count=1 skip=12</source>
This works for many of the VIA Epia boards.
Alternatively you can automatically generate it using this nice script from Peter Stuge:
<source lang="bash">
cat /proc/iomem | grep 'Video ROM' | (read m; m=${m/ :*}; s=${m/-*}; e=${m/*-}; \
dd if=/dev/mem of=vgabios.bin bs=1c skip=$[0x$s] count=$[$[0x$e]-$[0x$s]+1])
</source>
- You (might) have a video BIOS image now. Check it at least with romheaders (as described above).
YABEL
- Yabel can be used to trace the VGA option rom.
- However its ability to prevent the option rom to do nasty things is limited: Often the GPU offers a way (e.g. trough an IO BAR) to access arbitrary locations in RAM, so limiting access of the GPU's PCI device to the option rom wouldn't contain it completely.
See Coreboot Options for more information about the option.