Overriding your DSDT
Some computers come with a broken DSDT. You can read more about this here. This document describes the Debian specific methods needed to override your DSDT on Debian.
WARNING: It is usually not recommended that you override your own DSDT. Overriding your DSDT with garbage can do physical harm to your computer. You have been warned!
Earlier versions of the kernel on Debian made it easy for you to override your DSDT, using the initrd patch. This meant you could just put your new DSDT in /etc/initramfs-tools/DSDT.aml, and regenerate your initrd by update-initramfs -u -k all, and the new DSDT would be used. However, I think the Debian devs thought this was a security risk, and have since dropped the initrd patch. This means, to override your DSDT, you have to really want it! You have to recompile the kernel.
Fortunately all you have to do is rebuild an official kernel, which is a lot easier than building from scratch.
Fixing your DSDT
Before you go about recompiling your kernel, you need to first fix your DSDT. This is documented here, so I only list the commands with brief explanations.
aptitude install iasl/unstable cat /sys/firmware/acpi/tables/DSDT > dsdt.dat # Get the systems DSDT iasl -d dsdt.dat # Disassemble it iasl -tc dsdt.dsl # Reassemble it
Now if the last command above gives you compilation errors or warnings, then you might need to override your DSDT. I'd suggest typing your error message, or parts of your error message into Google, and seeing if someone posted a fix on the forums. Here's the errors I had on my HP 2710p:
bash$ iasl -tc dsdt.dsl Intel ACPI Component Architecture ASL Optimizing Compiler version 20090521 [Jun 14 2009] Copyright (C) 2000 - 2009 Intel Corporation Supports ACPI Specification Revision 3.0a dsdt.dsl 8473: Return (Package (0x02) Warning 1099 - Statement is unreachable ^ dsdt.dsl 8590: Wait (\_SB.C1AD, 0x10) Warning 1104 - Possible operator timeout is ignored ^ ASL Input: dsdt.dsl - 16075 lines, 576782 bytes, 7697 keywords AML Output: dsdt.aml - 71673 bytes, 1198 named objects, 6499 executable opcodes Compilation complete. 0 Errors, 2 Warnings, 0 Remarks, 2528 Optimizations
I got lucky. There were only two warnings, and no errors. So I probably didn't have to fix the DSDT in the first place. But I decided to fix it anyway: The first warning was obvious to fix -- comment out the unreachable code. Typing the second error message into Google showed someone on the Ubuntu forums with a similar error, and a fix that worked for me: I just had to change the 0x10 to 0xffff to make the second warning go away.
Here's a diff -u showing the fixes:
--- dsdt.dsl 2009-12-28 23:12:50.000000000 -0600 +++ dsdt-fixed.dsl 2009-12-28 23:14:03.000000000 -0600 @@ -8470,11 +8470,11 @@ } Return (Local0) - Return (Package (0x02) - { - 0x04, - 0x00 - }) + // Return (Package (0x02) // Unreachable code + // { + // 0x04, + // 0x00 + // }) } Method (C2D3, 1, NotSerialized) @@ -8587,7 +8587,7 @@ Store (0x01, Index (DerefOf (Index (Local0, 0x02)), 0x01)) If (And (C05C, 0x40)) { - Wait (\_SB.C1AD, 0x10) + Wait (\_SB.C1AD, 0xffff) // Changed 0x10 to 0xffff to remove error message. See http://ubuntuforums.org/showthread.php?t=659027&page=2 } Store (\_SB.C073, Index (DerefOf (Index (Local0, 0x02)), 0x02))
Now once you figured out how to fix the compilation errors, save your new DSDT into the file dsdt-fixed.dsl. Recompile this:
iasl -tc dsdt-fixed.dsl
and it will generate a file called dsdt-fixed.hex. Save this somewhere (say /root/dsdt/dsdt-fixed.hex), as we will use this in the next step.
Recompiling a kernel with your fixed DSDT
Now we get your newly fixed DSDT installed. This involves recompiling a kernel. I'm going to describe how to recompile an official kernel with the necessary modifications. A great guide to recompiling an official kernel can be found here. I'm going to follow most of the steps there (with minimal explanation) and show only what's necessary to override the DSDT.
NOTE: Compiling the kernel takes a long time. However there's no reason you need to do this on the same machine you're overriding the DSDT of. If you have access to a fast Debian machine, you can do this there instead. HOWEVER certain parts of the user space need to be the same on both machines. I think you at least need the same libc on both machines, but not much else. The machines can probably be different architectures too.
Install the build dependencies:
apt-get install fakeroot build-essential devscripts apt-get build-dep linux-2.6
Get the kernel source (replace 2.6.31-2 below with your desired kernel version).
apt-get source linux-2.6=2.6.31-2 cd linux-2.6-2.6.31/ dch --local +dsdt
Now edit debian/config/defines and add dsdt to the value of abi.abiname. Both the machine I'm compiling the kernel on, and the target machine (the one with the broken DSDT) have architecture amd64. If your architecture is different, change appropriately (see debian/rules.gen for possible targets).
make -f debian/rules source-all fakeroot make -f debian/rules.gen setup_amd64_none_amd64 cd debian/build/build_amd64_none_amd64
Now your task is to edit the .config file in this directory and tell it about your new DSDT. This involves adding the lines
CONFIG_STANDALONE=n CONFIG_ACPI_CUSTOM_DSDT=y CONFIG_ACPI_CUSTOM_DSDT_FILE="/root/dsdt/dsdt-fixed.hex"
in the appropriate place. To do this, you have a couple of options: You can directly edit this in your favourite text editor (vim). Search for a similar commented out option, and replace it with the appropriate line above.
If you're worried you might mess something up, then you can instead
aptitude install ncurses-dev make menuconfig
and set the ACPI DSDT file using the menu options. Now once this is done, you need to compile your kernel. This is time consuming:
cd ../../.. fakeroot make -f debian/rules.gen binary-arch_amd64 binary-indep DEBIAN_KERNEL_JOBS=2 cd ..
The DEBIAN_KERNEL_JOBS should be the number of CPU's you have available when compiling your kernel. (Gentoo folks usually advise setting it to one more than the number of CPU's.) Whichever setting you use, you'll still be waiting for a while
If you think you might mess up, it might be a good idea to enable ccache to the above step. aptitude install ccache, and append DEBIAN_KERNEL_USE_CCACHE=true to the last line above. This way, if you need to recompile it will be a lot lot faster.
If this successfully completes, you should have all the .deb packages in the current directory. If you don't have any custom modules (e.g. openafs, broadcom-sta, ndiswrapper), then just do
dpkg -i linux-image-2.6.31-dsdt1-amd64_2.6.31-2+dsdt1_amd64.deb
as root, and reboot your system.
If you have custom modules, then you also need the Linux headers for this. If you install the headers first, then dkms will automatically compile some modules for you (e.g. openafs). As root do
dpkg -i linux-headers-2.6.31-dsdt1-common_2.6.31-2+dsdt1_amd64.deb dpkg -i linux-headers-2.6.31-dsdt1-amd64_2.6.31-2+dsdt1_amd64.deb dpkg -i linux-image-2.6.31-dsdt1-amd64_2.6.31-2+dsdt1_amd64.deb
and look in your system log to make sure there was no error produced by dkms. Finally install any modules you might have installed through module-assistant. You have to pass -l 2.6.31-dsdt1-amd64 to tell it to generate these modules for your newly compiled kernel.
m-a -l 2.6.31-dsdt1-amd64 a-i <your favourite module>
Now reboot into your new kernel. You can tell that your new DSDT is in use if you see something like
ACPI: Override [DSDT- nc65xx], this is unsafe: tainting kernel ACPI: DSDT @ 0x000000003f7c84c0 Table override, replaced with:
in the output of dmesg. The first thing you should do is to make sure your CPU temperatures and fan voltages are correctly reported.
Credits
This page was originally written by gi1242