Archive for the ‘tuxbox’ Category

U-Boot hacking -or- The dbox2 can boot from disk!

Monday, July 6th, 2009

Thanks to a kind donator, I now own a Nokia dbox2 with IDE interface. (For those that don’t know - the dbox2 is a settop box designed for german paytv 10 years ago in a way that its bootloader would only run signed software. A limitation that was put aside by some cool hackers early in this century. Nowadays it usually runs Linux on its 66MHz powerpc CPU, 32MB RAM and 8MB FLASH ROM. Later some cool guys designed an IDE interface that plugs into the memory expansion slot)

The main use of such an IDE interface for most people is to use the box as a video recorder. However, I am already doing this via the ethernet port, wich is more practical for me than a built in disk.

I would have deemed it much more useful if I was able to boot from the IDE drive, since that would make it much easier to try out new experimental code without needing to upgrade the FLASH image all the time (having the known working version in FLASH as a fallback is mandatory for good WAF).

So I pondered the problem and found out, that people had already implemented basic support for the IDE interface in U-Boot (which is used as a “second stage” bootloader), and it could already access and read the disk.

Unfortunately, U-Boot needs to be in FLASH, and this U-Boot would then only boot from disk.

So I have been hacking on making U-Boot actually read multiple boot command lines (and and option which one to boot as default) from a config file in the /var/ partition of the FLASH which makes it pretty easy to switch the device we boot from. It is now actually similar to the boot process of the Tripledragon.

The only thing that’s missing now is a driver for the front panel keys, so that you can change the selection on the fly without using a serial console. That’s coming next, after the summer vacation ;)

Cross compilers for openSUSE

Thursday, April 30th, 2009

Based on Torsten Duwe’s great work (currently in the Buildservice in home:duwe:crosstools), which is building but not working 100% correctly, I fixed the powerpc version up (I have no other architecture to test on) and put them into the openSUSE Buildservice in home:seife:cross for now.
Get them from here: http://download.opensuse.org/repositories/home://seife://cross/SLE_11
(don’t get put off by that SLE_11, the cross compilers should be pretty system agnostic. For testing I ran them on a SLES10 which is probably older than anything you want to use, and they worked just fine)

Edit: I just found out that this only works because I have a patched rpm on my SLES10 which understands lzma compression. I have added SLES10SP2 to the repository so that pre-LZMA-rpm distributions still can use it.

So if you need a powerpc crosscompiler, just add that repository, install packages “cross-powerpc-embed-linux-gnueabi-binutils”, “cross-powerpc-embed-linux-gnueabi-gcc”, “cross-powerpc-embed-linux-gnueabi-glibc” and “cross-powerpc-embed-linux-gnueabi-kernel-headers” and you are ready to go.
Make sure that /opt/cross/bin is in your $PATH and configure your project for target “powerpc-embed-linux-gnueabi”.

Still TODO: get them into a proper semi-official project.

Oh - and of course I already changed my favourite embedded projects so that they are now able to build with an “external” toolchain ;)

Setting the repeat rate on an input device (Kernel 2.4 and 2.6)

Monday, December 8th, 2008

If you ever come into the situation of having to set the repeat delay/period on an input device (/dev/input/eventX), with the additional challenge of needing it to work on both 2.4 and 2.6 kernels, maybe this code snippet might help you (fd is the filedescriptor of the device, opened writable):

        #include <linux/input.h>
        struct input_event ie;
        ie.type = EV_REP;
        ie.code = REP_DELAY;
        ie.value = 1000; /* 1 second initial delay */
        if (write(fd, &ie, sizeof(ie)) == -1)
                perror("REP_DELAY");
        ie.code = REP_PERIOD;
        ie.value = 250; /* 4 events per second */
        if (write(fd, &ie, sizeof(ie)) == -1)
                perror("REP_PERIOD");

Looks pretty trivial, doesn’t it? But it took me quite some time to realize that I needed to write a “magic” event into the device to set the properties ;)

Triple Dragon continued

Wednesday, July 9th, 2008

This week is entirely dedicated to getting the Triple Dragon started with some usable software - and it is going along quite well.
I feared that I would have to dig down into DirectFB to solve my original framebuffer problems (on the first try I was unable to set the transparency - the setting, which is done with a private ioctl(), was always ignored), since the original software uses DirectFB, but in the end this is fortunately not the case.
The solution was simple: I need to issue the transparency-ioctl() after setting the framebuffer parameters, not before.
Right now, enigma is pretty usable, the “normal” TV viewing stuff is already working. I’m now refining the build system, so that I can tell people what they need to do to build the software, then I’ll look at the init scripts etc, so that they can even boot it.
Next thing will be fixing the not yet working stuff - some hardware-dependent like the SCART switching stuff, some software like the media-player and record / timeshift features, but then I’ll hopefully have some more people working on the project ;-)

