Building my own XPud

Jan Newmarch, jan@newmarch,name, http://jan.newmarch.name

Motivation

I want a 10 foot GUI with two features:

Why is it so hard to find?

There are many distros that will do one or even two of those three demands, but none I found would do all three, till I came across XPud. So close...

But it needed some work for my environment. Specifically:

Essentially, want I want could be termed a micro-distro - a distro configured to my needs! This article goes through what I had to do to tune xPUD to my system. I chose xPUD as it's GUI was closest to what I wanted out of all the distros I have looked at.

Config file

You need to install xPUD and build it. Follow the instructions at http://wiki.github.com/penk/mkxpud (copied to the end of this article).

After that, to customise it you need to build your own configuration file. These files exist in mkxpud/config in your distro. Copy the default.cookbook to, say, myxpud.cookbook and start editing.

To build, just change the line

./tools/mkxpud all
to
./tools/mkxpud all myxpud

Development environment

You can build xPUD on one machine, install it on a USB stick, reboot your target environment, and repeat ... and ... waste a lot of time... Some of this cannot be avoided, especially if your target has specific hardware requirements. So to ensure my wireless card was supported, I had to do this cycle.

But for many software only issues, it is much faster in the long run to use a virtualised environment. I use VirtualBox, but other virtual systems such as VmWare are just as good. Install the virtual sytstem, set up an xPUD virtual machine booting off an ISO file. Then each time you rebuild the ISO, you just start the xPUD virtual machine again and test it. Is it heavy on resources? Not particularly: on a netbook running Ubuntu with 2Gb RAM I have run 3 simultaneous Linux virtual machines quite comfortably - Windows is a drain on resources, though.

Modules

xPUD comes with a minimal set of modules. My xPUD host is an HP thin client without wireless. So I use a Linksys USB wireless card. This card is supported by a full distro such as Ubuntu, but not xPUD.

xPUD can download a file of lots of drivers, but this bumps up the size of xPUD. I thought I would try the minimal version...

So I boot the HP machine from a full distro and use lsmod to see what modules are needed. This is messy: you need to get all of the modules and their parents. The xPUD code should be able to pick up the dependencies, but currently doesn't. So I got a list, rebuilt xPUD and tried it. When it didn't work, I rebooted into Ubuntu to see what I had missed, added modules to xPUD, rebuilt it, etc.

Adding modules statically to xPUD is done by editing your own config file. In the config file is a section named [module]. Add your own modules to the list of modules. In my case, I had to add the line

lib80211 input-polldev led_class cfg80211 mac80211 rt2x00lib rt2x00usb rt2500usb
for my rt2500usb wireless device. Ideally, it should just need the rt2500usb entry and pick up the rest.

Samba

I have a (Linux) server which delivers SAMBA shares. I want these to be visible to my xPUD client. The first point is that the cifs module is not included in xPUD. This can be fixed as above by adding a line containing cifs to the [module] section of your configuration file.

This ensures that the module's .ko file is present in the xPUD file system. But it doesn't load it, and running the mount command doesn't force it to load either. So we have to force loading of the cifs module.

The file /usr/share/plate/chrome/content/plate.js loads the usual UI. This contains a call to /usr/local/bin/post-boot.sh, and at the end of that shell script, all the of the files in /etc/post-boot.d are executed. So we create a file in that directory with a name such as 10cifs with contents

