Compiling kernel IEGD 10.x module for any Linux distribution19 Feb 2010
Intel has put great effort to put complete open-source drivers into recent kernels for its devices. Only device that is clearly missing there is GMA500 (aka Poulsbo, aka US15 chipset, aka Atom Z5xx family). This is understood as it does relay on Imagination Technologies PowerVR core licensed out by Intel to produce GMA500, so most of the driver parts cannot go open-source as it would imply of violation of some agreement between ImgTec and Intel.
Fortunately Intel provides binary driver set called Intel® Embedded Graphics Driver (IEGD) supporting all embedded video chipsets, containing binary form of video driver libraries for latest Xorg, OpenGL and VA.
While most of the work you need to do is to have
IEGD_10_3_Linux.tgz file (in
case of IEGD 10.3) extracted onto the target box and to copy various
files in proper places (follow IEGD documentation). Yet there is one more
complicated thing extra – IEGD Kernel Module (IKM)
iegd_mod.ko that has to
be compiled out of the source shipped with IEGD.
Linux Kernel module
IEGD documentation clearly states that only few distributions are supported by this driver, and those are i.e. Fedora 8 & 10, some older Ubuntu 8.x and finally Moblin. But what about others, such as Debian, newer Ubuntu. You think you are unlucky running other distro? You shall understand word “supported” here as “tested”.
Reading the documentation, in all cases your are supposed to enter
of extracted drivers and launch
install.sh script. This script shall compile
and install without any hassle IKM on “supported” distributions. Surprisingly
trying that on your distribution even it is not supported may work too! With
one important exception it produces bogus driver that will crash your kernel.
Finding the proper way for your distribution
This recipe will save some few hours up to few days of struggling with fancy errors trying to compile and run the IKM module on your system :)
Investigating the driver and
install.sh first thing to notice is that it checks
you Kernel version, it also takes (false) assumption that your are running one
of the “supported” distros, so i.e 2.6.27 may mean Fedora version of the 2.6.27
Kernel not any 2.6.27 kernel.
Linux distributions have this fancy characteristic that they usually come with heavily patched kernel, so when you take 2.6.xx driver module from one distro and try to run it on the same version kernel on the other distro it will likely crash your kernel. Why? Incompatible ABI.
What Intel (Tungsten?) did in IKM is prepared IKM/val subfolder with headers
extracted from several kernel sources of “supported” distributions. And what
install.sh does, it tries to guess which one of DRM and AGP kernel module
headers placed in that subfolder are OK for your Kernel.
In case you are running on the “unsupported” distribution the answer in 95%
cases is NONE! Even you will be able to compile the
Makefile produced by
install.sh the module will crash you kernel as soon
you will try to use it. Since your kernel has incompatible ABI (different
structures) with the ABI provided inside IKM/val subfolder.
Preparing for compilation of IKM for your own kernel
If you are running “unsupported” distribution you should avoid then using
IKM/val subfolder. The right way is to take AGP and DRM headers
out of your running kernel sources (you don’t have to compile the whole kernel
So go to
IEGD_10_3_Linux folder and launch:
sudo apt-get install linux-headers-x.y.zz apt-get source linux-image-x.y.zz
x.y.zz is your running kernel version. (Use your own distro command to
grab kernel source if you don’t run on Debian or Ubuntu)
This will install kernel headers and scripts to build kernel modules and also
linux-x.y.zz folder containing source code of your running Kernel.
The whole trick if to place (replace) Makefile in IKM folder as below:
KERNELVER ?= $(shell uname -r) KERNELDIR ?= /lib/modules/$(KERNELVER)/build INSTALLDIR ?= /lib/modules/$(KERNELVER)/kernel/drivers/char/agp PWD ?= $(realpath .) EXTRA_CFLAGS += -I$(PWD)/include EXTRA_CFLAGS += -I$(PWD)/../linux-$(KERNELVER)/drivers/char/agp EXTRA_CFLAGS += -I/lib/modules/$(KERNELVER)/build/include/drm all: clean modules modules: @echo $(PWD) @$(MAKE) -C $(KERNELDIR) M=$(PWD) modules install: install -o root -g root -m 755 -d $(INSTALLDIR) install -o root -g root -m 744 iegd_mod.ko $(INSTALLDIR) /sbin/depmod -a uninstall: rm -rf $(INSTALLDIR)/iegd_mod.ko /sbin/depmod -a clean: @rm -f *.o iegd*.ko iegd*.mod.c iegd*.o agp/*.o drm/*.o Module.symvers @rm -fr .intel* .tmp* .*.cmd agp/.*.cmd drm/.*.cmd obj-m := iegd_mod.o iegd_mod-objs := agp/pci.o agp/global.o agp/drv_alm.o agp/drv_nap.o \ agp/drv_plb.o agp/drv_cmn.o agp/drv_gn4.o drm/iegd_drv.o \ drm/iegd_interface.o drm/iegd_interface_265.o \ drm/iegd_interface_2611.o drm/iegd_interface_2615.o \ drm/iegd_interface_2624.o drm/psb_irq.o
You don’t need to launch
install.sh at all. Just paste the file as above.
As you see now, this
Makefile references to
../linux-$(KERNELVER) for your
running Kernel source AGP & DRM headers. Yet however you may still need to do
few tweaks in your
Makefile, see notes below:
Note (1) In case you are running older kernel,
/lib/modules/$(KERNELVER)/build/include/drm may not exist, then
$(PWD)/../linux-$(KERNELVER)/drivers/char/drm should be right path to put in
Note (2) The Kernel source code folder you downloaded (i.e. via apt-get
source) may not actually match exactly
linux-$(KERNELVER), so you may change
that EXTRA_CFLAGS setting manually:
In case of Ubuntu
uname -r is
2.6.31-19-generic while the extracted source
folder name has no
-generic suffix and it is just
linux-2.6.31-19. In case
uname -r is
2.6.26-21 while the extracted source folder name is
linux-2.6-2.6.26-21. Weird huh? Final fixes before compilation
There is a file still missing if you try now to
make. It is file that exists
IKM/val/agp but does not exist in your
$(PWD)/../linux-$(KERNELVER)/drivers/char/agp. It is called
Wonder why the heck it is NOT in
IKM/include!? This is a little lack of
consequence from Intel here.
Anyway just copy interface_abs.h into IKM/include out of
IKM/val/agp/agpm0vmob2 if you are running on >= 2.6.30 Kernel or from
IKM/val/agp/agpm0v103 otherwise. The only difference between
agpm0v103 is one macro definition.
Finally we need two little extra fixes:
Trying to compile on Debian Lenny we will get many nasty errors from kernel headers for
igd_abs.hinclusion in this source file little down fixes the issue. Edit
#include "iegd.h" -#include "igd_abs.h" #include "drmP.h" #include "drm.h" +#include "igd_abs.h" #include "iegd_drm.h" #include "iegd_drv.h" #include "psb_intregs.h"
IKM/drm/iegd_drv.ctries to include
linux/config.hat the very beginning of the file. This is not actually necessary, and anyway does not exist, so you may comment that out:
-#include <linux/config.h> +/* #include <linux/config.h> */
Compiling at last
Now you are ready to so
sudo make install. This time
should be ABI compatible with your kernel.
I have tested this method on Debian 5.0 Lenny and Ubuntu 9.10 Karmic Koala.
To ensure everything works fine after driver installation try:
sudo modprobe iegd_mod
And try to go into
IKM/agp and compile and run
gcc -o agp_test agp_test.c sudo ./agp_test
Next try the same with
IKM/drm compiling and running
If those two test won’t fail and won’t blow your kernel it means you have fully working IEGD module on your own Linux distro.
Notes for users of old psb-modules or psb-kernel-source Ubuntu package
psb-kernel-source Ubuntu packages install their own
drm.ko module at
/lib/modules/`uname -r` -type f -name 'drm*' you should have
In case if you find other
drm.ko, probably in
updates/char/drm delete it.
That one came from
psb-kernel-source and is causing you a trouble. You may
ensure you got only valid
drm.ko reinstalling your kernel image with:
apt-get install --reinstall linux-image-`uname -r`
Notes for curious
The difference of
Makefile of mine and
Makefile produced of
KERNELVER ?= $(shell uname -r) KERNELDIR ?= /lib/modules/$(KERNELVER)/build INSTALLDIR ?= /lib/modules/$(KERNELVER)/kernel/drivers/char/agp PWD ?= $(realpath .) EXTRA_CFLAGS += -I$(PWD)/include EXTRA_CFLAGS += -I$(PWD)/../linux-$(KERNELVER)/drivers/char/agp EXTRA_CFLAGS += -I/lib/modules/$(KERNELVER)/build/include/drm
If you try to run
EXTRA_CFLAGS will include two of
folders which contain some Kernel source extracted header definitions that are
likely not compatible with your Kernel.
I use also
PWD ?= $(realpath .) here instead of
PWD ?= $(shell pwd) because
with some Linux headers versions
$(shell pwd) resolves to
not the path where IKM sources are.
Notes for Intel
It would be nice for next IEGD release if IKM source tree would be made for readable and clear:
IKM/valshould be renamed to IKM/kernel-headers (what the heck “val” means here ?!) and this should be noted somewhere in docs that files here are NOT made by Intel but extracted of “supported” Linux distributions Kernel sources
interface_abs.hshould moved away from IKM/val (IKM/kernel-headers) to avoid confusion (with point 1) and placed into IKM/includes (and there should be
#ifdeffor this one macro that makes it different for across 2.6.30)
IKM/drm/iegd_interface.cshould be fixed as described above (moving
iegd_abs.hinclusion little bit down).
<include/config.h>is not necessary, may be removed.
install.shshould contain case when running on “unsupported” distribution.
So it shall make SURE if running on “supported” distributions and then and only then use files from IKM/kernel-headers, OTHERWISE ask for a path for your own Linux distribution Kernel source’s to find a path for your own
include/drm) i.e. by showing:
Your Linux distribution and Kernel version was untested, however you may try to compile and run driver on your own risk. Please provide your running kernel sources extracted i.e. on Debian or Ubuntu using apt-get source linux-image-2.6-686: [path to your kernel]:
Fell free to post your comments and problems with method presented here below using comment form!
Posted in Linux