Triple Dragon, anyone?

Monday, June 9th, 2008

After a kind guy donated me a Triple Dragon satellite STB (running Linux, of course), i started hacking on it. Unfortunately, the source code to the original Application is not available, but i’m not too happy with that one anyway. With the help of another Tuxbox-pioneer, Carsten “Carjay” Juttner, i now have the enigma GUI basically running on the machine. I do have some problems with the graphics device and the framebuffer (especially the interaction between both), so if you have information or can share your programming experience on IBM STB04xxx boxes or even on the Triple Dragon hardware / API, i would be most grateful for any hints.
I want to solve those problems before moving on and porting neutrino to that beast ;-)

linux@dbox2: implemented AVIA ENX reset

Saturday, August 25th, 2007

Since this is the first weekend after returning from vacation, i thought i’d turn to the tuxbox project again. This time i experimented with my Sagem dbox2 instead of my dreambox 500.
I was finally fed up with the joy of reverse-engineered hardware: sometimes, if you do strange things to the AVIA ENX chip, it will somehow lock up. Unfortunately, there is no way to reset it, short of rebooting the box. Looking at the code i found out that there actually is a reset function for the chip, but it’s only used at module load and unload. Unfortunately you cannot unload the module since lots of other stuff depends on it, so rebooting the box is actually faster than trying to reload the module.

I went for the quick and very dirty way and exported a file in /proc which, if something is echoed into it, performs a chip reset of the AVIA ENX chip.

The diff is quick, dirty, and trivial. But it works for me. The important parts of it are here:

--- a/driver/ext/aviaEXT.c      21 May 2006 23:01:10 -0000
+++ b/driver/ext/aviaEXT.c      25 Aug 2007 12:53:13 -0000
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/devfs_fs_kernel.h>
 #include <asm/uaccess.h>
+#include <linux/proc_fs.h>

 #include "avia_av.h"
 #include <dbox/aviaEXT.h>
@@ -86,6 +87,14 @@ static struct file_operations aviaEXT_fo
                .ioctl = aviaEXT_ioctl
 };

+extern void avia_gt_dmx_risc_reset(int);
+static int avia_av_proc_write_avia_reset(struct file *f, const char *b, unsigned long c, void *d)
+{
+       printk("calling avia_gt_dmx_risc_reset(1)\n");
+       avia_gt_dmx_risc_reset(1);
+       return c;
+}
+
 static int __init aviaEXT_init(void)
 {        if (!(devfs_h = devfs_register(NULL,"dbox/aviaEXT", DEVFS_FL_DEFAULT, 0, 0,
@@ -93,6 +102,18 @@
                printk(KERN_ERR "aviaEXT: could not register with devfs.\n");
                return -EIO;
        }
+
+       struct proc_dir_entry *proc_bus_avia_reset;
+
+       proc_bus_avia_reset = create_proc_entry("avia_reset", 0200, proc_bus);
+       if (!proc_bus_avia_reset) {
+               printk("avia_av_proc: could not create /proc/bus/avia_reset");
+               return -ENOENT;
+       }
+
+       proc_bus_avia_reset->write_proc = avia_av_proc_write_avia_reset;
+       proc_bus_avia_reset->owner = THIS_MODULE;
+
        return 0;
 }

Of course you need to EXPORT_SYMBOL(avia_gt_dmx_risc_reset); at the appropriate place.

Combine this interface with something like the following:

#!/bin/sh
valold=""
while sleep 1; do
        # the "avia" interrupts stop if the chip has crashed
        valnew=$(grep avia$ /proc/interrupts)
        if [ "$valnew" = "$valold" ]; then
                echo "$(date) avia_reset"
                echo > /proc/bus/avia_reset
        fi
        valold="$valnew"
done

It resets the chip automatically, should it crash again while experimenting.

Hackweek is over

Friday, June 29th, 2007

Hackweek was an event where my employer, the SUSE Linux Products GmbH in Nürnberg, or to be precise: our mother company, Novell, allowed all of its Linux engineers to work one week on stuff that we like.
Not on the stuff that our boss (or marketing, or the sales people or whoever) likes.
This was a pretty neat idea. They topped it off by taking care of everything: we had a nice brunch every morning, during the days we were served various refreshments and the evenings were rounded off with a nice meal, too. Sometimes it was hard to get to hacking, besides all that food ;-)

I mostly finished off one of my pet projects from the last months, porting the neutrino GUI to the dreambox, which is now committed to the project’s cvs and, save some minor cleanups, should be pretty much ready to use.

Some links:

  • My idea.opensuse.org project page (not much to see there)
  • The tuxbox project
  • The tuxbox project webforum (mostly german)