ACPI DSDT in initrd
What is the ACPI DSDT in initrd patch?
This patch is intended for people who like to hack their DSDT and don't want to
recompile their kernel after every change.
To find out what a DSDT is, go to the ACPI page. The ACPI project integrates ACPI support into the linux kernel.
A custom DSDT (Differentiated System Description Table) is useful when your computer uses ACPI but problems occur due to broken implementation. Typically, your computer works but there are some troubles with the hardware detection or the power management. You can check that troubles come from errors in the DSDT by activating the ACPI debug option and reading the logs. This table is provided by the BIOS, therefore it might be a good idea to check for BIOS update on your vendor website before going any further. Errors are often caused by vendors testing their hardware only with Windows or because there is code which is executed only on a specific OS with a specific version and Linux hasn't been considered during the development. If you succefully use an modified DSDT table, I highly recommend you to email your DSDT to the computer/motherboard vendor for inclusion in the next BIOS upgrade (and more Linux awareness in the future products).
Warning: this new version only supports initrd of type initramfs.
To use the DSDT into the initrd you must apply one of the following patches:
|Kernel version||DSDT in initramfs patch|
|2.6.28 to 2.6.29||acpi-dsdt-initrd-v0.9c-2.6.28.patch|
|2.6.25 to 2.6.27||acpi-dsdt-initrd-v0.9c-2.6.26.patch|
|2.6.21 to 2.6.24||acpi-dsdt-initrd-v0.8.4-2.6.21.patch|
|2.6.18 to 2.6.19||acpi-dsdt-initrd-v0.8.2-2.6.18.patch|
|2.6.16 to 2.6.17||acpi-dsdt-initrd-v0.8.2-2.6.17.patch|
|2.6.14 to 2.6.15||acpi-dsdt-initrd-v0.8.1-2.6.15.patch|
SuSE, Mandriva and Ubuntu, as well as other distros, already include this patch in the default kernel, no need for re-compiling your kernel! However, be careful concerning which version of the patch your distro uses, some might still use version <= 0.7, in which case the manual insertion of the DSDT is described at the end of this webpage. In SuSE, have a look at /etc/sysconfig/kernel for more information (ACPI_DSDT=...) or see this Howto. In Mandriva, use mkinitrd with the flag --dsdt.
Configuring DSDT in initramfs support
First you need to patch your kernel:
cd /usr/src/linux patch -p1 < /tmp/acpi-dsdt-initrd-patch-v0.x-....patchIn kernel config enable the ramdisk (not as module!) and initrd (in Block Devices) and enable CONFIG_ACPI_CUSTOM_DSDT_INITRD at the ACPI options (General Setup|Power Management|ACPI Support|Read custom DSDT from initramfs). Recompile your kernel.
The second step consists in adding the DSDT to the initrd (note that since version 0.8, this step is different than before). The final file has to be of initramfs type and has to contain the DSDT as a file situated at the root and called DSDT.aml. If your mkinitrd or mkinitramfs doesn't support it, you can use this script to add the DSDT file to your initramfs and then use this command:
initrd-add-dsdt initrd.img my-dsdt.aml
If you use Lilo as bootloader, you need to execute it so it knows about your new version of initrd.
How do I check that my initrd is an initramfs?The easiest way is to use file:
file -z /boot/my-initrd.imgIt should return
ASCII cpio archive (SVR4 with no CRC) (gzip compressed data...)
How do I create an initrd of type initramfs?If your mkinitrd doesn't create the initrd by default in this format, it might be possible to force it with a flag. There is no standard way, it depends on the distribution, check the mkinitrd manpage. On Debian, you have to use the new program called mkinitramfs. In case your mkinitrd doesn't support at all initramfs, you might have more chance by using yaird.
I don't have any initrd, how can I override the DSDT?The simplest way is to start using an initrd! Tools like yaird are now fairly easy to use and if it does nothing else but contain the DSDT it should not cost much on the boot time.
Another way is to insert the DSDT right inside the kernel (you then don't need this patch). However, this requires to recompile the kernel each time you add or update the DSDT.
How do I know that this has worked, that the kernel is using my modified DSDT?There is a message early at boot which indicates if it has worked or if there was an error while reading the DSDT.aml file. You can read it by typing this command:
dmesg | grep "Looking for DSDT in initramfs"
Why isn't this patch in the official kernel?Then main reason is that the ACPI maintainer considers that 1) allowing the users to override this manufacturer-written code could lead to hardware damage (very unlikely, but some computers do provide the software complete control on the battery or on the fans) and that 2) if there is really a bug in the DSDT, it is the manufacturer's job to provide a fix (this has the advantage of improving Linux awareness to the hardware makers). You can refer to those threads of the LKML.
The good news is that nowadays mostly no new computer sold needs to have its DSDT fixed. So it this patch will hopefully be one day useless.
Update as of 2008-03-15: Several maintainers in the Linux kernel have started to reconsider their position on the feature. The patch as even made a brief appearance in some development versions of the kernel 2.6.25 (it has been reverted because deemed too likely to bring bugs, but a new approach, patch v0.9, is already available for next development cycle).
Bonus patchThomas Renninger has provided additional patches for more features. I decided not to include them because it would make the normal patch harder to maintain and I expect very few people find interest in them. Still, it might be valuable to some... This is a version of the patch for 2.6.17 with support for SSDT and tainting of the kernel when a modified table is in use (flag A).
Old version of ACPI DSDT inside initrd
The previous versions of the patch worked differently, although the technical approach was phylosophically inferior, it allowed any type of initrd to be used. Apply one of the following patches depending on your kernel version:
|Kernel version||DSDT in initrd patch|
|2.6.14 to 2.6.15 (by Eric Piel)||acpi-dsdt-initrd-v0.7e-2.6.14.patch|
|2.6.12 to 2.6.13 (by Eric Piel)||acpi-dsdt-initrd-v0.7d-2.6.12.patch|
|2.6.9 to 2.6.11 (by Eric Piel)||acpi-dsdt-initrd-patch-v0.7d-2.6.9.patch|
|2.6.5 to 2.6.8 (by Eric Piel)||acpi-dsdt-initrd-patch-v0.5-2.6.5-eric.patch|
|2.4.23 vanilla (by Markus Gaugusch)||acpi-dsdt-initrd-patch-v0.3-2.4.23.diff|
After compiling the kernel, prepare your initrd this way:
echo -n "INITRDDSDT123DSDT123" >> /boot/initrd # magic signature cat DSDT.aml >> /boot/initrdPlease note, that the -n option for the echo commands should not be used for the older patches (e.g. for 2.4.x).
If you don't use an initrd yet, the signature is not necessary. In this case, just copy the DSDT.aml file into /boot and pass it as initrd.
If necessary, update your boot loader (e.g. by calling lilo) and reboot. The initrd must not be passed as kernel parameter, but as "initrd=..."!
The message "Looking for DSDT in initrd ..." will tell you if the DSDT was found or not.
If you need to update your DSDT, generate a new initrd and perform the steps above. If you don't use an initrd yet (it's empty), then just delete the old one and perform the steps above.
Problems with initramfs (2.6 kernels)With version 0.7d and older, please also apply acpi-dsdt-initramfs-fix-2.6.10-cleanup.patch in case you use initramfs (version 0.7e already contains this patch). If you don't know what type of initrd you have, you can apply it, it can't hurt. Typically, you need this patch when this message appears at boot time:
kernel panic - not syncing: VFS: Unable to mount root fs on unknown block (0,0)Thanks go to Gabriel Mitica for reporting this bug and Robert Spanton for a fix to initramfs.