Using intel graphics

Besides `$vgasize', the `$monitor' environment variable is used to specify how to configure the graphics card. When using vga(8) directly, it is needed if no -m parameter is given.

On the 9front and ANTS isos, `$monitor' is set to `ask' by default; during boot, /rc/bin/screenrc then asks the user to specify it.

Intel graphics (igfx) cards are generally well supported on 9front, and can be used in one of two ways: with VESA or the native igfx driver.

It is generally preferable to just use VESA, but this may not always be possible.



If the monitor type is set to `vesa', either in `$monitor', or with the -m flag, vga(8) will attempt to configure the requested mode using the card's VESA BIOS. Several requirements must be satisfied for this to work:

See vga(8) for usage. Use the -p flag to list available modes.

If configuring the selected mode on the selected display does not work, there are two options:


The igfx driver currently supports the following type of cards and connections:

Both the type of card and the type of connection to the display must be supported for modesetting to work.

In addition, mode timings must be provided, either in vgadb(6) or in EDID information from the display (see below).

Lastly, the driver must recognize the card, and vga(8) must know to select igfx as its driver. The former is achieved by recording its did in vga(8)'s igfx controller code (/sys/src/cmd/aux/vga/igfx.c). The latter is done by recording its did in the igfx `ctlr' entry in vgadb(6). Dids can be obtained using pci(8).

In the simplest case, a supported card is connected to a display, internal or not, using a supported connection. Automatic configuration is then sufficient, and nothing needs to be edited.

If the requested mode and timings cannot be obtained with automatic configuration, a vgadb(6) entry must be used.


This is done using monitor=auto as such:

	; aux/vga -m auto -l $vgasize

When the monitor is set to `auto', the driver attempts to probe any connected displays for EDID, and matches any mode information found against the specified resolution. If multiple entries match (for instance, for different refresh rates, or on different displays), the first one is always used.

To check what EDID information is found, use vga(8)'s -p flag. The total lack of mode information for a given display indicates a buggy monitor, an unsupported connection or a bug in the driver.

Caveat: since the first match is always used, should the display specify multiple entries for the same mode with different refresh rates, the only way to choose a specific one is to use vgadb(6).


Read vgadb(6).

In this case, the monitor is set to something other than `vesa' or `auto'. Setting monitor=foo has vga(8) look for entries named foo= or aliases pointing to it in vgadb(6), specifying timings for the requested mode.

For example, given the settings:


Or the command line:

	; aux/vga -m x230 -l 1366x768x32

Vga(8) will look for an entry such as:


One only needs to add a new entry if automatic configuration does not work (or selects the wrong timings), and if no other entry for the same resolution exists.

The entries named include= as well as the aliases defined subsequently allow one to use `vga', `multisync' and others interchangeably for a number of "standard" resolutions.

It is often necessary to explicitely select a port when using vgadb(6), since the default is rarely correct, especially with laptops (see below).


Igfx cards have several ports which can be configured to drive a display. They can be configured for a given type of connection. By convention, the driver numbers them as follows:

The port is VGA (1) by default.

If using automatic configuration, a port is selected automatically, and, provided only one display has an EDID entry for the requested mode, nothing more is needed.

Otherwise, a port is specified manually in a vgadb(6) entry. Igfx does not recognize the ',#N' syntax used with VESA (see vga(8)). Instead, special attributes are used:

LVDS should be selected for laptops up until ivy bridge. From haswell on, LVDS is superceded by eDP, and display= must be used instead.


The driver is split in two parts:

In case a device's did is missing from the driver, but is from an allegedly supported generation, it should be sufficient to simply add it to both files, as well as in vgadb(6).

If the card's generation is not officially supported, but is close to one that is (example: iron lake and sandy bridge), it might be sufficient to add the card as one from the latter generation.

Modifying /sys/src/9/pc/vgaigfx.c is not strictly necessary, since it only implements the hardware cursor, and is inactive if the card is uninitialized. In case the hardware cursor implementation for the given card is buggy, the hardware cursor may be disabled manually (see vga(3)), or by moving its controller entry in vgadb(6) to one that does not set the hwgc= attribute.


In case a supported card does not work with a display reported to work on other operating systems, the best course of action is to debug the issues yourself, since the same hardware will probably not be available to others.

The reference documentation for igfx cards is the collection of Programmer's Reference Manuals (prm), available at

If the card works with VESA, but not with igfx, you can compare both methods by dumping its registers.

The easiest way is to use vga(8)'s -p option, which, when monitor is not set to `vesa', dumps the card's state. Set monitor=vesa during boot, and once the card is configured, call:

	; aux/vga -pm auto -l $vgasize >/path/to/somefile >[2=1]

For extremely verbose output, add the -V and -i flags.

This will output the state before and after igfx configures the card. The only caveat is that the values are those of soft registers employed by vga(8) (see the code). If you suspect that these do not reflect the truth, you may rerun vga(8) without the -l flag to get a new dump after re-snarfing the registers.

Another option is to use cinap's igdump scripts, which use io(1) to fetch the values of a list of offsets corresponding to registers.

cinap's igdump with values for ivy bridge

igdump with values for haswell, sandybridge and gm965

To use these, you need to:

Register names and offsets are listed in the prm's. If there are no mmios.txt provided for your generation of card, you'll have to build your own.

To find out which addresses to point io(1) to, trace what realemu(8) is doing with the -p flag (warning: flood). For example:

	; @{rfork n; aux/realemu -p; aux/vga -m vesa -p} >/dev/null |[2] sed 10q

The output will look like:

	rport 03d4 18
	rport 03d6 ff
	rport 03d0 ff
	rport 03ce 08
	rport 03d2 ff
	rport 03c4 00
	rport 03c7 00
	rport 03c8 40
	wport 1800 00002020
	rport 1804 bff80001

Printed are the address, then the value. Ignore addresses figured in ports.txt, and those accessed as byte values. In this case, the values needed are `0x1800' for writes, and `0x1804' for reads.

Once all is prepared, run:

	; dump.rc | pretty.rc >/path/to/somefile

Note: this requires that vga(8) has attached a memory segment with the igfx card's pci memory, meaning it must have been run at least once with monitor set to something other than `vesa'.

Note: should you use igdump to fetch the state before using igfx, do not use the -l flag when invoking vga(8).

You now have all available information on hand, and no more excuses to refuse debugging this yourself. The last piece of the puzzle is just /sys/src/cmd/aux/vga/igfx.c which, with the documentation opened, is simple to understand.

As a last recourse, you may complain on the 9front mailing lists, on IRC, or on the grid chat. Keep in mind however that the only way to allow someone else to debug the drivers for you is by providing a lot of information and conducting many tests -- please try to debug your issues yourself first.

When writing a bug report, please add the following information:


Screen blanking with VESA is buggy for some of the more recent generations of cards like haswell, and may cause screen unblanking to fail. In this case, blanking should be disabled (see mouse(3), vga(3)).

Keep in mind that on machines with multiple graphics cards, only the first card (usually the igfx one) will be seen by vga(8).