I was specifying in /boot/config.txt
in order to get the NIC to function, and then after boot, (using nmap to find it, then ssh'ing in and) running
and ensuring with lsmod that the dwc2 module was loaded. However, it seems that this is a good chunk of where I am going wrong - specifying dtoverlay in config.txt does not appear to be the same as running the dtoverlay command later after the system has booted - so if I am accessing the Pi Zero via the network, with "dtoverlay=enc28j60" in config.txt, then after logging in run "sudo dtoverlay dwc2", this is NOT sufficient. If I have "dtoverlay=dwc2" in config.txt and then run scripts to create a /dev/hidg0, while logged in locally, it does create the device.
In all cases, I still can't "modprobe g_hid" without getting a "No such device" error. But I can create a /dev/hidg0 with a script, libcomposite, and configfs!
First off, I needed a custom device tree overlay in order to make this work, so I put this into lee.dts:
Code: Select all
// Custom overlay that combines enc28j60 & dwc2 overlays
// Probably a better way to do this with /include/ but I don't know how and this worked for me
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2708";
fragment@0 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
eth1: enc28j60@0{
compatible = "microchip,enc28j60";
reg = <0>; /* CE0 */
pinctrl-names = "default";
pinctrl-0 = <ð1_pins>;
interrupt-parent = <&gpio>;
interrupts = <25 0x2>; /* falling edge */
spi-max-frequency = <12000000>;
status = "okay";
};
};
};
fragment@1 {
target = <&spidev0>;
__overlay__ {
status = "disabled";
};
};
fragment@2 {
target = <&gpio>;
__overlay__ {
eth1_pins: eth1_pins {
brcm,pins = <25>;
brcm,function = <0>; /* in */
brcm,pull = <0>; /* none */
};
};
};
fragment@3 {
target = <&usb>;
#address-cells = <1>;
#size-cells = <1>;
dwc2_usb: __overlay__ {
compatible = "brcm,bcm2835-usb";
reg = <0x7e980000 0x10000>;
interrupts = <1 9>;
dr_mode = "otg";
g-np-tx-fifo-size = <32>;
g-rx-fifo-size = <256>;
g-tx-fifo-size = <256 128 128 64 64 64 32>;
status = "okay";
};
};
__overrides__ {
int_pin = <ð1>, "interrupts:0",
<ð1_pins>, "brcm,pins:0";
speed = <ð1>, "spi-max-frequency:0";
dr_mode = <&dwc2_usb>, "dr_mode";
g-np-tx-fifo-size = <&dwc2_usb>,"g-np-tx-fifo-size:0";
g-rx-fifo-size = <&dwc2_usb>,"g-rx-fifo-size:0";
g-tx-fifo-size = <&dwc2_usb>,"g-tx-fifo-size:0";
};
};
(those are tabs rather than spaces, I don't know how important that is but this is what worked for me)
I simply took
the source for the NIC DTO and
the source for the dwc2 overlay and combined them and modifying slightly (added the dwc2 fragment@0 as fragment@3 - I have no idea if I could have literally copied and pasted but this seemed more sensible). I originally looked up these files to see if there was some kind of conflict between them while trying to debug loading them in different orders with the dtoverlay command after booting - doesn't look like it to me. But I know next to nothing about the device tree
Based on
the documentation here, I ran:
Code: Select all
sudo apt-get install device-tree-compiler # just to make sure, it was already installed for me in the Raspbian Jessie Lite 2015-05-27 image
dtc -@ -I dts -O dtb -o lee.dtbo lee.dts
... which gave me ...
Code: Select all
pi@pi0kbtest:~ $ dtc -@ -I dts -O dtb -o lee.dtbo lee.dts
Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@1 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@2 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@3 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@3/__overlay__ has a reg or ranges property, but no unit name
and a lee.dtbo file. I copied both lee.dtbo and lee.dts into /boot/overlays (because I am lazy) and modified /boot/config.txt to include
then proceeded with the customary goat sacrifice and prayers to the dark one, tried a reboot aaaaaaand...
... it worked! The result is, I now have the Pi Zero on the network (
and a static MAC set so it gets the same IP address every time, as trying to configure it in /etc/network/interfaces seems to do nothing) and can run a script to create a /dev/hidg0 which I will hopefully be able to write to to send keystrokes. The script is:
Code: Select all
#!/bin/bash
# From the README at https://github.com/girst/hardpass
dtoverlay dwc2
modprobe dwc2
modprobe libcomposite
cd /sys/kernel/config/usb_gadget/
mkdir -p g1
cd g1
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409
echo "fedcba9876543210" > strings/0x409/serialnumber
echo "girst" > strings/0x409/manufacturer
echo "Hardpass" > strings/0x409/product
N="usb0"
mkdir -p functions/hid.$N
echo 1 > functions/hid.usb0/protocol
echo 1 > functions/hid.usb0/subclass
echo 8 > functions/hid.usb0/report_length
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 > functions/hid.usb0/report_desc
C=1
mkdir -p configs/c.$C/strings/0x409
echo "Config $C: ECM network" > configs/c.$C/strings/0x409/configuration
echo 250 > configs/c.$C/MaxPower
ln -s functions/hid.$N configs/c.$C/
ls /sys/class/udc > UDC
It appears that this script MUST be run BEFORE plugging the device into a host. I don't yet know what repercussions this has for running it during boot, while the device is attached to a host.
So in theory, now I need to write scancodes to /dev/hidg0 and I should end up with a network controllable keyboard. Somehow I doubt this last part is going to be quite that easy!