Monday, September 22, 2014

Lush theme for Emacs24

I've been using a custom color theme for Emacs for a long time now. Recently, I streamlined it a bit and made it ready for Emacs24.

I've also registered it with the awesome MELPA, which is an elegant package archive for Emacs24. You can find and install it under lush-theme.

Instructions on how to manually install it can also be found on the lush-theme Github page.

Following are two screenshots of the theme for Ruby and C.


Wednesday, April 23, 2014

Linux: Quick and easy way to realize device attributes with dev_groups

  • Come up with a name for your device attribute. I'll use foo.
  • Attributes can be read only, write only, or read/write. Create corresponding functions for the attribute with _show and _store following your attribute name:
static ssize_t foo_show(struct device *dev,
                        struct device_attribute *attr,
                        char *buf)
{
    return scnprintf(buf, PAGE_SIZE, "Hello attribute!\n");
}

static ssize_t foo_store(struct device *dev,
                         struct device_attribute *attr,
                         const char *buf, size_t count)
{
    dev_info(dev, "I got %s\n", buf);
    return count;
}


  • Create a struct device_attribute with the DEVICE_ATTR_ macros for each of your attributes. You can decide between RW, RO, WO versions.
static DEVICE_ATTR_RW(foo);
static DEVICE_ATTR_WO(wo_attr);


If you look at the expansion of the DEVICE_ATTR_RW macro, and the macros used inside the macro, you can see that DEVICE_ATTR_RW(foo) finally expands to:
struct device_attribute dev_attr_foo =
    {.attr  = {.name = __stringify(foo),
               .mode = (S_IWUSR | S_IRUGO)},
     .show  = foo_show,
     .store = foo_store,}


  • With the macro-created name for your attribute in mind, create a struct attribute:
static struct attribute *tutorial_attrs[] = {
 &dev_attr_foo.attr,
 &dev_attr_wo_attr.attr,
 NULL,
};


  • Finally, use the ATTRIBUTE_GROUPS macro to create a struct attribute_group:
ATTRIBUTE_GROUPS(tutorial);


This macro finally gives you a struct attribute_group *tutorial_groups[] which houses your tutorial_attrs[]. You can then use it to register your device attributes, e.g. with dev_groups of struct class.
example_class = class_create(THIS_MODULE, "example");
example_class->dev_groups = tutorial_groups;


All steps combined:
static ssize_t foo_show(struct device *dev,
                        struct device_attribute *attr,
                        char *buf)
{
    return scnprintf(buf, PAGE_SIZE, "Hello attribute!\n");
}

static ssize_t foo_store(struct device *dev,
                         struct device_attribute *attr,
                         const char *buf, size_t count)
{
    dev_info(dev, "I got %s\n", buf);
    return count;
}

static DEVICE_ATTR_RW(foo);

static struct attribute *tutorial_attrs[] = {
 &dev_attr_foo.attr,
 NULL,
};

ATTRIBUTE_GROUPS(tutorial);

Saturday, April 19, 2014

Block/get rid of "The disk you inserted was not readable by this computer" messages in Mac OS X

If your Mac OS X box has volumes that OS X does not recognise, e.g. Linux volumes partitioned with ext4, you will be bugged with a popup stating "The disk you inserted was not readable by this computer" on every boot. This can get quite annoying.




Unfortunately, OS X doesn't read volume names of some (all?) ext4 volumes, nor does it recognise their UUIDs, which makes it impossible to use /etc/fstab to block the volumes.

However, I found a github project that realises a daemon that registers a callback to OS X' disk arbitration framework in order to block volumes by their names, with a list of names supplied by the user.
It is not quite what I needed, so I forked the project and changed it such that it blocks volumes by their BSD disk name, which relives you from the annoying popup.

You see these names when executing diskutil list in a terminal, e.g. disk2s2.

Get your diskejectd copy from github. Howto/installation is supplied in the readme!

Monday, April 7, 2014

Fixing the Mad Catz R.A.T 7 mouse under openSUSE / Linux

There are quite some tutorials available for fixing the Mad Catz R.A.T. 7 mouse under Ubuntu or other Linux flavors, but I found none of them to be updated for recent distros like openSUSE 13.1 which don't have a xorg.conf anymore.

Also, different pages suggest different button mappings for the xorg Section descriptor. Most of them fix the urgent issues like the "stuck in a window" effect or similar ones that "freeze" the desktop, but with some, the back and forward buttons did not work in Firefox or Chrome/Chromium.

Here is how I got the mouse working as expected (side scrolling works too!):
  1. Create the file /etc/X11/xorg.conf.d/50-rat7.conf as root or via sudo (under Ubuntu, the path is /usr/share/X11/xorg.conf.d).
  2. Copy the following into the file.
  3. Reboot (or kill your X session / restart your login manager).
Section "InputClass"
        Identifier "Mad Catz Inc. R.A.T. 7"
        MatchProduct "Mad Catz Mad Catz R.A.T.7 Mouse"
        MatchIsPointer "true"
        MatchDevicePath "/dev/input/event*"
        Driver "evdev"
        Option "Buttons" "17"
        Option "ButtonMapping" "1 2 3 4 5 0 0 8 9 7 6 12 0 0 0 16 17"
        Option "ZAxisMapping" "4 5 6 7"
EndSection

