Tuesday, August 12, 2014

Controlling USB device access on Linux (e.g. BADusb defense)

So, there was a lot of fuzz about a recent talk by Karsten Nohl et al. at BlackHat about the the unsecurity of current USB implementations (on the computer side) which happily load drivers for all kinds of devices as soon as a (potentially malicious) USB stick is connected.

I completely agree that, as shipped, most computer systems will be susceptible to this attack, and assume that all of their attacks will work as advertised. What I don't agree with at all is their conclusion, which boils down that no effective defenses exist.

While I haven't made my homework to develop a defense, I want to at least show the mechanism in current Linux kernels to limit binding of potentially dangerous drivers to specific devices, so that e.g. a inserted USB-stick would only be mounted as a block device, and its malicious keyboard interface be ignored.

Binding of Drivers

A linux-module can claim ownership of certain usb vendor/device ids or device classes. Those are visible when looking at the modinfo of a kernel module, to facilitate autoloading of modules, but are also registered in internal kernel structures, so that drivers compiled in statically directly can be mated with the proper devices:

$ modinfo snd-usb-audio
filename:       /lib/modules/3.15.8-1-ARCH/kernel/sound/usb/snd-usb-audio.ko.gz
license:        GPL
description:    USB Audio
author:         Takashi Iwai
alias:          usb:v*p*d*dc*dsc*dp*ic01isc01ip*in*
alias:          usb:v0D8Cp0103d*dc*dsc*dp*ic*isc*ip*in*
alias:          usb:v*p*d*dc*dsc*dp*ic01isc03ip*in*
alias:          usb:v200Cp100Bd*dc*dsc*dp*ic*isc*ip*in*
(...)
This information currently comes from the MODULE_DEVICE_TABLE of sound/usb/card.c, stored in an array called usb_audio_ids. The bold one is the "default class", the others all are included in the "quirks table", which includes all exceptions from the default class.
static struct usb_device_id usb_audio_ids [] = {
#include "quirks-table.h"
     { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
       .bInterfaceClass = USB_CLASS_AUDIO,
       .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
     { }                                         /* Terminating entry */
 };
MODULE_DEVICE_TABLE(usb, usb_audio_ids);
On connection of a USB device, the kernel will look through all its currently registered modules that claim to support USB devices (by registering those tables with the kernel) and bind devices to drivers (and if it doesn't succeed, it will call udev/hotplug to load a module that does). 

The Vulnerability

So, if you connect a particular USB headset, the electronics of which I have laying around... you get a new sound device in ALSA...
[root@optiplex devices]# aplay -l
**** List of PLAYBACK Hardware Devices ****
(...)
card 1: Headset [Logitech USB Headset], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
But also a new keyboard! (the mute/volume buttons on the headset, but those could be arbitrary buttons entering text, too).
[root@optiplex devices]# xinput
⎡ Virtual core pointer                     id=2 [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer               id=4 [slave  pointer  (2)]
⎜   ↳ Logitech USB-PS/2 Optical Mouse         id=8 [slave  pointer  (2)]
⎣ Virtual core keyboard                   id=3 [master keyboard (2)]
    ↳ Virtual core XTEST keyboard             id=5 [slave  keyboard (3)]
    ↳ Power Button                             id=6 [slave  keyboard (3)]
    ↳ Power Button                             id=7 [slave  keyboard (3)]
    ↳ Das Keyboard                             id=9 [slave  keyboard (3)]
    ↳ Logitech Logitech USB Headset           id=10 [slave  keyboard (3)]
If you look in the sysfs filesystem, you can see, that the USB headset (usb device 5-1) has 4 distinct functions (.0 -- .3) on configuration :1.
[root@optiplex /sys/bus/usb/devices/5-1]# ls
5-1:1.0     bcdDevice    maxchild
5-1:1.1     bmAttributes   port
5-1:1.2     busnum    power
5-1:1.3     configuration  product
authorized     descriptors    quirks
avoid_reset_quirk    dev    removable
bConfigurationValue  devnum    remove
bDeviceClass     devpath    speed
bDeviceProtocol      driver    subsystem
bDeviceSubClass      ep_00    uevent
bMaxPacketSize0      idProduct    urbnum
bMaxPower     idVendor    version
bNumConfigurations   ltm_capable
bNumInterfaces     manufacturer
And those are described by the (very lengthy) lsusb -v output, which I'll not reproduce completely here, just try it for yourself on any USB device.

Bus 005 Device 006: ID 046d:0a0b Logitech, Inc. ClearChat Pro USB
Device Descriptor:
 (...)
  bNumConfigurations      1
  Configuration Descriptor: (configuration #1 starts here)
    bLength                 9
(...)
    Interface Descriptor: (interface 1:0)
(...)
       bDescriptorType         4
       bInterfaceNumber        0
(...)

    bInterfaceClass         1 Audio
      bInterfaceSubClass      1 Control Device
(...)
      AudioControl Interface Descriptor: (detailed info about audio capabilities)
        bLength                10
(...)
    Interface Descriptor: (interface 1:3)
      bInterfaceNumber        3
(...)
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 

So, here you have it, one device that (legitimately) is both a soundcard and a keyboard/mouse (e.g. an human interface device). Given enough motiuvation, code could be written for the controller inside the soundcard that enters arbitary text to my computer. And that's basically the vulnerability presented in the Black Hat Presentation by Nohl et al.

Defense

But, you can easily turn off this automatic binding, at least on Linux, with one single command:
[root@optiplex ~]# echo 0 >/sys/bus/usb/drivers_autoprobe 
Now, whenever you connect a USB device to your computer, it will not automatically connect the usb-soundcard to the ALSA subsystem and the volume buttons to the hidraw/keyboard driver. If I now connect the aforementioned soundcard, I'll not get a new keyboard in xinput, nor a soundcard in ALSA (and also not a network- or block-device for a network card or USB disk).

The only thing I'll get in my dmesg is the message, that an USB device has been connected:
[13399.092113] usb 5-1: USB disconnect, device number 6
[13405.245389] usb 5-1: new full-speed USB device number 7 using uhci_hcd
And to manually bind this device, you first have to choose the appropriate USB configuration...
# echo 1 >/sys/bus/usb/devices/5-1/bConfigurationValue 
...and tell the usb audio driver to bind to that device.
# echo 5-1:1.0 >/sys/bus/usb/drivers/snd-usb-audio/bind
Now you have the USB audio interface, but not the keyboard, yet... If you wanted, you'd just bind usb-hid to interface 3.
# echo 5-1:1.3 >/sys/bus/usb/drivers/usbhid/bind 
To verify that your keyboard presses aren't registed from the connected device before, and are registered after binding, you can run "xev" and press the volume buttons (note: those, in principle, could enter arbitrary text to your computer, depending on the programming of the controller in the device).
KeyRelease event, serial 38, synthetic NO, window 0x3800001,
    root 0x1dc, subw 0x3800002, time 13880057, (41,58), root:(2384,618),
    state 0x10, keycode 123 (keysym 0x1008ff13, XF86AudioRaiseVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False
The most often quoted use-case if obviously connection of a usb-storage device, e.g. an external harddrive or flash-stick.

[14567.888596] usb 6-1: new high-speed USB device number 4 using ehci-pci
# echo 1 >/sys/bus/usb/devices/6-1/bConfigurationValue
# echo 6-1:1.0 >/sys/bus/usb/drivers/usb-storage/bind
[14667.692717] usb-storage 6-1:1.0: USB Mass Storage device detected
[14667.692936] scsi7 : usb-storage 6-1:1.0
[14668.696482] scsi 7:0:0:0: Direct-Access     TOSHIBA  MK4309MAT        G5.0 PQ: 0 ANSI: 0 CCS
[14668.698461] sd 7:0:0:0: [sdd] 8452080 512-byte logical blocks: (4.32 GB/4.02 GiB)
(yes, it's a very, very crappy and old USB harddisk)

Proper user-interface, current lack thereof.

To convert all this sysfs poking into a proper user-friendly software, one will have to...

  • On computer startup, disable  autoprobe (probably there's a kernel command line for that).
  • Statically configure the minimal interfaces used (e.g. the main usb keyboard, trackpad/mouse, ...).
  • During normal operation, watch hotplug-events or poll the sysfs filesystem for newly inserted usb devices.
  • Verify presented configurations of USB devices and their interfaces with a policy (e.g. enable only usb-storage devices, e.g. "thumbdrivers"
  • Ask the user, if he's happy with this device.
  • On successful verification, only bind the single necessary driver (e.g. usb-storage) to the proper interface of the device.

Of course, for certain devices more sophisticated verification schemes could be envisioned, checking certificates, downloading firmware for verification (which, again, might be forged, ...).

The "Authorized" Mechanism

There's a second mechanism to disable/enable communication with USB device using the "authorized" property of USB controllers. It's described in the kernel documentation.

Windows...

There seems to be a group policy for that... Local Computer PolicyComputer Configuration,Administrative TemplatesSystemDevice Installation, and Device Installation Restrictions

Monday, March 24, 2014

Stairville DJ-X 16, voided my warranty

The DJ-X 16 is a very basic DMX controller, which I used to test out DMX controlled (d'uh...) LED lights. I cannot recommend it, it lacks a lot of features, and the buttons/faders have a very flimsy feeling. Nevertheless: Because I was pondering if it was worthwhile to modify its firmware, I decided to void the warranty (yeah!) and here are few pictures documenting the insides of this device.

What I found pretty interesting is the fact that, even though I bought it new only a few months ago, and it's still being manufactured exactly like that, it uses pretty antique components, and is an all-through-hole PCB, not a single SMD to be found.

The main controller is a Atmel AT89C55WD, a 8051 compatible 8-bit microcontroller. It's meagre 256 bytes of internal RAM is extended by 8k of High-Speed (120ns...) SRAM. A 29EE010 EEPROM takes care of the 8051's lack of long-term memory. Everything else is 80s-style design, with a lot of 47hc's.

There's a second, smaller, PCB which is home of the SN57176 RS485 driver/receiver, an optocoupler (MIDI out/through), connectors and a 7805 voltage regulator. The flat-ribbon cable connecting this connection-PCB to the main board is nicely labeled on the silkscreen, very convenient.

K1    1   2  COM
K2    3   4  Audio2
K3    5   6  Audio1
k5    7   8  MIDI in
+5V   9  10  +5V
NC    11 12  MIDI through
GND   13 14  GND
+5V   15 16  +5V
NC    17 18  DMX out
+12V  19 20  +12V

From Chris’ Miscellanea

From Chris’ Miscellanea

From Chris’ Miscellanea

Sunday, March 09, 2014

Playing with a AM2302 Temperature/Humidity Sensor & LUFA

I played around with a Adsong AM2302 Temperature/Humidity sensor today which has a pretty neat serial interface.

From Chris’ Miscellanea

I wrote some code to read in the data using the input-capture mode of the Timer/Counter1 in a AVR ATmega32u4 (way overpowered, but it's handy on a Olimexino 32U4 board) to learn about using the LUFA USB library a little, maybe someone can put it to actual use?

$ cu -l ttyACM0
Connected.
Triggering conversion.
AS2302 raw bytes: recv cnt=0 01 76 00 fa 71

status: 0, temp=250 (*0.1 dC), rh=374 (*0.1%)

Thursday, March 06, 2014

Get /dev/spidev on an Raspberrypi running under Archlinux ARM working again.

Currently, when running a raspberry-pi with the latest kernel available for Archlinux, access to the SPI bus via /dev/spidev no longer works. Bugs have been filed, but apparently the late-binding logic available via spi_register_board_info just seems to be broken right now.

I've written a small kernel module that doesn't fix the initial bug, but just does the binding of spidev to the first two chipselects of the first spi master. It's available on github.


$ ls -la /dev/spidev*
zsh: no matches found: /dev/spidev*

$ sudo insmod rpi_add_spidev_module/rpi_add_spidev_module.ko 

$ dmesg
(...)
[  245.299487] spi_master spi0: ...is the master for device #0.
[  245.299709] spi spi0.0: ...is the device #0.
[  245.299734] spi_master spi0: ...is the master for device #1.
[  245.304763] spi spi0.1: ...is the device #1.

$ ls -la /dev/spidev0.*
crw------- 1 root root 153, 0 Mar  6 16:47 /dev/spidev0.0
crw------- 1 root root 153, 1 Mar  6 16:47 /dev/spidev0.1

# cd /sys/bus/spi/drivers/spidev
# ls -l
total 0
--w------- 1 root root 4096 Jan  1 00:03 bind
lrwxrwxrwx 1 root root    0 Jan  1 00:02 module -> ../../../../module/spidev
lrwxrwxrwx 1 root root    0 Jan  1 00:03 spi0.0 -> ../../../../devices/platform/bcm2708_spi.0/spi_master/spi0/spi0.0
lrwxrwxrwx 1 root root    0 Jan  1 00:02 spi0.1 -> ../../../../devices/platform/bcm2708_spi.0/spi_master/spi0/spi0.1
--w------- 1 root root 4096 Jan  1 00:00 uevent
--w------- 1 root root 4096 Jan  1 00:02 unbind

Using software to talk to a proprietary SPI gyro/accelerometer module works again.

$ sudo ./rpi_gyro /dev/null  
Opened gpio25 direction as fd 5.
Opened gpio25 value as fd 6.
Opened /dev/spidev0.0 as fd 7 (0x03, 8, 0).
Opened /dev/spidev0.1 as fd 8 (0x03, 8, 0).
lsm330dlc_dump_regs: dumping accelerometer registers.
$00: $00 $00 $00 $00   $00 $00 $00 $ff
$08: $00 $00 $00 $00   $00 $00 $00 $33
$10: $86 $16 $a6 $26   $48 $25 $21 $1e
$18: $1b $a3 $50 $65   $c0 $00 $50 $00
$20: $27 $00 $00 $80   $40 $00 $00 $ff
$28: $00 $2d $c0 $01   $40 $27 $80 $9e
$30: $00 $00 $00 $00   $00 $00 $00 $00
$38: $00 $00 $00 $00   $00 $00 $00 $00
lsm330dlc_dump_regs: dumping gyro registers.
$00: $d3 $66 $a8 $cc   $4d $d0 $11 $f1
$08: $20 $06 $ff $18   $02 $83 $00 $d3
$10: $90 $2b $19 $44   $0c $e0 $61 $60
(...)

Sunday, February 09, 2014

Riso Kagaku Corp Webmail Notifier Redux: Kernel Module Cleanup

Trying to clean up this code, so that it's usable without too much friction...

I put up my slightly modified version of the usbled.c kernel module on github. It includes support for one of the cheapest incarnation of USB-led devices, the Riso Kagaku Corp. Webmail Notifier. It can now be built out-of-tree easily (trying to forward to the kernel guys to merge it eventually) and includes udev rules and a script to automate the re-binding of device from usbhid to the usbled driver).

Movie hosted by instagram:



Friday, October 25, 2013

DeLock 61114 uses a NEC Corporation uPD72873 (µPD72873) Chipset (Cardbus Firewire Interface)

I got myself a Cardbus FireWire card, namely a DeLock 61114. As it's always very hard to find the Chipset used for a particular card, I'd want to post it here, so that it may be found by neighbors also interested in this information.

→ DeLock 61114 uses a NEC Corporation (Renesas) uPD72873 (µPD72873) with vid 0x1033 and pid 0x00e7 [1033:00e7].

If you want to use the card for Audio applications I can attest that it does not work at all with either an Echo AudioFire 4 and a Focusrite Saffire Pro 26 I/O with ffado/jackd under Linux, which is not surprising as the NEC chipset if often classified as "problematic". I bought it for a different purpose and did not know the chipset in advanced, let's hope it will turn out to be usable.

lspci -tv

-[0000:00]-+-00.0  Intel Corporation Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller
(...)
           +-1e.0-[02-06]--+-[0000:03]---00.0  NEC Corporation uPD72873 [Firewarden] IEEE1394a OHCI 1.1 Link/2-port PHY Controller

lspci -v

$ sudo lspci -s 03:00.0 -v -v -nn
03:00.0 FireWire (IEEE 1394) [0c00]: NEC Corporation uPD72873 [Firewarden] IEEE1394a OHCI 1.1 Link/2-port PHY Controller [1033:00e7] (rev 01) (prog-if 10 [OHCI])
Subsystem: NEC Corporation uPD72873 [Firewarden] IEEE1394a OHCI 1.1 Link/2-port PHY Controller [1033:00e7]
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- SERR- Latency: 64 (5000ns min, 11000ns max), Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 19
Region 0: Memory at 8c000000 (32-bit, non-prefetchable) [size=4K]
Region 1: Memory at 8c001000 (32-bit, non-prefetchable) [size=256]
Region 2: Memory at 8c001100 (32-bit, non-prefetchable) [size=256]
Capabilities: [60] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME+
Kernel driver in use: firewire_ohci
Kernel modules: firewire_ohci

dmesg on insert

[ 4893.716245] pcmcia_socket pcmcia_socket0: pccard: CardBus card inserted into slot 0
[ 4893.716285] pci 0000:03:00.0: [1033:00e7] type 00 class 0x0c0010
[ 4893.716330] pci 0000:03:00.0: reg 0x10: [mem 0x00000000-0x00000fff]
[ 4893.716353] pci 0000:03:00.0: reg 0x14: [mem 0x00000000-0x000000ff]
[ 4893.716377] pci 0000:03:00.0: reg 0x18: [mem 0x00000000-0x000000ff]
[ 4893.716504] pci 0000:03:00.0: supports D1 D2
[ 4893.716511] pci 0000:03:00.0: PME# supported from D0 D1 D2 D3hot
[ 4893.716732] pci 0000:03:00.0: BAR 0: assigned [mem 0x8c000000-0x8c000fff]
[ 4893.716747] pci 0000:03:00.0: BAR 1: assigned [mem 0x8c001000-0x8c0010ff]
[ 4893.716760] pci 0000:03:00.0: BAR 2: assigned [mem 0x8c001100-0x8c0011ff]
[ 4893.716868] firewire_ohci 0000:03:00.0: enabling device (0000 -> 0002)
[ 4893.717115] firewire_ohci 0000:03:00.0: setting latency timer to 64
[ 4893.776285] firewire_ohci 0000:03:00.0: added OHCI v1.10 device as card 2, 4 IR + 4 IT contexts, quirks 0x1
[ 4894.276463] firewire_core 0000:03:00.0: created device fw0: GUID 00004c020001af59, S400

Platform for Test

Dell Latitude D410, Intel(R) Pentium(R) M processor 1.60GHz, 2 GByte RAM, Kernel 3.11.6-1-ARCH, Archlinux x86 (32bit)





$ ffado-diag 
FFADO diagnostic utility 2.1.0-Unversioned directory
============================
(C) 2008 Pieter Palmers
    2009-2010 Arnold Krille


=== CHECK ===
 Base system...
  kernel version............ 3.11.6-1-ARCH
    Preempt (low latency)... True
    RT patched.............. False
  old 1394 stack present.... False
  old 1394 stack loaded..... False
  old 1394 stack active..... False
  new 1394 stack present.... False
  new 1394 stack loaded..... True
  new 1394 stack active..... True
  /dev/raw1394 node present. False
  /dev/fw* permissions:
crw------- 1 root root 248, 0 Oct 25 20:08 /dev/fw0
  User IDs:
uid=1000(chris) gid=100(users) groups=100(users),4(adm),10(wheel),14(uucp),92(audio),190(systemd-journal)
 Prerequisites (dynamic at run-time)...
   gcc ............... gcc (GCC) 4.8.2
   g++ ............... g++ (GCC) 4.8.2
   PyQt4 (by pyuic4) . Python User Interface Compiler 4.10.3 for Qt version 4.8.5
   jackd ............. jackd version 0.121.3 tmpdir /dev/shm protocol 24
     path ............ /usr/bin/jackd
     flags ........... -ljack -lpthread -lrt 
   libraw1394 ........ 2.1.0
     flags ........... -lraw1394 
   libavc1394 ........ 0.5.4
     flags ........... -lavc1394 -lrom1394 -lraw1394 
   libiec61883 ....... 1.2.0
     flags ........... -liec61883 -lraw1394 
   libxml++-2.6 ...... 2.36.0
     flags ........... -I/usr/include/libxml++-2.6 -I/usr/lib/libxml++-2.6/include -I/usr/include/libxml2 -I/usr/include/glibmm-2.4 -I/usr/lib/glibmm-2.4/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/sigc++-2.0 -I/usr/lib/sigc++-2.0/include -lxml++-2.6 -lxml2 -lglibmm-2.4 -lgobject-2.0 -lglib-2.0 -lsigc-2.0 
   dbus-1 ............ 1.6.16
     flags ........... -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -ldbus-1 
 Prerequisites (static at compile-time)...
   gcc ............... gcc (GCC) 4.8.1 20130725 (prerelease)
   g++ ............... g++ (GCC) 4.8.1 20130725 (prerelease)
   PyQt4 (by pyuic4) . Python User Interface Compiler 4.10.3 for Qt version 4.8.5
   jackd ............. sh: jackd: command not found
     path ............ 
     flags ........... Package jack was not found in the pkg-config search path.
   libraw1394 ........ 2.1.0
     flags ........... -lraw1394 
   libavc1394 ........ 0.5.4
     flags ........... -lavc1394 -lrom1394 -lraw1394 
   libiec61883 ....... 1.2.0
     flags ........... -liec61883 -lraw1394 
   libxml++-2.6 ...... 2.36.0
     flags ........... -I/usr/include/libxml++-2.6 -I/usr/lib/libxml++-2.6/include -I/usr/include/libxml2 -I/usr/include/glibmm-2.4 -I/usr/lib/glibmm-2.4/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/sigc++-2.0 -I/usr/lib/sigc++-2.0/include -lxml++-2.6 -lxml2 -lglibmm-2.4 -lgobject-2.0 -lglib-2.0 -lsigc-2.0 
   dbus-1 ............ 1.6.14
     flags ........... -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -ldbus-1 
 uname -a...
   Linux latitude-d410 3.11.6-1-ARCH #1 SMP PREEMPT Sat Oct 19 00:29:46 CEST 2013 i686 GNU/Linux
 Hardware...
   Host controllers:
03:00.0 FireWire (IEEE 1394) [0c00]: NEC Corporation uPD72873 [Firewarden] IEEE1394a OHCI 1.1 Link/2-port PHY Controller [1033:00e7] (rev 01) (prog-if 10 [OHCI])
Subsystem: NEC Corporation uPD72873 [Firewarden] IEEE1394a OHCI 1.1 Link/2-port PHY Controller [1033:00e7]
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- SERR-
Latency: 64 (5000ns min, 11000ns max), Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 19
Region 0: Memory at 8c000000 (32-bit, non-prefetchable) [size=4K]
Region 1: Memory at 8c001000 (32-bit, non-prefetchable) [size=256]
Region 2: Memory at 8c001100 (32-bit, non-prefetchable) [size=256]
Capabilities:
Kernel driver in use: firewire_ohci
Kernel modules: firewire_ohci

   CPU info:
Architecture:          i686
CPU op-mode(s):        32-bit
Byte Order:            Little Endian
CPU(s):                1
On-line CPU(s) list:   0
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 13
Model name:            Intel(R) Pentium(R) M processor 1.60GHz
Stepping:              8
CPU MHz:               1600.000
BogoMIPS:              3193.49
 Configuration...
  IRQ information
Hardware Interrupts:
--------------------
 IRQ    0: PID:  None, count:           [906109], Sched None (priority None), drivers: ['timer']
 IRQ    1: PID:  None, count:            [10837], Sched None (priority None), drivers: ['i8042']
 IRQ    8: PID:  None, count:                [1], Sched None (priority None), drivers: ['rtc0']
 IRQ    9: PID:  None, count:                [1], Sched None (priority None), drivers: ['acpi']
 IRQ   12: PID:  None, count:              [755], Sched None (priority None), drivers: ['i8042']
 IRQ   14: PID:  None, count:           [112126], Sched None (priority None), drivers: ['ata_piix']
 IRQ   15: PID:  None, count:                [0], Sched None (priority None), drivers: ['ata_piix']
 IRQ   16: PID:  None, count:             [6925], Sched None (priority None), drivers: ['uhci_hcd:usb1', 'ehci_hcd:usb5', 'i915', 'snd_intel8x0']
 IRQ   17: PID:  None, count:           [608140], Sched None (priority None), drivers: ['uhci_hcd:usb2', 'b43']
 IRQ   18: PID:  None, count:                [0], Sched None (priority None), drivers: ['uhci_hcd:usb3']
 IRQ   19: PID:  None, count:            [47980], Sched None (priority None), drivers: ['uhci_hcd:usb4', 'yenta', 'firewire_ohci']

Software Interrupts:
--------------------


=== REPORT ===
FireWire kernel drivers:

The new FireWire kernel stack is loaded. 
If running a kernel earlier than 2.6.37 and problems are experienced, either 
try with the old Firewire kernel stack or upgrade to a newer kernel 
(preferrably 2.6.37 or later).

ffado output (on EchoFire 4)


05803339228: Warning (StreamProcessor.cpp)[1708] updateState: ignoring identity state update from/to ePS_Created
05803339616: Warning (StreamProcessor.cpp)[1708] updateState: ignoring identity state update from/to ePS_Created
05804389908: Warning (TimestampedBuffer.cpp)[ 251] calculateRate: (0x952cf08) rate ( 425.80881) more that 10% off nominal (rate= 512.00000, diff=      3406.470, update_period=8)
05804390013: Warning (TimestampedBuffer.cpp)[ 251] calculateRate: (0x952cf08) rate ( 422.66907) more that 10% off nominal (rate= 512.00000, diff=      3381.352, update_period=8)
05804397825: Warning (TimestampedBuffer.cpp)[ 251] calculateRate: (0x952cf08) rate ( 426.40921) more that 10% off nominal (rate= 512.00000, diff=      3411.274, update_period=8)
05804397982: Warning (TimestampedBuffer.cpp)[ 251] calculateRate: (0x952cf08) rate ( 422.66876) more that 10% off nominal (rate= 512.00000, diff=      3381.350, update_period=8)
05804405797: Warning (TimestampedBuffer.cpp)[ 251] calculateRate: (0x952cf08) rate ( 422.66907) more that 10% off nominal (rate= 512.00000, diff=      3381.352, update_period=8)
05804405903: Warning (TimestampedBuffer.cpp)[ 251] calculateRate: (0x952cf08) rate ( 424.58093) more that 10% off nominal (rate= 512.00000, diff=      3396.648, update_period=8)
(...)
05805685889: Warning (IsoHandlerManager.cpp)[ 292] Execute: Timeout while waiting for activity
05808703126: Fatal (IsoHandlerManager.cpp)[ 348] Execute: (0x95005f0, Transmit) Handler died: now: 1750DB1D, last: 134FD732, diff: 49202155 (max: 49152000)
05808703167: Warning (StreamProcessor.cpp)[ 173] handlerDied: Handler died for 0x952d360
jackd watchdog: timeout - killing jackd
no message buffer overruns

Sunday, October 20, 2013

Notes: More Toradex-T20 Stuff...

So, I've wasted (again) too much time on the Toradex T20 I've written about earlier. It was collecting dust all of the time, but it's actually quite a nice toy, albeit not receiving nearly as much attention from developers, here are some random notes for myself, blogged so that I don't loose them.

USB

Switch the micro USB-on-the-go-connector (usable as a “normal” port, e.g. for connecting a Wireless LAN card or a USB thumbdrive) to host-mode:

# echo 1 >/sys/bus/platform/drivers/tegra-otg/tegra-otg/enable_host

Devices connected to the micro-usb with a OTG cable will now appear as usual, on the new “usb3” port.

Flash/Boot

Linux-Images to be run by the stock u-boot should look like this:

# mkimage -l /mnt/linux.img 
Image Name:   Linux_3_1_10+
Created:      Sun Oct 20 03:14:16 2013
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    6198328 Bytes = 6053.05 kB = 5.91 MB
Load Address: 00008000  ← !
Entry Point:  00008000  ← !

These are “legacy” images. The newer .its-based images work, too, but only with newer kernels (I tried 3.10 and 3.11) and those are broken in different ways, see below.

Copy the linux-images to the “default location” in internal NAND flash where 0x00800000 is the mtd device size (must be a multiple of the “erase block size” and 6198392 is your image file size). “/dev/mtd6” is the “LNX” partition when using the stock mtdparts command line option.

# mtd_debug erase /dev/mtd6 0 0x00800000
Erased 8388608 bytes from address 0x00000000 in flash
# mtd_debug write /dev/mtd6 0 6198392 /mnt/linux.img
Copied 6198392 bytes from /mnt/linux.img to address 0x00000000 in flash

“mtd_debug” is part of the “mtd-utils” package.

To find the correct flash block, have a look at /proc/mtd:

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 3de80000 00080000 "USR"
mtd1: 00300000 00080000 "BCT"
mtd2: 00080000 00080000 "PT"
mtd3: 00200000 00080000 "EBT"
mtd4: 00080000 00080000 "BMP"
mtd5: 00200000 00080000 "ENV"
mtd6: 00800000 00080000 "LNX" ← !
mtd7: 00080000 00080000 "ARG"

The partitions are shown in proper (NAND-flash) order in u-boot's mtdparts command (even though this also only parses the mtdparts variable):

Tegra2 # mtdparts  (note: u-boot prompt, not Linux!)
device nand0 , # parts = 8
 #: name size offset mask_flags
 0: BCT                 0x00300000 0x00000000 0
 1: PT                  0x00080000 0x00500000 0
 2: EBT                 0x00200000 0x00780000 0
 3: BMP                 0x00080000 0x00b80000 0
 4: ENV                 0x00200000 0x00e00000 0
 5: LNX                 0x00800000 0x01200000 0
 6: ARG                 0x00080000 0x01c80000 0
 7: USR                 0x3de80000 0x01f80000 0

ENV is the u-boot environment, LNX is the default location for the linux kernel, USR the root-filesystem if running from internal flash. For the other partitions, I'm not sure. There's a “lnx_nand.cfg” in Toradex' T20_LinuxImageV2.0 which might shed a light on the exact purpose of all the unexplained partitions, unfortunately this seems to be handled by NVidias binary-only nvflash utility.

Booting with your root-fs on a sd-card (use no cards slower than class 10):

(u-boot environment variables)
myargs=root=/dev/mmcblk0p1 rootfstype=ext4 rootflags=data=writeback,commit=15 rootdelay=5,noatime,nodiratime
myboot=run setup; setenv bootargs ${defargs} ${myargs} ${mtdparts} ${setupargs} ; run myload ; bootm
myload=nboot ${loadaddr} 0 ${lnxoffset}

In principle, the kernel could also be started of a mmc drive:

Tegra2 # fatload mmc 0:1 $loadaddr linux.img
reading linux.img
mmc_send_cmd: MMC Timeout
    Interrupt status        0x00000001
    Interrupt status enable 0xfbff003b
    Interrupt signal enable 0xfbff0002
    Present status          0x01e70206

6198392 bytes read

But I always get this MMC Timeout error, and the loaded data is corrupt.

If you want to test a new kernel, booting over TFTP/Network (wired ethernet) or from a USB-disk works as expected (example below uses the same sd-card not working above, in a cheap and crappy usb card-reader):.

Tegra2 # fatload usb 0:1 $loadaddr linux.img
reading linux.img

6198392 bytes read
Tegra2 # bootm
## Booting kernel from Legacy Image at 00408000 ...
   Image Name:   Linux_3_1_10+
   Created:      2013-10-20   9:14:16 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    6198328 Bytes = 5.9 MiB
   Load Address: 00008000
   Entry Point:  00008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK

Starting kernel ...

Kernel and Distribution

I didn't have much luck with a more-recent stock-kernel, the most serious problem in those kernel being a misconfiguration of the voltage regulators. My board became very hot and was pretty unstable. So I'm sticking with the antiquated vendor supplied kernel (3.1.10) right now with a config based on the Toradex shipped one.

I'm running ArchLinux based on the root-filesystem for the compact TrimSlice computer which also runs on a NVidia Tegra.






Sunday, September 22, 2013

DCF77 via GPIO on the Raspberry Pi (patched radioclkd2)

Update 2015-02-15, see below.
Update 2016-02-14, see even farther below.

After replacing my old linux-PC based router with a Telco-supplied plastic-box, I no longer have a usable NTP server at home. As a first measure, I’ve put a small DCF77 module on a raspberry-pi. It seems that most people add a serial to usb converter for that, but the raspberry has perfectly fine GPIOs that are capable of generating an interrupt for low CPU load -- and that’s all one needs. You can find my very lightly patched radioclkd2 for parsing the pulses on github.
I’ve added an additional filtering capacitor to the back of the module (be careful, inrush current will crash your Pi when connecting the leads!) a long time ago when it was still connected to the old PC, and there’s a pullup from the pulse output (which typically is open-drain/open-collector) to Vcc (3.3V). In my case, on a Rev. A Raspberry, I use GPIO0 (probably a bad choice, because it’s also one of the two accessible i2c pins, but easily changed).
Unfortunately it turned out that at its current location, reception is pretty bad, but easily solved by repositioning the Pi.
IMG_20130922_121308764

Update:I got a few emails regarding this project (which I hadn't had running for quite some time) recently, so I'll try to add this information on the old blog-post.

First, if you get a lot of pulses with bad, and very short, lengths (<10ms)
  • Reposition the DCF77 receiver with a long cable, away from all your computer stuff and switch-mode power supplies.
  • Wrap a huge ferrite core around this cable, to attenuate wire-conducted noise to the DCF77 receiver.
  • Add additional filtering caps at both sides of the cable (near the Rpi and DCF77 receiver module).
That way, I could get reliable reception again.

Second, if your ntpd doesn't seem to register any time from radioclkd2, even if it seems to receive properly: If you enable debug mode in radioclkd2, it will *not* update the shared memory. So after you've verified proper operation, put radioclkd2 in the background without -d.

Update 2016-02-14: Here are two pictures showing radioclkd2 acquiring time from a DCF77 module.

From Chris’ Miscellanea

From Chris’ Miscellanea






Monday, September 02, 2013

Webmail Notifer, Linux Kernel Module

This is an update on the Webmail Notifier, a cheap chinese gadget that's nothing more than a RGB LED connected via USB. In this case, it's an especially cheap version that can only display 7 distinct colours, plus black (off).

Finally I was sufficiently annoyed to put the code into a “proper” kernel module (original module on kernel.org). Here's my patch that adds this particular LED gadget.

Here's the thing cycling through random colours:

Wednesday, July 03, 2013

Repairing an Alesis IO26

There's a really common way to kill your firewire-devices, which is to forcefully plug in the 6-pin connector, carrying both supply power and data signals, rotated by 180 degrees (which normally should be prevented by the asymmetrical shape of the connector). That way you'll send +12V, the most common supply voltage, into the chip that connects to the cable. This kills the chip pretty reliably.

This audio-interface (Alesis IO26) was damaged using this method:

From Chris’ Miscellanea

Thankfully the internal layout of the device is pretty clean. There's a stack of two PCBs (only the lower one shown) on the left side inside. The lower one has the DSP, Firewire controller and a ARM based controller. It connects with flat cables to the "analog" boards. On top, it carries a switching power supply generating the internal voltages (+3.3V, +5V, +/-15V and +48V from a single, galvanically isolated 9..30V input) which is missing in the photo.

From Chris’ Miscellanea

A good way to diagnose these kind of errors (according to some forums and FAQs) is to look at the idle-voltage on the firewire-bus lines (TPA0+...TPA0-...). They are supposed to be biased to a internally generated 1/2 Vcc (~1.8V) via 56 Ohm resistors from the twisted-pair lines to a bias pin (TBIAS0/1). It's described in the data sheet of the chip, here it's a TSB41AB2 from TexasInstruments In my case one bias-voltage-regulator spat out 3.3V, the other 0V (there's one for each of the two firewire ports). One of the ports had one receiver line stuck at 0V (chip-internal short to GND).

The only way to repair it is to desolder the chip, and replace it with a new one. Then the interface should be functioning again (I did not populate the mechanically damaged connector and associated terminating resistors, one port is enough for me).

From Chris’ Miscellanea

From Chris’ Miscellanea

The two shorted pins #1 and #2 are both GND, so I did not bother to clean up the blob.

Sunday, June 09, 2013

Audix APS 910 - Inline Phantom Adapter

This adapter allows you to connect "normal" electret-type microphones to differential, phantom-powered inputs, like the ones to be found on sound mixing desks. I got one of those, but as the pinout was not mentioned anywhere, I made these photographs.

http://www.audixusa.com/docs_12/units/APS910.shtml

Mini-XLR pinout is supposed to be: 1: GND, 2: Signal, 3: Vbias. Even though the supply pin (3) is quite susceptible to noise coupling into the adapter output, Firther more, the signal pin (2) itself has a 1k or so pullup to Vbias. So to connect to a 2-pin electret microphone, just connect only pin 2. If you need more bias current, also connect pin 3, but then your signal will be slightly attenuated.

Phantom supply current is preetty high, at around 5mA each on "Hot" and "Cold" pins. (P48 on my mixing desk goes down to 13V when the adapter is connected)

From Chris’ Miscellanea

From Chris’ Miscellanea

From Chris’ Miscellanea


From Chris’ Miscellanea

Friday, May 31, 2013

Reboot your Arch-linux running computer early, in case some vital component failed to initialize (a.k.a. e1000e_fsckup_initcpio)

Ok, so this is embarrassingly primitive, but so that I don't loose it (again), I put this small script on github. Maybe someone else having a problem with things not initializing properly on every boot can find the concept useful: I have a computer based on a “DFI LanParty Mini-ITX P55-T36” motherboard with an integrated Intel Gigabit interface. Which works fine so far, but always fails to initialize networking on the first bootup after power-on. This is obviously inconvenient for unattended operation.

To fix this once and for all and reboot the computer early, feel free to use the code at https://github.com/vogelchr/e1000e_fsckup_initcpio.

From Chris’ Miscellanea

Thursday, May 30, 2013

Antlers (May 2013 edition)

I was on vacation again, so here's the obligatory antlers picture. I already posted another one elsewhere, but that was taken with the (a little bit) crappy phone camera and doesn't do the wallpaper and the antlers justice.


From Chris’ Miscellanea

Sunday, May 19, 2013

Wireless on Raspberry π, Power Issues

I'm playing with a Accellerometer/Gyroscope/Magnetometer board (ebay, link probably stale soon), and to have it somewhat mobile, I've connected it to the ole' trusty Raspberry π.

Unfortunately I have problems with a lot of WiFi adapters because of the many fuses inside of the π dropping voltages (starting with 4,5V from my Notebook/USB hub, it goes down to 3,8V on the USB connector). But adding a short wire bridging all those fuses helps ;-).



The dongle used is really old, it's a 

Bus 001 Device 005: ID 07b8:b21d AboCom Systems Inc RT2573

and gets quite warm (correlates well with the high power consumption and hence voltage drop on the fuses), also looses contact with my (just nearby) access point frequently.

[ 2140.585617] ieee80211 phy0: wlan0: No probe response from AP 68:7f:74:5e:42:ff after 500ms, disconnecting.
[ 2140.607093] cfg80211: All devices are disconnected, going to restore regulatory settings
[ 2140.607132] cfg80211: Restoring regulatory settings
[ 2140.607420] cfg80211: Calling CRDA to update world regulatory domain
[ 2141.948125] wlan0: authenticate with 68:7f:74:5e:42:ff
[ 2141.996396] wlan0: send auth to 68:7f:74:5e:42:ff (try 1/3)
[ 2141.998072] wlan0: authenticated
[ 2141.998877] rt73usb 1-1.2:1.0: wlan0: disabling HT due to WEP/TKIP use
[ 2141.998912] rt73usb 1-1.2:1.0: wlan0: disabling HT as WMM/QoS is not supported
[ 2142.035630] wlan0: associate with 68:7f:74:5e:42:ff (try 1/3)
[ 2142.037914] wlan0: RX AssocResp from 68:7f:74:5e:42:ff (capab=0x431 status=0 aid=20)
[ 2142.037943] wlan0: invalid AID value 0x14; bits 15:14 not set
[ 2142.057687] wlan0: associated




Sunday, March 31, 2013

Happy Easter

And remember: As long as the eggs aren't completely covered in snow, it's spring enough.

From 2013-03-31

Friday, March 29, 2013

Webmail Notifier - Linux Hidraw

I got myself a plastic toy: A small box with a controlable LED that can be turned on- or off, with the intention of notifying the user of unread emails.

https://www.google.de/search?q=webmail+notifier&tbm=isch

My incarnation of this relatively simple concept identifies itself with a USB VID/PID of 0x1294:0x1320:


# lsusb -s 1:14
Bus 001 Device 014: ID 1294:1320 RISO KAGAKU CORP.


And it shows itself in the kernel log as follows:


[10772.855386] usb 1-1.6: new low-speed USB device number 15 using ehci-pci
[10772.949641] hid-generic 0003:1294:1320.000D: hiddev0,hidraw2: USB HID v1.10 Device [MAIL MAIL ] on usb-0000:00:1a.0-1.6/input0


As it registers itself with the HID subsystem, we can use the resulting hidraw device to talk to it without using any script or tool, just make a convenience symlink with useable permissions using a small udev rule:


$ cat /etc/udev/rules.d/99_webmail_notifier.rules
# USB Webmail Notifier (RGB LED)
SUBSYSTEM=="hidraw" SUBSYSTEMS=="usb", ATTRS{idVendor}=="1294", ATTRS{idProduct}=="1320", GROUP="users", MODE="0660", SYMLINK="webmailnotify"


Then you can make it change its colour with a simple echo-command in any script:


$ echo -en '\001\0\0\0\0' >/dev/webmailnotify


The only ugly thing about it: It seems to send back some HID report which confuses and angers the kernel routines, but this shall be dealt with at some later point.


[11170.163495] hid-generic 0003:1294:1320.000D: extract() called with n (56) > 32! (swapper/0)


Saturday, February 09, 2013

AES/EBU to ‘SPDIF’  - ghetto style


For interfacing AES/EBU to S/PDIF, I've built a simple transformer out of a small ferrite core, I was planning to convert the 110Ω symmetric AES/EBU signal coming out of a surplus ADC/DAC (I love you, eBay ;-) ...) to the S/PDIF of my computer interfaces (and vice-versa).

There's a nice text about all this over at RANE, but normal people just shell out the 100€ for two of Neutrik's transformers in a box.

The screenshots below show the output of the transformer, terminated by 75 Ohm (or by the audio-interface S/PDIF input, looks identical) when driven by the AES output. I wanted to hide everything in the XLR connector shell, and hence the ferrite beads are pretty small. Therefore they saturate visibly at 32kHz fs, but it works fine for this signal direction. At 96kHz everything looks perfect.


From Chris’ Miscellanea

From Chris’ Miscellanea

From Chris’ Miscellanea

The other direction works not as nicely: All of my audio-gear has a pretty high output impedance on the S/PDIF outputs! With a open output, I get something like 3-5VPP of signal swing, but terminated it goes down to 500mV (just as the spec says). With the saturating ferrite beads, the high-impedance outputs cannot provide the additional current, and the ideally square-shaped output degenerates to tiny spikes of both polarities and is completely unusable. The not-very-pretty-but-working-solution: Just connect the SPDIF to AES 1:1, but keep cable lengths short. (no scope, screenshots, sorry).

Monday, January 14, 2013

M-Audio Fast-Track Pro PCB Pictures

I'm a little annoyed by the limitations of the M-Audio Fast-Track Pro, so I'm thinking about how to mod it. My main grief is the abysmally bad windows drivers that bluescreen constantly under Win7. Then there is the limitation of USB1.1, which does not have enough bandwidth for anything more than 2x24/96 streams. My plan is to make a normal standalone S/PDIF ADC/DAC (2in, 2out, 24/96) out of it.

First, I took a few pictures of the two PCBs inside the unit, and traced a few signals. You can see immediately that the electronic layout of the unit is very tidy!

Main integrated components:
Misc. Digital
The phantom voltage generator has a venerable NE555!

OP-Amps
  • NJM2115 NRC Dual Operational Amplifier
  • NJM3414 NRC Single Supply Dual High Current Operational Amplifier (Headphone Out)


From M-Audio Fast Track Pro

From M-Audio Fast Track Pro

From M-Audio Fast Track Pro

From M-Audio Fast Track Pro

From M-Audio Fast Track Pro