Override DSDT to fix Toshiba Battery Status

When I installed Debian on my new laptop earlier this year, I was impressed by how easy it was to set everything up. However, I had to cope with a nagging bug: My system couldn’t recognize the battery, so I had no idea how much time I had before running out of power. It turns out that sloppy Windows programmers at Toshiba shipped my Satellite L640 laptop with broken firmware that had to be fixed before the Linux kernel would recognize my battery.

It is necessary to recompile Linux to override the DSDT file. A succession of clumsy mistakes made this a miserably drawn-out process for me, but when it’s done correctly it’s reasonably simple. Following are the steps I took to override the DSDT on my 64-bit system running Debian GNU/Linux 6.0.2 (squeeze).

Step 1: Fix the DSDT File

See this helpful article for more details: http://techinterplay.com/fix-toshiba-battery-issue-linux.html.

Get the original DSDT from the machine:

$ sudo cat /sys/firmware/acpi/tables/DSDT > dsdt.dat

Disassemble it, installing the package iasl if necessary:

$ iasl -d dsdt.dat

Using your favorite editor (mine’s Vim), open up the newly-created dsdt.dsl and replace the line

OperationRegion (EMEM, SystemMemory, 0xFF808001, 0xFF)

with

OperationRegion (EMEM, EmbeddedControl, 0×00, 0xFF)

Save as dsdt-fixed.dsl and exit. Now reassemble:

$ iasl -tc dsdt-fixed.dsl

This creates the file dsdt-fixed.hex which we will compile into the kernel. You can ignore the errors and put the file somewhere in your /home directory for safe keeping (e.g., /home/user/src/dsdt/).

I made the mistake of saving it under /root even though I was running make as me. Wasting hours compiling only to find it didn’t work is no fun, so don’t do that. Don’t put it in the kernel include/ directory either because, on my system anyways, it won’t compile at all.

Step 2: Compile Linux with Custom DSDT

I had never compiled Linux before, so I followed the steps at the Debian wiki: http://wiki.debian.org/OverridingDSDT.

You may need to install build dependencies:

$ sudo aptitude install fakeroot build-essential devscripts
$ sudo aptitude build-dep linux-2.6

Find out what kernel you’re running and download its source to a convenient folder (e.g., /home/user/src/):

$ uname -r
2.6.32.5-amd64
$ cd src/
$ apt-get source linux-image-2.6.32-5-amd64
$ cd linux-2.6-2.6.32/

Note: If you have additional repositories such as squeeze-backports, make sure that you’re not downloading a different kernel source by temporarily commenting the relevant deb-src line out of /etc/apt/sources.list and updating apt. The squeeze-backports kernel, 2.6.39, will build, but I had some networking problems with it.

Add a comment to the changelog (e.g., “Custom dsdt”):

$ dch --local +dsdt

Edit debian/config/defines and append an identifier (e.g., “dsdt”) to the value of abi.abiname. This will be added to the name of the new kernel package. Then do this:

$ make -f debian/rules source-all
$ fakeroot make -f debian/rules.gen setup_amd64_none_amd64

Edit the file debian/build/build_amd64_none_amd64/.config so that it contains the lines:

CONFIG_STANDALONE=n
CONFIG_ACPI_CUSTOM_DSDT=y
CONFIG_ACPI_CUSTOM_DSDT_FILE="/home/user/src/dsdt/dsdt-fixed.hex"

Finally, it is time to compile the kernel. Set the “DEBIAN_KERNEL_JOBS” option to the number of CPUs on your machine to help speed things up; it will still take forever, so be patient:

$ time fakeroot make -f debian/rules.gen binary-arch_amd64 binary-indep DEBIAN_KERNEL_JOBS=4

This took almost three hours on my 2.67GHz processor:

real	164m18.577s
user	408m31.336s
sys	45m18.594s

Note: Running this command directly from the console saves a little time—about 15 minutes on my machine—when compiling. Log out of your desktop, go to tty1 (Ctrl+Alt+F1), log in, and kill your display manager (e.g., $ sudo killall gdm3). After you’ve run the command above in your source directory and generated the kernel image, start X up again (e.g., $ sudo gdm3 start) and log back in.

Note: Actually, it’s probably easier just to run it in a SCREEN session that you can attach or detach from as desired.

If you know what you’re doing (I don’t), you can considerably cut compile time by customizing the kernel yourself and removing extraneous drivers and such.

If all goes well, src/ should be filled with .deb files, including our new kernel image. Install it with dpkg (as root):

$ sudo dpkg -i linux-image-2.6.32-5-dsdt-amd64_2.6.32-35+dsdt1_amd64.deb

Reboot, and Linux will (hopefully) recognize your battery!

