Novena as a USB keyboard

From Studio Kousagi Wiki
Jump to: navigation, search

Novena has the ability to act as a USB HID device, such as a keyboard, mouse, or joystick. It can do this through the use of the configfs system.

Setup Script

Create a file called something like hid-gadget.sh:

#!/bin/sh

configfs="/sys/kernel/config/usb_gadget"
g=g1
c=c.1
d="${configfs}/${g}"
func=hid.usb0

do_stop() {
        echo "" > "${d}/UDC"

        rm "${d}/configs/${c}/${func}"

        rmdir ${d}/strings/0x409/

        rmdir "${d}/configs/${c}/strings/0x409"
        rmdir "${d}/configs/${c}"
        rmdir "${d}/functions/${func}"
        rmdir "${d}"
}

do_start() {
        mkdir "${d}"
        echo 0x05e2 > "${d}/idVendor"
        echo 0x0613 > "${d}/idProduct"
        echo 8 > "${d}/bMaxPacketSize0"

        mkdir "${d}/strings/0x409"
        echo "12345" > "${d}/strings/0x409/serialnumber"
        echo "kosagi" > "${d}/strings/0x409/manufacturer"
        echo "Software keyboard" > "${d}/strings/0x409/product"

        mkdir "${d}/configs/${c}"

        mkdir "${d}/configs/${c}/strings/0x409"
        echo "config 1" > "${d}/configs/${c}/strings/0x409/configuration"
        echo 120 > "${d}/configs/${c}/MaxPower"

        mkdir "${d}/functions/${func}"
        echo "1" > "${d}/functions/${func}/protocol"
        echo "1" > "${d}/functions/${func}/subclass"
        echo "8" > "${d}/functions/${func}/report_length"
        /bin/bash -c 'echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0' > "${d}/functions/${func}/report_desc"

        ln -s "${d}/functions/${func}" "${d}/configs/${c}"

        udc=$(ls -1 /sys/class/udc/)
        echo "${udc}" > "${d}/UDC"
}

if [ "$1" = "start" ]
then
        do_start
elif [ "$1" = "stop" ]
then
        do_stop
else
        echo "Usage: $0 (stop | start)"
fi

Mark it as executable:

chmod a+x hid-gadget.sh

Start it as root:

sudo ./hid-gadget.sh start


This will create /dev/hidg0

Sending Input

The file /dev/hidg0 is a HID device. You can write HID packets to it and they will be received on the host. It's a bit annoying to write HID packets, so Linux ships with hidg_test.c, which is present in the Documentation directory: gadget_hid.txt.

Strip off the header from gadget_hid.txt, rename it to hidg_test.c, and compile it with:

gcc hidg_test.c -o hidg_test

Run it by specifying the hidg device, and whether you want a keyboard, joystick, or mouse:

sudo ./hidg_test /dev/hidg0 keyboard

Then, type into the window what packets you would like to send. Characters a-z are supported, and you can send a capital C by typing something like:

--left-shift c

Press Return to actually submit the command.

Stopping HID

Stopping the HID device can be done by running ./hid-gadget.sh stop