Patching DSDT in recent Linux kernels without recompiling

Up until a year or two ago, the Linux kernel let you replace the ACPI DSDT by adding a customized version to the initrd. However, more recent versions disable that by default. If you’re using Grub2 as your bootloader though, the alternative is simple: just add acpi /boot/dsdt.aml to your Grub config. If you prefer a more elegant solution, just add the attached 01_acpi.txt to /etc/grub.d, renamed it to 01_acpi and chmod +x it; then run update-grub2 to rebuild your Grub config. It originally came from ubuntuforums.org and I removed the -e flag in the acpi line, which caused the new DSDT only to be visible to Grub, but not to the OS.

I believe the acpi command in Grub2 originally came from the Hackintosh community – messing around with DSDTs is a lot more common there because Mac OS X is rather picky.

For those of you who don’t know what I’m talking about: the DSDT describes certain hardware features your PC has, such as buttons, CPU power save modes, and lots of other things. Some mainboards have very poorly done BIOSes that have equally messed up DSDT tables. I won’t go into a lot of detail regarding how to fix those here though (it’s as simple as cat /proc/acpi/dsdt > dsdt.dat; iasl -d dsdt.dat; editing dsdt.dsl to your liking; iasl -tc dsdt.dsl (this last step will probably produce a number of errors that can be solved by googling for the error number and making the appropriate changes in dsdt.dsl)).

Another valuable hint for people messing around with DSDTs: the DSDT is not the only place that can contain this kind of information, the other place would be the SSDT and possibly additional SSDTs. You can find them in /sys/firmware/acpi/tables and decompile them just like the DSDT as described above. Instead of recompiling the SSDT by itself, you could probably also consider merging it into your custom DSDT at the appropriate places.

Tags: , ,