$ acpi -V
Battery 0: Discharging, 32%, 01:11:16 remaining
Battery 0: design capacity 5600 mAh, last full capacity 5188 mAh = 92%
Adapter 0: off-line

If you have custom modules, you need to compile them too—so see the wiki on that. Until the Linux developers add a workaround upstream, this process will be necessary whenever you upgrade to a new kernel.

Note: After installing virtualbox I regretted not keeping all of the .deb files I made. In order to compile custom modules (like vboxdrv), you also need to install the linux headers for your new kernel:

$ sudo dpkg -i linux-headers-2.6.32-5-dsdt-amd64_2.6.32-35+dsdt1_amd64.deb \
linux-headers-2.6.32-5-dsdt-common_2.6.32-35+dsdt1_amd64.deb

Keep backups of these files if you think you might need them, otherwise you’ll have to compile again like I did.

This entry was posted in Unix, Linux, and GNU and tagged , , , , , , . Bookmark the permalink.

8 Responses to Override DSDT to fix Toshiba Battery Status

  1. Lukman says:

    I can’t create DSDT.hex

    how to create it?

    • taylor says:

      you need to be root (i.e., sudo) for this command:
      $ sudo cat /sys/firmware/acpi/tables/DSDT > dsdt.dat

      iasl needs to be installed for you to disassemble the file:
      $ sudo aptitude install iasl

      this command:
      $ iasl -d dsdt.dat
      will create the file dsdt.dsl

      after editing it with your favorite editor (e.g., vim, nano, gedit, etc.) and saving the file as “dsdt-fixed.dsl”, the command:
      $ iasl -tc dsdt-fixed.dsl
      will generate your dsdt-fixed.hex file.

      good luck! it took me a long time to get the whole process to work.

  2. gero says:

    Hello.

    How did you configure this?
    Edit debian/config/defines and append an identifier (e.g., “dsdt”) to the value of
    abi.abiname. This will be added to the name of the new kernel package. Then do this:
    I didn’t find those folders.

    I have a satellite pro l640 sp4136 and Debian Squeeze 64 bits 6.0.2 I used the instructions here http://techinterplay.com/fix-toshiba-battery-issue-linux.html and I successfully build my kernel.
    After that I can’t change the bright of the monitor and the color depth (stuck in 16 bits).
    I can’t create a useful xorg.con file neither.
    You did other things after compiling the kernel?

    Thanks for the post, it was a great help.

    • taylor says:

      debian/config/defines should be in the linux source tree (e.g., /home/taylor/src/linux-2.6-2.6.32/debian/config/defines).

      the techinterplay.com article was very helpful; the only problem was that the kernel wouldn’t compile for me if i put dsdt-fixed.hex in the kernel’s include/ directory as suggested. i’m keeping it in a safe place in my home directory for the next time i have to recompile.

      overall i did not have too many problems configuring debian on my machine; i’ll try to share the tips and tweaks that worked for me in future posts. best of luck~

      • gero says:

        Yeah, I couldn’t compile the kernel the firs time… the problem is a firmware that is not included with the kernel, but one driver “vt6656″ needs it… so you must go to the .config file and set “CONFIG_VT6656=n” or simply comment the line with a sharp ‘#’…
        It is a know problem with the kernel, but I don’t know if it is fault of the kernel people or is debian staff fault.

        But it’s strange I’m using the same kernel, the same version of debian but I don’t have the “define” file.
        I have “/root/source/linux-2.6-2.6.32/debian/Config/”

        I don’t know what I did… but I still have problems with my custom kernel… It’s the same configuration of the debian build, just without vt6656, and with a custom DSDT file… but I can’t change the color depth or change the back light (and I can’t make an usable xorg.configfile)… but Instead I solved the problem doing a trick… I boot debian with the custom kernel, then “reboot” the kernel (I mean go to the lowest run level) then debian I don’t know why reboot with the default debian kernel and problem solved. Maybe it’s a little Spartan solution but what the hell “This Is my DEBIAN!”

        Thanks for your time.

  3. Cody Schafer says:

    Thanks, I really appreciate you making this info available.

    If I may ask, how did you determine the fix to be made? (or where did you find this info from?)

    • Cody Schafer says:

      whoops, just noticed the link at the top.

      • taylor says:

        Yes, I’m afraid there was little magic on my part—I just subscribed to the Debian and Ubuntu bug reports and waited for info to come out. The techinterplay.com and wiki.debian.org articles were my primary sources, but I learned the hard way that I had to make a few changes to get their steps to work right on my system. Being inexperienced in the kernel department, I wanted to make sure to put what I did all in one place so I (and others) could avoid the same mistakes.

        Peace~

Leave a Reply

Your email address will not be published. Required fields are marked *

*

*

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>