Adrian revised this gist . Go to revision
1 file changed, 129 insertions
S41usbconfigfs(file created)
| @@ -0,0 +1,129 @@ | |||
| 1 | + | #!/bin/sh | |
| 2 | + | # Largely taken from postmarketOS' init functions, many thanks! | |
| 3 | + | # Their repository is licensed under the terms of the GPLv3, same as waitaha. | |
| 4 | + | # https://gitlab.com/postmarketOS/pmaports/-/blob/master/main/postmarketos-initramfs/init_functions.sh | |
| 5 | + | ||
| 6 | + | umask 077 | |
| 7 | + | ||
| 8 | + | start() { | |
| 9 | + | printf "Configuring USB: " | |
| 10 | + | ||
| 11 | + | mkdir /config | |
| 12 | + | mount -t configfs -o nodev,noexec,nosuid configfs /config | |
| 13 | + | ||
| 14 | + | CONFIGFS=/config/usb_gadget | |
| 15 | + | ||
| 16 | + | if ! [ -e "$CONFIGFS" ]; then | |
| 17 | + | echo "SKIP" | |
| 18 | + | return | |
| 19 | + | fi | |
| 20 | + | ||
| 21 | + | # Default values for USB-related deviceinfo variables | |
| 22 | + | usb_idVendor="0x18D1" # default: Google Inc. | |
| 23 | + | usb_idProduct="0xD001" # default: Nexus 4 (fastboot) | |
| 24 | + | usb_serialnumber="waitaha" | |
| 25 | + | usb_network_function="ncm.usb0" | |
| 26 | + | usb_network_function_fallback="rndis.usb0" | |
| 27 | + | usb_adb_function="ffs.usb0" | |
| 28 | + | usb_mass_storage_function="mass_storage.0" | |
| 29 | + | ||
| 30 | + | deviceinfo_manufacturer=$(cat /etc/deviceinfo | sed -n 's/.*manufacturer=\([^,]*\)[,]*/\1/p; s/.*manufacturer=\([^,]*\)$/\1/p') | |
| 31 | + | deviceinfo_name=$(cat /etc/deviceinfo | sed -n 's/.*name=\([^,]*\),codename.*/\1/p') | |
| 32 | + | ||
| 33 | + | # Create an usb gadget configuration | |
| 34 | + | mkdir $CONFIGFS/g1 | |
| 35 | + | echo "$usb_idVendor" > "$CONFIGFS/g1/idVendor" | |
| 36 | + | echo "$usb_idProduct" > "$CONFIGFS/g1/idProduct" | |
| 37 | + | echo 0x0223 > "$CONFIGFS/g1/bcdDevice" | |
| 38 | + | echo 0x0200 > "$CONFIGFS/g1/bcdUSB" | |
| 39 | + | ||
| 40 | + | # Create English (0x409) strings | |
| 41 | + | mkdir $CONFIGFS/g1/strings/0x409 || echo " Couldn't create $CONFIGFS/g1/strings/0x409" | |
| 42 | + | ||
| 43 | + | echo "$deviceinfo_manufacturer" > "$CONFIGFS/g1/strings/0x409/manufacturer" | |
| 44 | + | echo "$usb_serialnumber" > "$CONFIGFS/g1/strings/0x409/serialnumber" | |
| 45 | + | echo "$deviceinfo_name" > "$CONFIGFS/g1/strings/0x409/product" | |
| 46 | + | ||
| 47 | + | # Create network function. | |
| 48 | + | if ! mkdir $CONFIGFS/g1/functions/"$usb_network_function"; then | |
| 49 | + | echo " Couldn't create $CONFIGFS/g1/functions/$usb_network_function" | |
| 50 | + | # Try the fallback function next | |
| 51 | + | if mkdir $CONFIGFS/g1/functions/"$usb_network_function_fallback"; then | |
| 52 | + | usb_network_function="$usb_network_function_fallback" | |
| 53 | + | else | |
| 54 | + | echo " Couldn't create $CONFIGFS/g1/functions/$usb_network_function_fallback" | |
| 55 | + | fi | |
| 56 | + | fi | |
| 57 | + | ||
| 58 | + | # Create ADB FunctionFS entry | |
| 59 | + | if ! mkdir $CONFIGFS/g1/functions/"$usb_adb_function"; then | |
| 60 | + | echo " Couldn't create $CONFIGFS/g1/functions/$usb_adb_function" | |
| 61 | + | fi | |
| 62 | + | ||
| 63 | + | # Create mass storage function entry | |
| 64 | + | if ! mkdir $CONFIGFS/g1/functions/"$usb_mass_storage_function"; then | |
| 65 | + | echo " Couldn't create $CONFIGFS/g1/function/$usb_mass_storage_function" | |
| 66 | + | fi | |
| 67 | + | ||
| 68 | + | # Create configuration instance for the gadget | |
| 69 | + | mkdir $CONFIGFS/g1/configs/c.1 | |
| 70 | + | mkdir $CONFIGFS/g1/configs/c.1/strings/0x409 | |
| 71 | + | echo "USB networking and storage and ADB" > $CONFIGFS/g1/configs/c.1/strings/0x409/configuration | |
| 72 | + | ||
| 73 | + | i=1 | |
| 74 | + | for disk in $(lsblk -d -I 8 -o KNAME -n); do | |
| 75 | + | if ! mkdir $CONFIGFS/g1/functions/"$usb_mass_storage_function/lun.$i"; then | |
| 76 | + | echo " Couldn't create $CONFIGFS/g1/functions/$usb_mass_storage_function/lun.$i" | |
| 77 | + | fi | |
| 78 | + | echo /dev/"$disk" > $CONFIGFS/g1/functions/"$usb_mass_storage_function/lun.$i"/file | |
| 79 | + | i=$(( i + 1 )) | |
| 80 | + | done | |
| 81 | + | ||
| 82 | + | # Link the network instance to the configuration | |
| 83 | + | ln -s $CONFIGFS/g1/functions/"$usb_network_function" $CONFIGFS/g1/configs/c.1 | |
| 84 | + | ||
| 85 | + | # Link the ADB function to the configuration | |
| 86 | + | ln -s $CONFIGFS/g1/functions/"$usb_adb_function" $CONFIGFS/g1/configs/c.1 | |
| 87 | + | ||
| 88 | + | # Link the mass storage function to the configuration | |
| 89 | + | ln -s $CONFIGFS/g1/functions/"$usb_mass_storage_function" $CONFIGFS/g1/configs/c.1 | |
| 90 | + | ||
| 91 | + | # Create adb mount point | |
| 92 | + | mkdir -p /dev/usb-ffs/adb | |
| 93 | + | # mount -o uid=2000,gid=2000 -t functionfs usb0 /dev/usb-ffs/adb | |
| 94 | + | mount -t functionfs usb0 /dev/usb-ffs/adb | |
| 95 | + | ||
| 96 | + | adbd & | |
| 97 | + | sleep 1 | |
| 98 | + | ||
| 99 | + | # Check if there's a USB Device Controller | |
| 100 | + | _udc_dev=$(ls /sys/class/udc) | |
| 101 | + | if [ -z "$_udc_dev" ]; then | |
| 102 | + | return | |
| 103 | + | fi | |
| 104 | + | ||
| 105 | + | # Remove any existing UDC to avoid "write error: Resource busy" when setting UDC again | |
| 106 | + | if [ "$(wc -w <$CONFIGFS/g1/UDC)" -gt 0 ]; then | |
| 107 | + | echo "" > $CONFIGFS/g1/UDC || echo " Couldn't write to clear UDC" | |
| 108 | + | fi | |
| 109 | + | # Link the gadget instance to a USB Device Controller. This activates the gadget. | |
| 110 | + | # See also: https://gitlab.com/postmarketOS/pmbootstrap/issues/338 | |
| 111 | + | echo "$_udc_dev" > $CONFIGFS/g1/UDC | |
| 112 | + | ||
| 113 | + | # Bring up the network interface | |
| 114 | + | ip addr add 172.16.42.1/24 dev usb0 | |
| 115 | + | ip link set usb0 up | |
| 116 | + | ||
| 117 | + | echo "OK" | |
| 118 | + | } | |
| 119 | + | ||
| 120 | + | case "$1" in | |
| 121 | + | start) | |
| 122 | + | start | |
| 123 | + | ;; | |
| 124 | + | *) | |
| 125 | + | echo "Usage: $0 start" | |
| 126 | + | exit 1 | |
| 127 | + | esac | |
| 128 | + | ||
| 129 | + | exit $? | |
Newer
Older