37 Responses to “Patching DSDT in recent Linux kernels without recompiling”

  1. Eric says:

    Just stumbled across this… glad to have found it. Thanks for the tip, it worked great for me on the 3.0.0 kernel in Ubuntu 11.10. My issue was with a Toshiba laptop not seeing the battery, so between your post and http://techinterplay.com/fix-toshiba-battery-issue-linux.html I’ve got my battery showing up and working without a kernel recompile. Thanks!

  2. Adrian says:

    Glad to find the useful tip. Thanks.

    I have a question about the last one sentence: “you could probably also consider merging it into your custom DSDT at the appropriate places.” Could you kindly provide the steps for merging SSDT into the custom DSDT?

  3. @Adrian: Just copy the contents from SSDT.dsl to DSDT.dsl and place them at a syntactically correct place (iasl will complain if you do it wrong). If identically-named sections exist both in DSDT and SSDT, you can usually replace the one in DSDT with the one from SSDT (though you might want to google to find out what that section name does — some sections appear to be allowed multiple times). If you upload your disassembled DSDT and SSDT to pastebin.com or something, I could take a look at it and give it a try.

  4. rod says:

    Eric, I’m following your recomendation of using grub instead of recompiling kernel. The custom downloadable kernel does work, but it kills the 3d nvidia acceleration with the propietary drivers. My question is: in Patching DSDT post the man mention a DSDT.aml to add in grub… but the files after extracting, disassemby and reasembli are .dat .hex and .dsl.
    ¿How exactly do you use your custom DSDT in grub? I am missing the step that trasform to .aml
    Thanks

  5. @rod:
    iasl -tc dsdt.dsl

  6. Nicholas Hunsicker says:

    Just wanted to say that I came over from the tech interplay page about fixing the toshiba battery issue as well, and I have this working now over here. For those that are totally clueless about messing with /etc/grub.d you need to remember to run an update-grub2 afterward otherwise you’re not going to see any change.

  7. ido says:

    Thanks for the post. Combined with the post in techinterplay.com, now I don’t have to endure “the torturing 2 hours” of recompiling anymore just to have the battery indicator light up in my desktop.

    By the way, I wonder what is the real function of -e in the first line of 01_acpi files ?

  8. Veer says:

    Hello Michael Kuron ,

    I have added the file 01_acpi.txt in to /etc/grub.d after changing the permission as you mentioned.
    Then I have edited the file DSDT.dsl as per the instruction of techinterplay.com. And recompiled the dsdt.dsl using the command iasl -tc dsdt.dsl. Finally I updated the grub. Unfortunately the battery meter is not showing up on my LinuxMint. Could you please assist me to resolve the issue?

  9. Is that grub2? Did you remove the .txt extension and then chmod +x it? If you did everything correctly, you’ll get a line saying that it found an ACPI table when you run update-grub2 to rebuild the grub config.

  10. Veer says:

    Hello,

    Thank you very much for your promptly reply. I have removed the extension and changed the permission as you mentioned. However the update grub is not showing found acpi table. Should I try once again?

  11. Veer says:

    Hello Michael Kuron,

    I apologize for the misinformation. I am using grub 1.99. Is it possible to fix the issue?

  12. I believe 1.99 is already grub2, I’m running 1.98 and that’s definitely grub2. Grub 1 lacks essential features, most notably the acpi command itself, so that wouldn’t work.
    Other than what I wrote previously, there’s nothing I can suggest (it should just work), so you’re on your own there. If you find out what’s causing the issue, please do post it. A good starting point would be to add an echo line to the script and see whether that gets output when running update-grub2. Also, please make sure that your recompiled DSDT is at /boot/dsdt.aml (case-sensitive), as that is where the script looks.

  13. Veer says:

    Hello Michael Kuron,

    Additional information if it will help the DSDT is located in /sys/firmware/acpi/tables/ instead of cat /proc/acpi.

    Thanks.

  14. AMAR says:

    Hi,

    I am also getting error “Non-ascii input file – DSDT.dsl” while recompiling the DSDT.dsl.

    thanks.

  15. Did iasl -d dsdt.dat yield the proper text file which you edited and does that error occur when you do iasl -tc dsdt.dsl? Maybe your iasl version has a bug (I used 20100528 from Debian Squeeze which worked fine) or your text editor screws up character encoding — it’s kind of hard to tell without knowing the details.

    Also, there are many places around the internet that explain how to recompile a DSDT and how to use iasl, neither of which my original blog post talked about — so I’d prefer to keep the comments restricted to the actual process of injecting the dsdt.aml.

  16. Jasmine Hassan says:

    This should be added to Kernel Documentation/acpi/override*.txt

    Danke shen :)

  17. Ubuntu user says:

    Thanks, I am using 11.04 and this works great.

  18. The commands for decompiling and recompiling (iasl -d and iasl -tc) have been mentioned several times here. Any further questions for them will get deleted.
    Any comments asking for help with specific iasl warnings will also get deleted. There are so many resources for DSDT fixing around the internet that can help you — Google is your friend.

  19. Mike says:

    This fix solves battery monitor update problem on Toshiba Satellite C655 (and probably other Toshiba models) running Ubuntu (Kubuntu) 11.10.

  20. Mike says:

    Spoke too soon… I knew I should have more fully tested this. :)

    On the Toshiba C655 the battery drain is updated, but the charging is not.

    Helpful if you want to know how much battery you have left when running on the battery, but doesn’t provide you with an update on the charging status. Have to unplug/plug in to get the current charge.

  21. gamma says:

    Hey, thank you very much. I finally managed to fix my battery problem without compiling the kernel. :-)

  22. arnold says:

    For it worked when I first followed the Techinterplay section to fix dsdl (http://techinterplay.com/fix-toshiba-battery-issue-linux.html).
    sudo su
    # cat /sys/firmware/acpi/tables/DSDT > DSDT.dat
    # iasl -d DSDT.dat
    # gedit DSDT.dsl

    do not copy/paste when you do the following, or you will get the error “Non-ascii input file – DSDT.dsl” when you try to compile!

    search for line : OperationRegion (EMEM, SystemMemory, 0×FF808001, 0×FF)
    and replace it with : OperationRegion (EMEM, EmbeddedControl, 0×00, 0×FF)
    save the file.

    # iasl -tc DSDT.dsl

    then I had to rename and move the .aml:
    # mv DSDT.aml /boot/dsdt.aml

    Then I followed this blog’s advice:
    …add the attached 01_acpi.txt to /etc/grub.d, renamed it to 01_acpi and chmod +x it; then run update-grub2…

    …happy now:)

  23. Michael says:

    I’ve tried your /etc/grub.d script and experienced the following problem:

    error: hd0 read error.
    error: hd0 read error.
    error: hd0 read error.
    error: hd0 read error.
    error: hd0 read error.
    error: hd0 read error.
    error: hd0 read error.
    error: hd0 read error.
    error: hd0 read error.
    assert: error stack overflow detected!
    error: hd0 cannot get C/H/S values.
    error: no such device: c42eea91-ed22-4ac5-9ddc-a9070f1080b6
    error: hd0 cannot get C/H/S values.
    error: hd0 cannot get C/H/S values.

    After that, grub gets me back into the menu from where I can select a kernel, which results in a similar error:

    error: hd0 cannot get C/H/S values.
    error: hd0 cannot get C/H/S values.

    This error only disappears when rebooting the system into a live CD, modifying the grub.cfg and removing the grub acpi option. I guess that there may be something wrong with my dsdt.aml, although it does not have any compile errors.

    Therefore, I propose an intermediate solution for easy debugging: /etc/grub.d/21_acpi

    [prefix code from /etc/grub.d/01_acpi here]

    # Load custom ACPI table
    if [ x${GRUB_CUSTOM_ACPI} != x ] && [ -f ${GRUB_CUSTOM_ACPI} ] \
    && is_path_readable_by_grub ${GRUB_CUSTOM_ACPI}; then
    cat <&2
    prepare_grub_to_access_device `${grub_probe} –target=device ${GRUB_CUSTOM_ACPI}` | sed -e “s/^/ /”
    cat << EOF
    acpi (\$root)`make_system_path_relative_to_its_root ${GRUB_CUSTOM_ACPI}`
    }
    EOF
    fi

  24. Michael says:

    I’ve found out that –no-edba fixes the problem from my last comment. However, I do not know how effective my update then is.

  25. Adam says:

    I’m new to Ubuntu but am running 12.04 and have the same issue with the battery showing as not present; i’ve followed the instructions from here and Techinterplay but i’m stuck at the part:

    search for line : OperationRegion (EMEM, SystemMemory, 0×FF808001, 0×FF)
    and replace it with : OperationRegion (EMEM, EmbeddedControl, 0×00, 0×FF)
    save the file.

    I cannot find this line in the DSDT.dsl file at all so assume this fix doesn’t apply to 12.04?

  26. David Rodrigues says:

    Hey Micheal,
    I’m facing the same problem as you are:

    (The grub problem -
    ….
    error: hd0 read error.
    error: hd0 read error.
    assert: error stack overflow detected!
    error: hd0 cannot get C/H/S values.
    etc… etc….)

    I’ve tried using your code for creating 21_acpi but it doesn’t seem to get accepted while generating grub.cfg.

    Could you tell me how you used it or if you have found another solution to your battery problem?

    Thanks

  27. Michael says:

    Well, I’ve not found any real solution to the problem yet :/ Next I’ll try to compile the DSDT directly into the kernel.

  28. David Rodrigues says:

    Hey I compiled it using the techinterplay instructions. Although the kernel worked fine, it still didn’t give any battery indicator. If your compiled kernel gets the indicator could you send me a copy at this (davidlandofnod@gmail.com) email address? Thanks in advance.

  29. Andrew says:

    totally worked! Thanks so much for the cleaner fix for my battery woes!

  30. Ashish Singh says:

    I did the mentioned step and got my battery meter and status running in Ubuntu 12.04. However, I have dual boot system in my Toshiba Satellite L645 with Windows 7. It seems that modifying the boot loader has caused my Windows to throw error “BIOS error – non compliance ACPI” and does not load. When I removed the files DSDT.dsl and 01_acpi from their respective folders, Windows works but I don’t have battery status in Ubuntu. Any suggestions ?

  31. You most likely screwed up the DSDT while modifying it. Try doing that step by step and see which step breaks it and then google around to see if someone has a fix.
    Alternatively, you could modify /etc/grub.d/10_linux to only run the acpi command when you boot Ubuntu (instead of running it right away when entering Grub).

  32. Ashish Singh says:

    @Michael Kuron – Thank You for your reply. I did not actually modified the DSDT but downloaded a copy of it. I’m not sure how to do step by step break down of it. Also could you specify what should I edit in /etc/grub.d/10_linux so it doesn’t effect Winodws. Thanks again !!!

  33. If you downloaded a DSDT.aml, it most likely isn’t even compatible with your computer. DSDTs are highly device-specific and even vary between revisions of the same hardware and might be modified during BIOS updates. Therefore: always modify the DSDT yourself.

  34. Ashish Singh says:

    I tried to edit DSDT myself. First of all, I couldn’t do cat /proc/acpi/dsdt since there are no such file there. So, I did cat /sys/firmware/acpi/tables/DSDT > DSDT.dat .Then I disassembled it using iasl -d DSDT.dat. I noticed that DSDT.dsl already has the line “OperationRegion (EMEM, EmbeddedControl, Zero, 0×FF)” so there is nothing to edit. So I built it again mv dsdt.aml ito /boot/dsdt.aml and did update-grub2. However, I still have the same issue. Also, I notice that in Ubuntu, I don’t have Suspend mode, just Hibernate.

  35. Ashish Singh says:

    Nevermind, I got it resolved. cat /sys/firmware/acpi/tables/DSDT > DSDT.dat was just outputting the incompatible DSDT.aml file that I had downloaded. Everything seems to be working now. Thanks for bearing with me.

Leave a Reply