160 lines
5.8 KiB
Bash
160 lines
5.8 KiB
Bash
#!/bin/bash
|
||
apt-get install bridge-utils
|
||
rmmod g_mass_storage
|
||
|
||
|
||
# 定义USB Gadget的根目录
|
||
GADGET_ROOT="/sys/kernel/config/usb_gadget/nanopi"
|
||
|
||
# *** 重要:请根据你的实际情况修改这个值! ***
|
||
# 你可以通过运行 'ls /sys/class/udc/' 命令来查看可用的 UDC 设备名称。
|
||
# 常见的名称有:musb-hdrc.0, musb-hdrc.4.auto, ci_hdrc.0, 20a00000.usb
|
||
UDC_DEVICE="musb-hdrc.4.auto"
|
||
|
||
# 确保脚本以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. 卸载并清理旧的 gadget 配置 (可选,但推荐在测试时使用以确保干净状态)
|
||
if [ -d "${GADGET_ROOT}" ]; then
|
||
echo "Disabling existing gadget '${GADGET_ROOT##*/}'..."
|
||
# 尝试解绑当前的 UDC (如果已经绑定)
|
||
# 这需要先进入 gadget 目录,然后才能 echo "" > 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
|
||
|
||
# 2. 进入 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; }
|
||
|
||
# 3. 设置设备描述符
|
||
echo "Setting device descriptors..."
|
||
echo 0x0955 > idVendor # FriendlyElec's Vendor ID (or your preferred)
|
||
echo 0x7020 > idProduct # Product ID for NanoPi-NEO-Core (or your preferred)
|
||
echo 0x0100 > bcdDevice # Device Version 1.0 (0x0100)
|
||
echo 0x0200 > bcdUSB # USB 2.0 (0x0200)
|
||
|
||
# RNDIS 复合设备通常使用特定的设备类/子类/协议
|
||
echo 0xEF > bDeviceClass # Miscellaneous Device Class
|
||
echo 0x02 > bDeviceSubClass # Common Class
|
||
echo 0x01 > bDeviceProtocol # Interface Association Descriptor (IAD)
|
||
|
||
# 4. 设置字符串描述符
|
||
echo "Setting string descriptors (Manufacturer, Product, Serial)..."
|
||
mkdir -p strings/0x409 # English (0x409)
|
||
|
||
# 获取设备树中的序列号,如果没有则使用默认值
|
||
if [ -f /proc/device-tree/serial-number ]; then
|
||
serialnumber="$(cat /proc/device-tree/serial-number|tr -d '\000')"
|
||
else
|
||
serialnumber="1234567890ABCD" # Default serial number
|
||
fi
|
||
echo "${serialnumber}" > strings/0x409/serialnumber
|
||
echo "FriendlyElec" > strings/0x409/manufacturer
|
||
echo "NanoPi-NEO-Core" > strings/0x409/product
|
||
|
||
# 5. 创建配置 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 Ethernet" > "${cfg}/strings/0x409/configuration" # Configuration description
|
||
|
||
# 6. 配置 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 # Link configuration c.1 to os_desc
|
||
|
||
# 7. 绑定到 UDC 以激活 Gadget
|
||
echo "Activating USB Gadget on UDC: ${UDC_DEVICE}..."
|
||
# Check if UDC device exists in /sys/class/udc/
|
||
if [ -e "/sys/class/udc/${UDC_DEVICE}" ]; then
|
||
echo "${UDC_DEVICE}" > UDC
|
||
echo "USB Gadget successfully activated."
|
||
else
|
||
echo "ERROR: UDC device '${UDC_DEVICE}' not found in /sys/class/udc/."
|
||
echo " Please check your UDC_DEVICE variable and 'ls /sys/class/udc/' output."
|
||
exit 1
|
||
fi
|
||
|
||
# 8. 配置 RNDIS 网络接口
|
||
echo "Configuring RNDIS network interface (usb0)..."
|
||
NET_IP="192.168.55.1"
|
||
NET_MASK="255.255.255.0"
|
||
|
||
# 等待 usb0 接口出现
|
||
echo "Waiting for 'usb0' interface to appear..."
|
||
interface_ready=0
|
||
for i in $(seq 1 10); do # 等待最多10秒
|
||
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 10 seconds. RNDIS network configuration failed."
|
||
echo " Check kernel modules (g_ether, usb_f_rndis) and dmesg for errors."
|
||
exit 1
|
||
fi
|
||
|
||
# 检查并安装 bridge-utils (如果需要)
|
||
if ! command -v brctl &> /dev/null; then
|
||
echo "WARNING: 'brctl' command not found. Please install 'bridge-utils' package."
|
||
echo " (e.g., 'sudo apt install bridge-utils' on Debian/Ubuntu)"
|
||
# 如果没有 brctl,尝试直接配置 usb0 接口,但不推荐
|
||
echo "Attempting to configure 'usb0' directly (without bridge)..."
|
||
ifconfig usb0 "${NET_IP}" netmask "${NET_MASK}" up
|
||
echo "RNDIS network configured to ${NET_IP} on usb0 directly."
|
||
else
|
||
# 清理旧的桥接设备 (如果存在)
|
||
if ip link show zzbr0 &> /dev/null; then
|
||
echo "Removing existing bridge 'zzbr0'..."
|
||
brctl delbr zzbr0
|
||
fi
|
||
|
||
brctl addbr zzbr0 # 创建一个名为 zzbr0 的网络桥接
|
||
ifconfig zzbr0 "${NET_IP}" netmask "${NET_MASK}" up # 配置桥接接口的IP地址
|
||
brctl addif zzbr0 usb0 # 将 RNDIS 接口 usb0 添加到桥接
|
||
ifconfig usb0 up # 确保 usb0 接口被激活
|
||
|
||
echo "RNDIS network configured to ${NET_IP} on 'zzbr0' (bridging 'usb0')."
|
||
fi
|
||
|
||
echo "--------------------------------------"
|
||
echo "USB Gadget RNDIS setup complete."
|
||
echo "Connect your device to a PC."
|
||
echo "--------------------------------------"
|
||
|
||
exit 0
|