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