Tuesday, September 9, 2008

Launchpad PPA launched!

Just setup my Launchpad PPA. Current contents are

Packages are built for Ubuntu Hardy. I will keep uploading new packages when I encounter an interesting software that has no Hardy package available within my reach.

[Last update: 04/13/2009]

Tuesday, July 8, 2008

MMC hack on WRT54G v2 with OpenWrt Kamikaze 7.09

To begin with, this is definitely NOT a new hack. While there are a whole bunch of postings and howtos talking about this hack, I simply would like to share some of my own experiences and thoughts in this matter. Thus I will be referring you to other sources on particular subjects rather than stuffing this blog entry with all the details.

PRECAUTION: Hacking a piece of hardware is almost NEVER for the faint hearted.

OK, let's kick it off!

1. Hack the PCB board
Simply put, we want to connect an MMC/SD card reader to several GPIO pins on the router mainboard. This is done by soldering pins of the card reader to corresponding solder points on the board. There is a pretty detailed wiki page on how to do this:
MMC Wiki
ATTENTION: Please read carefully section "3.2. WRT54G v2.2 and WRT54GS" of the page before any soldering, even if you are working on a v2! You will need a multimeter for this project, both for finding the correct pins and for detecting short circuits.

2. Customize the firmware
Soft reboot will stop working correctly after the hack; instead it will take you to the failsafe mode. If you are just interested in a solution and don't want to wet your own feet, go to the end of this section and download my compiled firmware. The details of this bug can be found in this thread:
Reboot Bug
The idea behind the workaround proposed by migube in the thread resolves this issue -- though not until we adapt his idea to Kamikaze. In Kamikaze, instead of modifying /etc/preinit, we need modify /etc/preinit.arch, and the magic place for inserting
echo '0xb8' > /proc/diag/gpiomask
is right before the line
echo '/sbin/hotplug.failsafe' > /proc/sys/kernel/hotplug
Note that the mask "0xb8" is calculated according to the gpio mask table in MMC Wiki. You can get the modified file here:
Since during the preinit stage jffs partitions haven't been mounted yet, in order to edit this file you have to build it into the firmware and reflash your hardware. To do this all you need is the ImageBuilder package. (Thanks again to the OpenWrt team for making things so easy.)
Kamikaze ImageBuilder (i686)
Kamikaze ImageBuilder (x86_64)
Unpack the archive and cd into it. Then type make to see help information. To overwrite the original preinit.arch file and build the firmware, you do the following (assuming you are at the root of the ImageBuilder folder):
$ mkdir -p files/etc
$ cp <new_preinit.arch> files/etc/preinit.arch
$ chmod +x files/etc/preinit.arch
$ make image FILES=files
Now your new firmware should be ready in bin folder. An alternative to building it yourself is to use my compiled version, which includes four extra packages than the standard set: kmod-fs-ext3, e2fsprogs, libuuid (required by e2fsprogs), and fdisk.
At last don't forget to flash it into your box. I assume all readers of this article know how to do it.

NOTE: After a soft reboot all port leds will be lit, but I haven't noticed any undesired behaviors other than this. No workaround for this is known yet. (If you know any please comment this entry.)

3. Prepare the system
Insert an empty SD card into the reader (of course only if you are not soldering on a card directly), and put your box back into shape. Everything else from now on can be done interactively from the router shell, i.e. no wires or flashing anymore.

