Jun
3

Fix Toshiba battery issue for Linux

Its been a year since I made my last post and have been thinking about what I could write  to start posting again. I have finally found a perfect one. Yepieeee, Its about vexing Toshiba battery conflict with the kernel.  I have got my battery issue fixed after a long wait. First of all let me thank Steve who proposed the perfect resolution for this issue and many thanks to other people who were also part of this seeking for a resolution.

Here was the scenario.

Laptop Made : Toshiba L650 X5310

OS : Ubuntu, Centos, BackTrack Linux

Issue : None of them detects and show my battery status.

I have tried different versions of Ubutnu, distros, Kernels and none of them helped and hence raised a bug report at https://bugs.launchpad.net/ubuntu/+source/linux/+bug/703302

Surprisingly the thread got replies/responses from many people who were having the same issue and none had a clue about the fix. But reply no:16 by George Moutsopoulos helped me to find the solution.

Old Results :

efheem@tuxjockey:~$ cat /proc/acpi/battery/BAT1/*
present:                 no
present:                 no
present:                 no
efheem@tuxjockey:~$ dmesg | grep batt
[    1.370268] ACPI: Battery Slot [BAT1] (battery absent)

The cause of issue is because Toshiba included two sets of boot data that tell the OS what hardware exists in the machine. Windows reads the correct one whereas Linux doesn’t. We will need to build our own kernel to make this happen. We will need to extract the DSDT (Differentiated System Description Table) from the machine, the ASL modified, and a new AML DSDT can be compiled. The sections below show the way to tell Linux to use this modified DSDT instead of the version that came with the BIOS.

Get the original DSDL of machine:

# cat /sys/firmware/acpi/tables/DSDT > DSDT.dat

Disassemble it

# iasl -d DSDT.dat

Make the changes:

# vi DSDT.dsl

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

Build it:

# iasl -tc DSDT.dsl

This will create a file DSDT.hex (This file is used for kernel recompilation)

I received the below two errors during this compilation

N:B :- You can actually ignore these errors, this works even having these error unfixed. But if interested you can work out to get those fixed.  Else directly goto ‘Kernel Recompilation’ section.

———————————-

DSDT.dsl  2656:                     0x00000000,         // Length
Error    4122 -                              ^ Invalid combination of Length and Min/Max fixed flags

DSDT.dsl  2663:                     0x00000000,         // Length
Error    4122 -                              ^ Invalid combination of Length and Min/Max fixed flags

———————————-

Fix : (If you didnt receive any error please skip this part )

open DSDT.dsl file and go to the line where iasl indicated the error. In my case I go to lines 2656 and 2663.

iasl is complaining about the “Length” line “0×00000000″. This is wrong. Look at the “Range Minimum” and “Range Maximum”. Open up your Kcalc or whatever you Gnome people use and change it to Numeral System Mode. Make sure HEX is selected and now we subtract the minimun range from the maximun range and then we add 1. Since the minimum range is 0 (And you can’t subtract 0) I will input  FEAFFFFF and then add 1 which gives me FEB00000  (Don’t get confused, I’m simply omitting “0x”, the calculator doesn’t need this). I change 0×00000000 to 0xFEB00000 by Length. So now it looks like this:

0×00000000,         // Granularity
0×00000000,         // Range Minimum
0xFEAFFFFF,         // Range Maximum
0×00000000,         // Translation Offset
0xFEB00000,         // Length

Line 2663 changed to

0×00000000,    // Granularity
0xFED40000,         // Range Minimum
0xFED44FFF,         // Range Maximum
0×00000000,         // Translation Offset
0×00005000,         // Length

compile again.

Kernel Recompilation :

Install necessary packages:

apt-get install fakeroot kernel-wedge build-essential makedumpfile kernel-package libncurses5 libncurses5-dev
apt-get build-dep --no-install-recommends linux-image-$(uname -r)
mkdir /root/source

cd /root/source

apt-get source linux-image-$(uname -r)

NB: My uname -r was 2.6.38.2-generic

cd linux-2.6.38

(replace this with your kernel version)

copy kernel config file from your current kernel:

cp -vi /boot/config-`uname -r` .config

now copy the DSDT.hex file to the include folder inside kernel source

cp DSDT.hex /root/source/linux-2.6.38/include

open .config file we have just copied

vi /root/source/linux-2.6.38/.config

Make the below changes

CONFIG_STANDALONE=n
CONFIG_ACPI_CUSTOM_DSDT=y
CONFIG_ACPI_CUSTOM_DSDT_FILE="DSDT.hex"

save and quit.

My pwd : /root/source/linux-2.6.38

start compiling the Kernel:

make menuconfig

load the .config file, save the menu file and exit.

We are about to start the compile process . A little trick you can do is to set the CONCURRENCY_LEVEL variable to speed up the compile of the kernel. The number should be the number of processors you have plus one. So in my case I have a Intel Core i5 processor so I will add one with the 4 available.

cat /proc/cpuinfo | grep -i processor
processor    : 0
processor    : 1
processor    : 2
processor    : 3

I have got 4 processors, so concurrency will be 4+1

# export CONCURRENCY_LEVEL=5

Start Building :

Here I named my custom kernel as tuxsage, replace it with the one you wish.

# make-kpkg clean
# fakeroot make-kpkg --initrd --append-to-version=-tuxsage kernel-image kernel-headers

(This will take some time)

Once this is completed you will find the built kernel one directory up from your present directory

# cd /root/source
# dpkg -i linux-image-2.6.38.(This part will be whatever name you gave it).deb
# dpkg -i linux-headers-2.6.38.(This part will be whatever name you gave it).deb

Make initramfs:

# update-initramfs -c -k 2.6.38+tuxsage (replace tuxsage with correct name)

Update Grub :

#update-grub

Reboot to the New Kernel :)

UPDATE : If you are using latest Ubuntu (11.10) with kernel 3.0.0-12-generic then you can get my custom compiled kernel with battery fix downloaded directly from http://www.4shared.com/file/O8CRV1qo/Toshiba-kernel-304-tuxsagetar.html which you can install and use. Have a look at ReadMe.txt for install instructions.

N:B : This post was made very soon after I got this fixed and you may find typos and other errors. Will proofread and fix those soon if any :-)

References :

https://bugs.launchpad.net/ubuntu/+source/linux/+bug/703302

https://bugzilla.kernel.org/show_bug.cgi?id=34532
https://bugzilla.kernel.org/show_bug.cgi?id=15707

http://homeport.org/~bcordes/satellite-l500-install.html

http://www.insanelymac.com/forum/lofiversion/index.php/t189272-100.html

http://en.gentoo-wiki.com/wiki/ACPI/Fix_common_problems

http://www.lesswatts.org/projects/acpi/overridingDSDT.php

http://www.question-defense.com/2010/09/26/how-to-recompile-your-ubuntu-10-10-kernel-for-patching-or-to-add-support-for-a-specific-device

100 Comments to “Fix Toshiba battery issue for Linux”

  • Aaron November 17, 2011 at 6:50 pm

    I used your custom kernel for 11.10 and it fixed the battery issue, so thank you for that. However, now my screen turns black on my laptop whenever I log in to my account. I can use an external monitor which is how I’m typing this right now, and the guest user screen doesn’t turn black. Please help.

    • Aaron November 17, 2011 at 6:51 pm

      Wow, it randomly just fixed itself.

    • Aaron November 23, 2011 at 10:58 pm

      So it does work when I plug in an external monitor, and then remove the monitor my laptop display works. However, if I turn it off and on again, the same issue happens. Does anyone know why?

  • Jose November 23, 2011 at 9:37 am

    Rebuilt NOT needed. Just folow the step in this link to fix this issue:

    http://blog.michael.kuron-germany.de/2011/03/patching-dsdt-in-recent-linux-kernels-without-recompiling/

    • rod November 27, 2011 at 3:38 am

      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

    • ido December 20, 2011 at 10:20 am

      Thanks for the link.

  • Yanesh Jankie November 24, 2011 at 9:40 pm

    perhaps making a video could greatly assist. I haven’t much history of programming (did some Pascal at school) but I do have a suggestion/ idea. you said that windows reads the correct file, right? can’t then the code that generates battery status for windows be isolated and run on Linux? or even have Windows installed on a very, very small partition of the disk, and run the code to generate battery status form that partition with a Linux app? it is extremely annoying to not know one’s battery status.. many thanks.

  • Jussi November 30, 2011 at 7:01 pm

    Fix for SATELLITE L750-1p9

    Replace BATTERY original _STA method with this patch:

    Method (_STA, 0, NotSerialized)
    {
    If (BTIN)
    {
    Return (0x1F)
    }
    Else
    {

    If (ECON)
    {
    Store (^^PCI0.LPCB.EC0.MBTS, Local0)
    If (LEqual (Local0, One))
    {
    Store (One, BTCH)
    Store (Zero, BIFI)
    Store (One, BTIN)
    Return (0x1F)
    }
    }

    Return (0x0f)
    }
    }

  • Cragle December 4, 2011 at 11:23 pm

    man i am using your compile kernel but i realized that after i stop using my laptop for a while my screen stay in black

  • John December 5, 2011 at 2:30 pm

    Thanks Jose, that solved my problem. Your method is the preferred way so that future kernel updates will not affect DSDT settings/bettery. Thanks a lot

  • Rodger December 10, 2011 at 5:33 am

    Is your custom compiled kernel for Ubuntu (11.10) for only 32bit? Is there a 64bit version?

  • FullMetal December 17, 2011 at 7:03 pm

    amd64 – i386 problem. If you get some time could you make the fix for 32 bits.
    Thanks a lot.

  • Pablo Barrales December 18, 2011 at 11:08 pm

    Thanks, this help to me, but now I have an error, and showme this:

    …..
    FATAL: Could not load /lib/modules/3.0.0+tuxsage/modules.dep: No such file or directory
    FATAL: Could not load /lib/modules/3.0.0+tuxsage/modules.dep: No such file or directory
    FATAL: Could not load /lib/modules/3.0.0+tuxsage/modules.dep: No such file or directory
    FATAL: Could not load /lib/modules/3.0.0+tuxsage/modules.dep: No such file or directory
    FATAL: Could not load /lib/modules/3.0.0+tuxsage/modules.dep: No such file or directory
    FATAL: Could not load /lib/modules/3.0.0+tuxsage/modules.dep: No such file or directory
    FATAL: Could not load /lib/modules/3.0.0+tuxsage/modules.dep: No such file or directory
    ….. Every time.

    • yoyo February 10, 2012 at 8:58 am

      There is a typo: should be 3.0.0-tuxsage instead of 3.0.0+tuxsage (- instead of +).

    • Mostav March 9, 2012 at 10:14 pm

      go to /root/source and with dir command find exact name and repeat last 2 commands…
      i’m sure u can

  • qmor January 4, 2012 at 8:39 pm

    Nice. Want to try this method. Maybe it could help with my toshiba L735

  • Francisco January 10, 2012 at 7:37 pm

    someone with this problem?

    LD drivers/built-in.o
    ld: final link failed: No space left on device
    make[2]: *** [drivers/built-in.o] Error 1
    make[1]: *** [drivers] Error 2
    make[1]: se sale del directorio «/root/source/linux-2.6.38»
    make: *** [debian/stamp/build/kernel] Error 2

    12 hours of work and i could not compile =S

  • Rich Dougherty March 13, 2012 at 9:48 am

    > search for line : OperationRegion (EMEM, SystemMemory, 0xFF808001, 0xFF)
    > and replace it with : OperationRegion (EMEM, EmbeddedControl, 0×00, 0xFF)

    Careful! The replacement text has a typo: 0×00 (with a multiply character, “×”) rather than 0×00 (with an “x”).

    • Faheem March 18, 2012 at 9:56 am

      Hey Rich, Thanks for the heads-up. This has been corrected.

  • sarath May 7, 2012 at 2:02 pm

    is customized kernal available for ubuntu 12.04 64bit?

  • Tim May 8, 2012 at 2:38 pm

    Hey, I’ve gotten to the point were I’m supposed to change the OperationRegion (EMEM, SystemMemory, 0×FF808001, 0×FF) , Backspace obviously doesnt work. but i can use the delete key, however I cannot input any new text? help please :(

  • Lukman May 13, 2012 at 6:33 am

    DSDT.dsl 4616: Method (_DSM, 4, NotSerialized)
    Warning 1088 – ^ Not all control paths return a value (_DSM)

    DSDT.dsl 4616: Method (_DSM, 4, NotSerialized)
    Warning 1081 – ^ Reserved method must return a value (Integer/String/Buffer/Package/Reference required for _DSM)

    how to fix this warning?

Post comment

Follow us on Twitter! Follow us on Twitter!
http://twitter.com/efheem
The next version of Ubuntu is coming soon

Recent Posts

Recent Comments

Firefox Download Button
Google Analytics Alternative Add to Technorati Favorites Technology Blogs - BlogCatalog Blog Directory Free Hit Counter Technology Google Analytics Alternative Blog Buzzer