Monday, January 31, 2011

Setting up usb gadget serial (g_serial) on Kobo Wifi

This article is part of an extended series on Kobo development and investigation


Apparently I have to make this more obvious:

  • Take a backup of your Kobo's SD card before doing anything. If something doesn't work, you can't fix your Kobo without this backup. I will not send you a backup.
  • Any device hacking is risky. If you can't afford to break your device, leave now.

The Kobo Wifi (apparently) has an onboard serial port, but it doesn't have any header pins let alone a usable socket. Using it will require bulldog clips at best, more likely soldering some pins in. Either way you have to open the case and keep it open while using the port which is inconvenient if you like to actually use your Kobo. In any case, I can't find any documentation for the pinout.

Telnet over wifi works and can be enabled without opening up the device - but tends to go down quite a bit, as it's not really intended for this use. It's hopelessly unsuitable for running a GDB remote debugger over.

It's fairly simple to modify the Kobo Wifi (and presumably the original Kobo, though I haven't tried it) to add support for serial-over-usb and/or ethernet-over-usb, both of which are much easier to work with than physical serial and much better than telnet/ftp over wifi. Enabling USB serial gadget support seems to interfere with the USB gadget mass storage system used to export the file system to a host computer, though, so don't make the change permanent unless you like to keep your library on an SD card. It looks like the 2.6.33-rc1 and newer kernels may contain support for multiple gadgets running at once, but the Kobo is on 2.6.28 and it's unlikely to be worth the effort of an update.

To get usb serial mode working, you must build a new kernel for the Kobo and copy the modules from that kernel over to the Kobo. You might want to make menuconfig and enable CONFIG_USB_CDC_COMPOSITE in drivers -> usb support -> usb gadget -> CDC Composite Device if you'd like to have simultaneous support for Ethernet and serial gadget mode, which can be really handy for debugging. See documentation/README.kernel in the KoboLabs git repository for how to build a new kernel and modules. I've asked them to pull it, so it should be there soon. You should not actually need to install the new kernel, as the modules you build should be compatible with the old kernel already on the device.

To install the modules, install them to some temporary MOD_INSTALL_PATH like /tmp/arm then cd /tmp/arm and tar cvzf KoboRoot.tgz lib. Copy the KoboRoot.tgz file to .kobo/KoboRoot.tgz on the device's onboard user-accessible flash storage and reboot to install the update. After a reboot, you can telnet in and modprobe g_serial (or g_cdc if you compiled the mixed serial/ethernet module) to enable USB serial support. To make the serial port useful you need to run /sbin/getty -L ttyGS0 115200 vt100 to listen for logins. This is easily wrapped in a shell script you can invoke via telnet, or via an autorun hook you add in /etc/init.d/rcS that runs a script off an add-in SD card if one is found. The same script can be used to bring up the usb0 ethernet device if you're using g_cdc.

If you want to make usb serial gadget support start at every boot (thus disabling the ability to manage the internal card library over USB - this will be annoying!), add this line to /etc/inittab on the device:

ttyGS0::askfirst:/sbin/getty -L ttyGS0 115200 vt100

... and add this line to /etc/init.d/rcS after "/bin/mount -t sysfs" :

/sbin/modprobe g_serial

If you'd prefer to have serial and ethernet, and made the kernel config change to enable it as described above, replace g_serial with g_cdc in the line above.

Once you've loaded the g_serial module one way or another and started a getty, you can connect the Kobo to your PC. When prompted for what to do, say "keep reading". You'll discover that the Kobo appears as a USB serial port that you can connect a terminal to. On a Linux host it should be /dev/ttyACMx (/dev/ttyACM0 if you have no other USB serial ports); check dmesg to be sure. You can use a terminal program like minicom, gtkterm or picoterm to talk to the port. The login is "root" and there is no password unless you set one later. You can transfer files using zmodem's rx command if you need to, use the usb ethernet module, or ftp them over wifi.

Unlike telnet over wifi, this serial console stays up no matter what antics nickel performs, and doesn't require the device to be open. It's similarly easy to use g_ether to expose an Ethernet interface or g_cdc to do both ethernet and serial at once. It's just a real pain that using them prevents the g_file_storage module used by the Kobo to manage the onboard memory from working!

3 comments:

  1. Hi

    I have my Kobo open now and a bus pirate hooked up to the serial header. The board clearly labels the pins (on the underside) as V, TX, RX and ground (starting from the top and moving down). V is just a supply voltage, so you don't need to use that. Signaling is 3.3V TTL and serial parameters are 115200 8 N 1.

    ReplyDelete
  2. hi,

    it happens that I'm trying to use another arm target running linux (pandaboard A3) as an USB device by using and OTG connector available on the board. I wanna use it with the g_serial module to communicate with a host pc. When I boot the panda with the proper usb cable connected I just have to load the g_serial module and the panda gets enumerated and I can connect via /dev/ttyACM0 device. The problem is when I unplug the board or boot it without being connected to the host. No matter how many times I load or remove-reload the module the board never gets enumerated again. I would like to know if you have any comments about, because this is really important and I can not find a way to overcome that issue. Thanks in advance, best regards, Vj

    ReplyDelete
    Replies
    1. I don't have a PandaBoard, so I really couldn't say. If it's running a vaguely recent kernel maybe ask on LKML, otherwise ask the PandaBoard people. It could be to do with how USB OTG works on the board, it could be a kernel issue, it could be practically anything.

      Delete