Boot the router, let it do all the initializations, and telnet into it. Then the first thing you need is the mmc driver. As described in MMC Wiki I recommend the optimized driver by Cyril. For WRT54G v2, you need the gpio5 version. Download and copy it to /lib/modules/2.4.34/ in your box. You also need to have kmod-fs-ext3, e2fsprogs, libuuid, and fdisk installed in your box. These are already included in my compiled firmware. Now on the router load the module:
# insmod mmc
# dmesg
A successful module init should give you something like this:
[INFO] mmc_hardware_init: initializing GPIOs
[INFO] mmc_card_init: the period of a 380KHz frequency lasts 518 CPU cycles
[INFO] mmc_card_init: powering card on. sending 80 CLK
[INFO] mmc_card_init: 80 CLK sent in 43090 CPU cycles
[INFO] mmc_card_init: resetting card (CMD0)
[INFO] mmc_card_init: doing initialization loop
[INFO] mmc_card_init: card inited successfully in 488 tries (14704842 CPU cycles).
[INFO] mmc_init: MMC/SD Card ID:
02 54 4d 53 44 35 31 32 28 8b bb 5f 90 00 81 1f [INFO] Manufacturer ID : 02
[INFO] OEM/Application ID: TM
[INFO] Product name : SD512
[INFO] Product revision : 2.8
[INFO] Product SN : 8bbb5f90
[INFO] Product Date : 2008-1
[INFO] mmc_card_config: size = 500224, hardsectsize = 512, sectors = 1000448
[WARN] mmc_init: hd_sizes=500224, hd[0].nr_sects=1000448
[INFO] mmc_card_init: set_blocklen (CMD16) succeeded !
Partition check:
mmca: p1
If you see any error in dmesg, most likely there's something wrong with your soldering. Checking for short circuits or wrong pins is all that I can suggest. As mentioned in the end of MMC Wiki, the recommended way of utilizing an external SD card is to make it your new root. ExternalMedia Wiki is an excellent guide on doing it, though not exactly working on my box. I've made some slight modifications to their method, and for clarity, I will include everything here.
# fdisk /dev/mmc/disc0/disc
(Erase the partition table and create one big partition)
# reboot
# insmod mmc
# mke2fs -j /dev/mmc/disc0/part1
# mount /dev/mmc/disc0/part1 /mnt -o noatime
# cp -a /rom/* /mnt/
# mkdir -p /etc/rc.mmc.d
Save the following file to /etc/config/bootfromexternalmedia
and the following file to /sbin/init.tmp
and the following file to /etc/rc.mmc.d/S40switch
and the following file to /mnt/etc/init.d/rcS (overwrite)
and the following file to /mnt/etc/init.d/network (overwrite)
Be sure to double check the paths before overwriting any file! Finally we are going to set the correct file permissions and activate the bootfromexternalmedia hack:
# chmod +x /sbin/init.tmp /etc/rc.mmc.d/S40switch \
/mnt/etc/init.d/rcS /mnt/etc/init.d/network
# rm /sbin/init
# mv /sbin/init.tmp /sbin/init
# sync
Unmount the card and reboot your box:
# umount /mnt
# reboot
Give it a couple of minutes and try to telnet into the box. If you see the prompt, hooray! You can now install your favorite softwares and web interfaces and everything as usual, except the HUGE boost in storage! If somehow you get stuck with the box, simply unplug and plug it, then it should deactive the bootfromexternalmedia hack and take you back to the old prompt. A log file should appear as /bootfromexternalmedia.log, indicating which service choked the system.

RATIONALE: The problem with the original approach in ExternalMedia Wiki and my WRT54G v2 is that the system got stuck at network initialization, namely the step of setup_switch. My understanding is that when initializing the network switch of this board, some gpios used are also shared with our MMC hack, which in turn causes a conflict. My proposed workaround is to move the switch initialization to an earlier time, before mounting the SD card. Simple, isn't it! I've also modified it to be more debug friendly and failure recoverable.


At last, a screenshot may give you a better idea of what will happen after this hack.

Thursday, February 7, 2008

Deb packages of Pidgin 2.3.1 for Ubuntu Feisty

Back ported from Hardy repository.

Main packages:
pidgin_2.3.1-2ubuntu1+jason1_i386.deb
pidgin-data_2.3.1-2ubuntu1+jason1_all.deb
libpurple0_2.3.1-2ubuntu1+jason1_i386.deb

Dummy package for dependency issues:
gaim_2.3.1-2ubuntu1+jason1_all.deb

Dev packages:
pidgin-dev_2.3.1-2ubuntu1+jason1_all.deb
libpurple-dev_2.3.1-2ubuntu1+jason1_all.deb

