S41usbconfigfs
· 4.1 KiB · Text
Raw
#!/bin/sh
# Largely taken from postmarketOS' init functions, many thanks!
# Their repository is licensed under the terms of the GPLv3, same as waitaha.
# https://gitlab.com/postmarketOS/pmaports/-/blob/master/main/postmarketos-initramfs/init_functions.sh
umask 077
start() {
printf "Configuring USB: "
mkdir /config
mount -t configfs -o nodev,noexec,nosuid configfs /config
CONFIGFS=/config/usb_gadget
if ! [ -e "$CONFIGFS" ]; then
echo "SKIP"
return
fi
# Default values for USB-related deviceinfo variables
usb_idVendor="0x18D1" # default: Google Inc.
usb_idProduct="0xD001" # default: Nexus 4 (fastboot)
usb_serialnumber="waitaha"
usb_network_function="ncm.usb0"
usb_network_function_fallback="rndis.usb0"
usb_adb_function="ffs.usb0"
usb_mass_storage_function="mass_storage.0"
deviceinfo_manufacturer=$(cat /etc/deviceinfo | sed -n 's/.*manufacturer=\([^,]*\)[,]*/\1/p; s/.*manufacturer=\([^,]*\)$/\1/p')
deviceinfo_name=$(cat /etc/deviceinfo | sed -n 's/.*name=\([^,]*\),codename.*/\1/p')
# Create an usb gadget configuration
mkdir $CONFIGFS/g1
echo "$usb_idVendor" > "$CONFIGFS/g1/idVendor"
echo "$usb_idProduct" > "$CONFIGFS/g1/idProduct"
echo 0x0223 > "$CONFIGFS/g1/bcdDevice"
echo 0x0200 > "$CONFIGFS/g1/bcdUSB"
# Create English (0x409) strings
mkdir $CONFIGFS/g1/strings/0x409 || echo " Couldn't create $CONFIGFS/g1/strings/0x409"
echo "$deviceinfo_manufacturer" > "$CONFIGFS/g1/strings/0x409/manufacturer"
echo "$usb_serialnumber" > "$CONFIGFS/g1/strings/0x409/serialnumber"
echo "$deviceinfo_name" > "$CONFIGFS/g1/strings/0x409/product"
# Create network function.
if ! mkdir $CONFIGFS/g1/functions/"$usb_network_function"; then
echo " Couldn't create $CONFIGFS/g1/functions/$usb_network_function"
# Try the fallback function next
if mkdir $CONFIGFS/g1/functions/"$usb_network_function_fallback"; then
usb_network_function="$usb_network_function_fallback"
else
echo " Couldn't create $CONFIGFS/g1/functions/$usb_network_function_fallback"
fi
fi
# Create ADB FunctionFS entry
if ! mkdir $CONFIGFS/g1/functions/"$usb_adb_function"; then
echo " Couldn't create $CONFIGFS/g1/functions/$usb_adb_function"
fi
# Create mass storage function entry
if ! mkdir $CONFIGFS/g1/functions/"$usb_mass_storage_function"; then
echo " Couldn't create $CONFIGFS/g1/function/$usb_mass_storage_function"
fi
# Create configuration instance for the gadget
mkdir $CONFIGFS/g1/configs/c.1
mkdir $CONFIGFS/g1/configs/c.1/strings/0x409
echo "USB networking and storage and ADB" > $CONFIGFS/g1/configs/c.1/strings/0x409/configuration
i=1
for disk in $(lsblk -d -I 8 -o KNAME -n); do
if ! mkdir $CONFIGFS/g1/functions/"$usb_mass_storage_function/lun.$i"; then
echo " Couldn't create $CONFIGFS/g1/functions/$usb_mass_storage_function/lun.$i"
fi
echo /dev/"$disk" > $CONFIGFS/g1/functions/"$usb_mass_storage_function/lun.$i"/file
i=$(( i + 1 ))
done
# Link the network instance to the configuration
ln -s $CONFIGFS/g1/functions/"$usb_network_function" $CONFIGFS/g1/configs/c.1
# Link the ADB function to the configuration
ln -s $CONFIGFS/g1/functions/"$usb_adb_function" $CONFIGFS/g1/configs/c.1
# Link the mass storage function to the configuration
ln -s $CONFIGFS/g1/functions/"$usb_mass_storage_function" $CONFIGFS/g1/configs/c.1
# Create adb mount point
mkdir -p /dev/usb-ffs/adb
# mount -o uid=2000,gid=2000 -t functionfs usb0 /dev/usb-ffs/adb
mount -t functionfs usb0 /dev/usb-ffs/adb
adbd &
sleep 1
# Check if there's a USB Device Controller
_udc_dev=$(ls /sys/class/udc)
if [ -z "$_udc_dev" ]; then
return
fi
# Remove any existing UDC to avoid "write error: Resource busy" when setting UDC again
if [ "$(wc -w <$CONFIGFS/g1/UDC)" -gt 0 ]; then
echo "" > $CONFIGFS/g1/UDC || echo " Couldn't write to clear UDC"
fi
# Link the gadget instance to a USB Device Controller. This activates the gadget.
# See also: https://gitlab.com/postmarketOS/pmbootstrap/issues/338
echo "$_udc_dev" > $CONFIGFS/g1/UDC
# Bring up the network interface
ip addr add 172.16.42.1/24 dev usb0
ip link set usb0 up
echo "OK"
}
case "$1" in
start)
start
;;
*)
echo "Usage: $0 start"
exit 1
esac
exit $?
| 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 $? |
| 130 |