If you bought your R.A.T. 7 when it was sold under the Saitek label, exchange MatchProduct with:
MatchProduct "Saitek Cyborg R.A.T.7 Mouse"

If your are not sure which one you got, you can utilize the lsusb tool and look for "Mad Catz" or "Saitek":
root@linux:~> lsusb
...
Bus 003 Device 003: ID 0738:1708 Mad Catz, Inc.
...

How to fix Ubuntu VMs hanging at boot in KVM / virt-manager

I have a Ubuntu 13.04 box which I use as a KVM host for several virtual machines. Using virt-manager, you can easily install 13.04 VMs without any difficulties, until you reboot the VM after installation.
In my setup, the VMs will hang up every time, the last thing visible in the boot console being the fsck utility.

I found out that you can fix this issue by changing the video adapter type for the VM. The default adapter is set to cirrus. Changing it to qxl or vga solved the problem for me.


I did not investigate further why this bug happens. qxl apparently has more video ram which might be a clue, but vga does not and it also works.

Wednesday, March 26, 2014

Nintendo DS Savegame read out/backup with an Arduino

Recently, I've used my Arduino Due to build a device for reading out my Nintendo DS save games. They are stored in raw format to your PC. The sources can be found on Github.

Read out a Nintendo DS savegame with an Arduino

All in all it was no difficult task, because inside the NDS cartridges, the save games are stored onto EEPROMs that use the SPI protocol.
All the necessary SPI pins are directly exposed via the pins of the NDS cartridge:

__________________   ___
|                  |_|   \
|                       __|
|                     17__| GND
|                     16__| MOSI
|                     15__| MISO
|                     14__| 
|                     13__| 
|                     12__| 
|                     11__|
|                     10__| 
|                      9__| 
|                      8__| 3,3V
|                      7__| 
|                      6__| EEPROM CS   (active low)
|                      5__| RESET       (active low, connect to 3,3V!)
|                      4__| GAME ROM CS (active low, connect to 3,3V!)
|                      3__| 
|                      2__| SCLK
|                      1_>| GND
|_________________________|

To connect the cartridge to the Arduino, I've bought a cheap cartridge slot replacement. You find plenty on Amazon, for example.

After connecting the NDS pins to a breadboard, voltage level conversion is needed, because the NDS EEPROMs operate on 3,3V.
On the Arduino Due, the SPI CS pins are already 3,3V, but MOSI, MISO and SCLK are 5V (I know, this mix up makes no sense at all, don't ask me...) and therefore need level shifting.
On other Arduinos than the Due, everything including CS is 5V.
I first tried it with a common level shifter circuit from adafruit that I had laying around, but it was not working for me. I am not 100% sure what the problem was, but what I saw from my logic analyzer makes me suspect the auto sensing of the level shifter was behaving in a confused manner.
Eventually, I went back to classical voltage dividers for MOSI and SCLK (sparkfun has a calculator). For MISO, I directly connected it to the Due and it turned out that the 3,3V suffice to be detected by the Due's processor.
Also make sure to connect the RESET and GAME ROM CS pins to 3,3V as indicated above!

I checked two of my NDS games and found ST Micro M45PExx and Sanyo LE25FW series EEPROMs, respectively. Both are 4MBit in size and use the same protocols. You can read from it by sending an opcode (0x03) followed by a 3 byte address. If you keep CS low afterwards, the EEPROM shifts out consecutive bytes, aka auto increments the address you read from, which makes the the read out sketch for the Arduino conveniently small.
I wrote a C program that talks to the Arduino over the programming cable and reads out a user supplied number of bytes from the EEPROM and stores it in raw format to your PC.
The sketch should work for most Arduinos, the C program works for Linux and Mac OS X.

You can find both with further instructions on Github.

Tuesday, March 18, 2014

Howto: Set MAC Address of SR-IOV Virtual Function

At least for Intel NICs, the MAC addresses for SR-IOV virtual functions are randomly generated when bringing up VFs. This is not useful for environments where you need fixed MACs, e.g. for the DHCP to give you a proper IP. However, the MACs can be changed with the ip tool.

Viewing the currently assigned MACs can be done via:
root@linux:~# ip link show eth0
2: eth0: <no-carrier> mtu 1500 qdisc mq state DOWN mode ...
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    vf 0 MAC xx:xx:xx:xx:xx:xx, spoof checking on
    vf 1 MAC xx:xx:xx:xx:xx:xx, spoof checking on

To change the MAC address of a specific VF, just do:
ip link set eth0 vf 0 mac xx:xx:xx:xx:xx:xx
ip link set eth0 vf 1 mac yy:yy:yy:yy:yy:yy

In case you are running a newer kernel version, where the Intel NICs recommend using the sysfs interface for bringing up VFs, you can write a simple bash script that gets executed at bootup that does the whole configuration in one place.

You first need to find the PCI(e) BDF notation of your NIC's Physical Function. You can do it via lspci:
root@linux:~# lspci
...
07:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
07:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
...

Note your BDF and write a small script like the following:
#!/bin/bash

echo 2 > /sys/bus/pci/devices/0000\:07\:00.0/sriov_numvfs
ip link set eth0 vf 0 mac xx:xx:xx:xx:xx:xx
ip link set eth0 vf 1 mac yy:yy:yy:yy:yy:yy

Finally, make sure that you script executes on every boot. How this can be done depends on the flavor of Linux/Unix you are using. Some good options are explained here.