Encryption plugins:
You can choose between pidgin-otr and pidgin-encryption. Check their websites for supported features. Personally I suggest pidgin-otr, due to its interoperability with other clients besides pidgin/gaim, e.g. Adium X on mac.
pidgin-otr_3.1.0-1jason1_i386.deb and libotr2_3.1.0-2jason1_i386.deb
or
pidgin-encryption_3.0-1jason1_i386.deb

Monday, February 4, 2008

Slow down your evdev mouse

Evdev is a generic input device driver for xorg. It provides basic support to a wide range of keyboards and mice. Particularly, sometimes the mouse driver may not work well with your stylish mouse, e.g. my Logitech VX Revolution. Then give evdev a shot and very likely it's gonna work like a charm. Generic as it is, however, evdev lacks many advanced features, among which one remarkable feature is to slow down mouse speed. AFAIK the mouse driver also lacks this functionality in its up-to-date version. To make it even worse, evdev does not respect "xset m" instructions, which could be used as a workaround for mouse. Thus if you possess a mouse with really high resolution, the flying speed will likely render it useless with evdev.

Now that's enough for background. I've made a tiny patch against xf86-input-evdev version 1.1.5, to add a "Speed" parameter to evdev. It takes a real value between 0 and 1, and a line like this in your evdev device section
Option "Speed" "0.5"
will slow down your mouse by half. The option defaults to 1.0 meaning original speed.

The patch is here (evdev-speed-1.1.5.patch) and I've also built a deb package for it here (xserver-xorg-input-evdev_1.1.5-0ubuntu2+jason1_i386.deb).

Tuesday, January 22, 2008

Let HAL work with thinkpad_acpi

With the new thinkpad_acpi module succeeding ibm_acpi, there is one great thing going on. Hot key presses are now sent to the input layer, which means you can handle them as real key press/release events and throw those ACPI handlers into garbage bin. The current version of HAL, however, is not working well with the event device created by thinkpad_acpi. Newer kernels come with SW_RADIO switch event which is the only SW bit used by thinkpad_acpi, but HAL fails to follow up the steps. Thus the pre-probing during HAL's process of adding a new input device will fail with no supported SW bits found. Simply put, HAL will not listen on that event device, which most probably renders it useless unless you write your own event handlers for it.

As simple as it is, I spent quite some time digging it up from the source code. Then when I posted it to the HAL mailing list, Ben Liblit kindly pointed me to this bug entry, where he provided a nice patch for HAL. Trust me, I searched around it really hard before getting into the source code, and Google failed to get me this link. Shame for Google. ;)

So if your HAL is 0.5.10, just apply the patch. Make sure your linux/input.h is new enough to contain SW_RADIO. With earlier versions, try searching for every appearance of SW_HEADPHONE_INSERT and make modifications accordingly.

With HAL 0.5.10, you can get quirks from this page to get correct keymaps (and other stuff) for your model. With older versions, like me, you can use my little program to map your keys your way.

thinkpad-acpi-keys.tar.gz

Compile setevkeycodes.c and put it in /usr/local/sbin. Install thinkpad-acpi as a service and copy thinkpad-acpi-keymap to /etc/default. If you prefer to use different paths, modify thinkpad-acpi script accordingly. FYI, the keymaps in thinkpad-acpi-keymap are my current settings, on a T60.

Tuesday, January 15, 2008

A subtle change in event interfaces with the new kernel

I'm finally fed up with the stock kernel 2.6.20 of Ubuntu feisty, because I want to try out the iwlwifi driver for my intel 3945 wireless card. The new kernel is 2.6.23.13, and I noticed a subtle change in event interfaces, which breaks acpi_fakekey for many special keycodes. It's when you write an "unsupported" keycode to an event device, the old kernel will take it and propagate it to all processes listening on that device, but the new kernel just ignores it, pretending nothing has happened. Here I use the term "unsupported" to refer to being unmasked by the device keybits. acpi_fakekey is doing a pretty simple job here: find the first keyboard device and write the key press/release event to it, without regard to the true capabilities of that device. Now you see how this change breaks it.