Files
airborne_CO2/mountdjirndism400.sh
2026-01-08 16:00:08 +08:00

174 lines
6.4 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
apt install -y bridge-utils
# The IP address shared by the USB network interface creatoedd by this script.
NET_IP="192.168.55.1"
# The associated netmask.
NET_MASK="255.255.0.0"
# 定义USB Gadget的根目录使用官网脚本的通用名称 "pi4"
GADGET_NAME="pi4"
GADGET_ROOT="/sys/kernel/config/usb_gadget/${GADGET_NAME}"
# --- UDC DEVICE 提示 ---
# 通常 Raspberry Pi (或类似SoC) 的 dwc2/ci_hdrc 等驱动会自动作为 UDC 设备出现。
# 官网脚本在绑定时直接使用 'UDC' 文件,不需要显式指定 UDC_DEVICE 变量。
# 系统会自动查找可用的 UDC 设备进行绑定。
# 确保脚本以root权限运行
if [ "$(id -u)" -ne 0 ]; then
echo "This script must be run as root. Please run with 'sudo'."
exit 1
fi
echo "--------------------------------------"
echo "Configuring USB Gadget for RNDIS ONLY."
echo "--------------------------------------"
# 1. 检查RNDIS所需的内核模块并确保 g_ether 未加载
echo "Checking and ensuring 'g_mass_storage' and 'g_ether' are not loaded, then loading 'libcomposite'..."
# 卸载 g_mass_storage
if lsmod | grep -q g_mass_storage; then
echo "Unloading g_mass_storage module..."
modprobe -r g_mass_storage || { echo "WARNING: Failed to unload g_mass_storage. This might cause issues."; }
sleep 1
fi
# 卸载 g_ether
if lsmod | grep -q g_ether; then
echo "Unloading g_ether module..."
modprobe -r g_ether || { echo "WARNING: Failed to unload g_ether. This might cause issues."; }
sleep 1
fi
# libcomposite 是 gadget 框架的基础
if ! lsmod | grep -q libcomposite; then
echo "Loading libcomposite module..."
modprobe libcomposite || { echo "ERROR: Failed to load libcomposite. Exiting."; exit 1; }
fi
# 2. 卸载并清理旧的 gadget 配置 (可选,但推荐在测试时使用以确保干净状态)
if [ -d "${GADGET_ROOT}" ]; then
echo "Disabling existing gadget '${GADGET_NAME}'..."
# 尝试解绑当前的 UDC (如果已经绑定)
if [ -f "${GADGET_ROOT}/UDC" ]; then
current_udc=$(cat "${GADGET_ROOT}/UDC")
if [ -n "$current_udc" ]; then
echo "Unbinding ${current_udc} from previous gadget..."
echo "" > "${GADGET_ROOT}/UDC" # 解绑 UDC
sleep 1
fi
fi
rm -rf "${GADGET_ROOT}" # 删除所有旧的配置
echo "Old gadget configuration removed."
sleep 1
fi
# 3. 创建新的 gadget 配置
echo "Creating new gadget configuration at ${GADGET_ROOT}..."
mkdir -p "${GADGET_ROOT}"
cd "${GADGET_ROOT}" || { echo "ERROR: Failed to cd to ${GADGET_ROOT}. Exiting."; exit 1; }
# 4. 设置设备描述符 (参考官网脚本的值)
echo "Setting device descriptors..."
#echo 0x0955 > idVendor # Linux Foundation (官网脚本值)
#echo 0x7020 > idProduct # Multifunction Composite Gadget (官网脚本中 RNDIS 启用时使用的值)
echo 0x2CA3 > idVendor # Linux Foundation (官网脚本值)
echo 0xF003 > idProduct # Multifunction Composite Gadget (官网脚本中 RNDIS 启用时使用的值)
echo 0x0001 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
echo 0xEF > bDeviceClass # Miscellaneous Device Class
echo 0x02 > bDeviceSubClass # Common Class
echo 0x01 > bDeviceProtocol # Interface Association Descriptor (IAD)
# 5. 设置字符串描述符 (参考官网脚本的值)
echo "Setting string descriptors (Manufacturer, Product, Serial)..."
mkdir -p strings/0x409 # English (0x409)
echo "psdk-rpi4b" > strings/0x409/serialnumber
echo "raspberry" > strings/0x409/manufacturer
echo "PI4" > strings/0x409/product
# 6. 创建配置 c.1
echo "Creating configuration 'c.1'..."
cfg="configs/c.1"
mkdir -p "${cfg}/strings/0x409"
echo 0x80 > "${cfg}/bmAttributes" # Self-powered
echo 250 > "${cfg}/MaxPower" # Max power consumption (250mA)
echo "RNDIS" > "${cfg}/strings/0x409/configuration" # Configuration description
# 7. 配置 RNDIS 功能
echo "Enabling RNDIS function (rndis.usb0)..."
func_rndis="functions/rndis.usb0"
mkdir -p "${func_rndis}"
ln -sf "${func_rndis}" "${cfg}" # Link RNDIS function to configuration c.1
# RNDIS OS Descriptors for Windows auto-detection (参考官网脚本的值)
echo "Setting RNDIS OS Descriptors..."
echo 1 > os_desc/use
echo 0xcd > os_desc/b_vendor_code
echo MSFT100 > os_desc/qw_sign
echo "RNDIS" > "${func_rndis}/os_desc/interface.rndis/compatible_id"
echo 5162001 > "${func_rndis}/os_desc/interface.rndis/sub_compatible_id"
ln -sf "${cfg}" os_desc
# 8. 绑定到 UDC 以激活 Gadget
echo "Activating USB Gadget..."
# 使用 udevadm settle 确保所有设备节点都已创建
udevadm settle -t 5 || :
# 直接将可用的 UDC 设备名称写入 UDC 文件。
# 如果系统有多个 UDC通常会选择第一个可用的。
# 官网脚本也是直接 'ls /sys/class/udc > UDC' 来完成。
UDC_LIST=$(ls /sys/class/udc)
if [ -z "$UDC_LIST" ]; then
echo "ERROR: No USB Device Controller (UDC) found in /sys/class/udc/. Cannot activate gadget."
exit 1
fi
echo "${UDC_LIST%% *}" > UDC # 取第一个 UDC 设备名称
echo "USB Gadget successfully activated on ${UDC_LIST%% *}."
# 9. 配置 RNDIS 网络接口
echo "Configuring RNDIS network interface (usb0)..."
# 等待 usb0 接口出现
echo "Waiting for 'usb0' interface to appear..."
interface_ready=0
for i in $(seq 1 15); do # 等待最多15秒给系统更多时间
if ip link show usb0 &> /dev/null; then
echo "'usb0' interface found."
interface_ready=1
break
fi
sleep 1
done
if [ "$interface_ready" -eq 0 ]; then
echo "ERROR: 'usb0' interface did not appear after 15 seconds. RNDIS network configuration failed."
echo " Check kernel modules ('libcomposite' and 'usb_f_rndis' which is part of g_ether function) and dmesg for errors."
exit 1
fi
# 清理旧的桥接设备 (如果存在)
if ip link show pi4br0 &> /dev/null; then
echo "Removing existing bridge 'pi4br0'..."
brctl delbr pi4br0
sleep 1
fi
/sbin/brctl addbr pi4br0 # 创建一个名为 pi4br0 的网络桥接
/sbin/ifconfig pi4br0 "${NET_IP}" netmask "${NET_MASK}" up # 配置桥接接口的IP地址
/sbin/brctl addif pi4br0 usb0 # 将 RNDIS 接口 usb0 添加到桥接
/sbin/ifconfig usb0 up # 确保 usb0 接口被激活
echo "RNDIS network configured to ${NET_IP} on 'pi4br0' (bridging 'usb0')."
echo "--------------------------------------"
echo "USB Gadget RNDIS setup complete."
echo "Connect your device to a PC."
echo "--------------------------------------"
exit 0