modprobe cifs
(Better might be to put cifs in a file such as /etc/modules but that isn't supported yet.).

So how do we add a file to the distro? In the configuration file is a section labelled [action]. Add the following to that section:

echo 'modprobe cifs' >> working/mykarmic/rootfs/etc/post-boot.d/10cifs;
chmod a+x working/mykarmic/rootfs/etc/post-boot.d/10cifs
which creates a new executable file in the working directory used in the file system build process. This will become part of the compressed file system on the ISO image, and will be executed as the UI is initialised, after booting is completed.

At this stage, we can't mount the SAMBA share unfortunately: the network connection might not have been established. In my case, I need to set a wireless SSID password.

Setting up fstab

There are several ways of accessing SAMBA shares from Linux. I decided to put an entry in /etc/fstab. The entry is

//192.168.1.4/HTML /server cifs username=<uid>,password=<password> 0 0
This mounts the SAMBA share HTML from host 192.168.1.4 into the /server directory.

Unfortunately I can't put a line echo '//192.168.1.4/HTML /server cifs username=<uid>,password=<password> 0 0' into the action section of my configuration file - the presence of '=' signs breaks the script (tools/parser) that reads the configuration file. There is a bug in the parser that needs to be fixed.

The workaround is to create my own file fstab and in the action section just copy it to the right location. The right location to copy to is working/mykarmic/rootfs/etc/fstab.

Configuring wireless

Under the xPUD Settings menu is a means of choosing the wireless network to connect to, including setting the password for a protected network. This setting is lost on each reboot. At any stage, information about wireless networks is stored by xPUD in /tmp/wifi.opt and /tmp/wifi.dev. This information is established by /usr/local/bin/post-boot.sh.

I know my wireless SSID and the (WEP) password required. The simplest for me is to add an iwconfig command to the actions section of my configuration file:

echo 'iwconfig wlan0 essid XXX key XXX' >> working/mykarmic/rootfs/etc/post-boot.d/20wireless;
(The command /usr/local/bin/get_wifi could also be used.).

After connecting to my wireless network, I can mount the SAMBA shares. But when does that occur? There is a hook directory /etc/dhcp3/dhclient-exit-hooks.d. Any file in there is executed when there is a change of DHCP state. The file I copy into working/mykarmic/rootfs/etc/dhcp3/dhclient-exit-hooks.d contains

if [ ${reason} = "BOUND" ]
then
    modprobe cifs
    mount /server
fi

Fixing mplayer

My server delivers playlists in .m3u format. mplayer can only handle these by using the option -playlist. In my setup, I use the browser to get to my music files. Clicking on "Play all" sends the m3u file to the browser to handle. The browser looks up the command in /etc/mozpluggerrc, but this is not correct for m3u files. The relevant section in that file is

audio/mpeg-url:m3u:MPEG music resource locator
audio/x-mpeg-url:m3u:MPEG music resource locator
audio/mpegurl:m3u:MPEG music resource locator
audio/x-mpegurl:m3u:MPEG music resource locator
audio/x-scpls:pls:Shoutcast Playlists
#       controls: mpg321 -q -@ "$file"
        nokill noisy : xmms -e -p "$file"

I copied the mozpluggerrc file. Using bug 168354 at Gentoo bug 168354 I edited it to

audio/mpeg-url:m3u:MPEG music resource locator
audio/x-mpeg-url:m3u:MPEG music resource locator
audio/mpegurl:m3u:MPEG music resource locator
audio/x-mpegurl:m3u:MPEG music resource locator
audio/x-scpls:pls:Shoutcast Playlists
#       controls: mpg321 -q -@ "$file"
#       nokill noisy : xmms -e -p "$file"
        controls: mplayer -playlist "$file"
Then in the action section I copy my file over the one in /etc.

Note that you must copy the mozpluggerrc from the distro (working/mykarmic/rootfs/etc) not from /etc - that file has different contents and will cause you problems if you try to use it in your distro.

Fixing sound

My HP thin client has an internal sound card, but a pathetic internal speaker. Anyway, I want to pump all sound through my stereo system. There is a headphone output, but xPUD doesn't turn it on. Again, the actions section of my configuration to the rescue.

echo '/usr/bin/amixer set Headphone 100% on' >> working/mykarmic/rootfs/etc/post-boot.d/30sound;

Final configuration file

The changes to xPUD consisted of setting up my own configuration file and making changes to it. In summary, they consist of

Building a USB stick using unetbootin

unetbootin can be used to install xPUD on a USB stick. But it won't boot. The file /syslinux.cfg on the stick needs to be edited. Change all occurrences of append initrd=/ubninit to append initrd=/opt/core,/opt/media

Customising xPUD

See also CustomizeXPUDLive

Build xPUD with mkxpud

This is copied. It didn't work too well for me

Quick Start

  1. Check out the latest source code:
    	   git clone git://github.com/penk/mkxpud.git    
    	 
  2. Build the rootfs and generate the image:
    	   ./tools/mkxpud all    
    	 
  3. Test your result:
    	   ./tools/mkxpud test    
    	 
This will create an iso9669 image at deploy/default.iso.

Build xPUD with mkxpud

This is also copied. It worked pretty good for me

This is a brief how-to on building xPUD with Ubuntu 9.10 (karmic koala). From http://wiki.github.com/penk/mkxpud

Download Rootfs and Modules

$ wget http://download.xpud.org/devel/karmic-rootfs.tgz
$ mkdir karmic-xpud
$ sudo tar zxvf karmic-rootfs.tgz -C karmic-xpud/
    

Internet connection inside build system

$ sudo chroot karmic-xpud/rootfs/ mkdir -p /proc/net/dev/
$ sudo chroot karmic-xpud/rootfs/ dhclient    
    

Upgrade and Setting

$ sudo cp /etc/hosts karmic-xpud/rootfs/etc/hosts
$ sudo chroot karmic-xpud/rootfs/ apt-get update
$ sudo chroot karmic-xpud/rootfs/ apt-get upgrade    
    

Export mkxpud from Repository

$ sudo git clone git://github.com/penk/mkxpud.git karmic-xpud/rootfs/mkxpud
$ find karmic-xpud/rootfs/mkxpud -name .git* -exec sudo rm -rf {} \;      
    

Build the xPUD Rootfs

$ sudo chroot karmic-xpud/rootfs/
$ cd mkxpud/
$ ./tools/mkxpud all      
    
That's it, the default cookbook will work. :-)