Android14 init.qcom.usb.rc详解

发布于:2025-08-30 ⋅ 阅读:(17) ⋅ 点赞:(0)

本文以高通平台为例,介绍其USB子系统启动以及USB各种配置动态切换的逻辑,它是以configfs架构实现动态配置USB。


相关文档


1. USB子系统的启动

1.1 on boot阶段

1.1.1 重启恢复用户选择的USB配置

当设备重启时恢复用户选择的USB配置,避免每次重启都回到默认模式,如果是第一次开机,则persist.vendor.usb.config为空,则使用默认值(MTP,文件传输)。

恢复的原理:当用户选择了对应的USB配置,例如MTP+adb调试,则系统会设置:setprop persist.vendor.usb.config mtp,adb,该属性被写入 /data/property/persist.vendor.usb.config,而persist属性重启时是不会丢失的。

on boot
    setprop sys.usb.config ${persist.vendor.usb.config}

1.1.2 启用USB gadget HAL来控制USB功能

on boot && property:vendor.usb.use_gadget_hal=1
   setprop sys.usb.configfs 2

✅property:vendor.usb.use_gadget_hal=1表示启动USB gadget HAL来控制USB功能。该属性是高通平台特有的系统属性,取值1表示把USB配置由init.rc交给了Gadget HAL 服务来实现。

✅可以通过以下指令验证是否生效,当前设备的configfs=2,而且usb.gadget的HAL层服务android.hardware.usb.gadget@1.2-service-qti也在运行。

✅何时设置了该属性vendor.usb.use_gadget_hal,在高通平台下是由vendor_product.mk文件中设置该属性值:

// path: Vendor/android/vendor/qcom/opensource/usb/vendor_product.mk
ifneq ($(filter taro kalama neo parrot anorak,$(TARGET_BOARD_PLATFORM)),)
  PRODUCT_PROPERTY_OVERRIDES += vendor.usb.use_gadget_hal=1
  PRODUCT_PACKAGES += android.hardware.usb.gadget@1.2-service-qti
  PRODUCT_PACKAGES += usb_compositions.conf
else
  PRODUCT_PROPERTY_OVERRIDES += vendor.usb.use_gadget_hal=0
endif

如果当前设备的芯片平台是枚举中的其中之一,则设置vendor.usb.use_gadget_hal=1,并打包android.hardware.usb.gadget@1.2-service-qti服务和USB模式配置文件usb_compositions.conf。

✅usb_compositions.conf介绍
该文件列举了vendor支持的VID-PID组合USB

# /vendor/etc/usb_compositions.conf: HSUSB VID PID supported compositions

# <properties>	                            <vid>	<pid>	<actual order of properties>
mass_storage								0x05C6	0xF000
mass_storage,adb							0x05C6	0x9015	adb,mass_storage
...
diag,qdss,rmnet								0x05C6	0x9083	diag,qdss_debug,rmnet
diag,qdss,rmnet,adb							0x05C6	0x9084	diag,qdss_debug,adb,rmnet
...
rndis,diag,diag_mdm,diag_mdm2,qdss,qdss_mdm,serial_cdev,dpl,adb		0x05C6	0x90F9

1.2 on post-fs阶段

1.2.1 只有on post-fs条件

on post-fs:在/data,/dev等关键文件系统挂在完成后执行,主要完成的动作如下:

  • 将内核的configfs文件系统挂载到/config
  • 创建Gadget实例g1(主设备)和g2(备用设备,例如反向充电时用)
  • 设置设备描述符(Strings相关操作)
  • 设置USB协议版本,0x200表示USB2.0,0x300表示USB3.0
  • 启用该Microsoft OS描述符,让 Windows 自动识别设备并加载正确驱动
  • 创建各种USB功能
  • 创建配置#1
  • FunctionFS挂载(用户空间)
  • 设置MTP设备类型为3
  • 执行脚本/vendor/bin/init.qcom.usb.sh
on post-fs
    // 将内核的configfs文件系统挂载到/config 
    mount configfs none /config
    //创建Gadget实例g1(主设备)和g2(备用设备,例如反向充电时用)
    mkdir /config/usb_gadget/g1 0770
    mkdir /config/usb_gadget/g2 0770
    //设置设备描述符,序列号-厂商-产品名
    mkdir /config/usb_gadget/g1/strings/0x409 0770
    mkdir /config/usb_gadget/g2/strings/0x409 0770
    write /config/usb_gadget/g1/strings/0x409/serialnumber ${ro.serialno}
    write /config/usb_gadget/g2/strings/0x409/serialnumber ${ro.serialno}
    write /config/usb_gadget/g1/strings/0x409/manufacturer ${ro.product.manufacturer}
    write /config/usb_gadget/g2/strings/0x409/manufacturer ${ro.product.manufacturer}
    write /config/usb_gadget/g1/strings/0x409/product ${vendor.usb.product_string}
    write /config/usb_gadget/g2/strings/0x409/product ${vendor.usb.product_string}
    //设置USB协议版本,0x200表示USB2.0,0x300表示USB3.0
    write /config/usb_gadget/g1/bcdUSB 0x0200
    write /config/usb_gadget/g2/bcdUSB 0x0200
    //启用该Microsoft OS描述符,让 Windows 自动识别设备并加载正确驱动
    //MSFT100是微软的签名
    write /config/usb_gadget/g1/os_desc/use 1
    write /config/usb_gadget/g1/os_desc/b_vendor_code 0x1
    write /config/usb_gadget/g1/os_desc/qw_sign "MSFT100"
    //创建各种USB功能
    mkdir /config/usb_gadget/g1/functions/mass_storage.0
    mkdir /config/usb_gadget/g1/functions/mtp.gs0
    mkdir /config/usb_gadget/g1/functions/ptp.gs1
    mkdir /config/usb_gadget/g1/functions/accessory.gs2
    mkdir /config/usb_gadget/g1/functions/audio_source.gs3
    mkdir /config/usb_gadget/g1/functions/midi.gs5
    mkdir /config/usb_gadget/g1/functions/ffs.adb
    mkdir /config/usb_gadget/g1/functions/ffs.diag
    mkdir /config/usb_gadget/g1/functions/ffs.diag_mdm
    mkdir /config/usb_gadget/g1/functions/ffs.diag_mdm2
    mkdir /config/usb_gadget/g1/functions/diag.diag
    mkdir /config/usb_gadget/g1/functions/diag.diag_mdm
    mkdir /config/usb_gadget/g1/functions/diag.diag_mdm2
    mkdir /config/usb_gadget/g1/functions/cser.dun.0
    mkdir /config/usb_gadget/g1/functions/cser.nmea.1
    mkdir /config/usb_gadget/g1/functions/cser.dun.2
    mkdir /config/usb_gadget/g1/functions/gsi.rmnet
    mkdir /config/usb_gadget/g1/functions/gsi.rndis
    mkdir /config/usb_gadget/g1/functions/gsi.dpl
    mkdir /config/usb_gadget/g1/functions/qdss.qdss
    mkdir /config/usb_gadget/g1/functions/qdss.qdss_mdm
    mkdir /config/usb_gadget/g1/functions/qdss.qdss_sw
    mkdir /config/usb_gadget/g1/functions/rndis_bam.rndis
    mkdir /config/usb_gadget/g1/functions/rndis.rndis
    mkdir /config/usb_gadget/g1/functions/rmnet_bam.rmnet
    mkdir /config/usb_gadget/g1/functions/rmnet_bam.dpl
    mkdir /config/usb_gadget/g1/functions/rmnet_bam.rmnet_bam_dmux
    mkdir /config/usb_gadget/g1/functions/rmnet_bam.dpl_bam_dmux
    mkdir /config/usb_gadget/g1/functions/ncm.gs6
    mkdir /config/usb_gadget/g1/functions/ccid.ccid
    mkdir /config/usb_gadget/g1/functions/uac2.0
    mkdir /config/usb_gadget/g1/functions/uvc.0
    write /config/usb_gadget/g1/functions/diag.diag/serial ${ro.serialno}
    //创建配置#1
    mkdir /config/usb_gadget/g1/configs/b.1 0770
    mkdir /config/usb_gadget/g2/configs/b.1 0770
    mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770
    mkdir /config/usb_gadget/g2/configs/b.1/strings/0x409 0770
    //设置功率
    write /config/usb_gadget/g1/configs/b.1/MaxPower 900
    //FunctionFS挂载(用户空间)
    mkdir /dev/usb-ffs 0775 shell system
    mkdir /dev/usb-ffs/adb 0770 shell system
    mount functionfs adb /dev/usb-ffs/adb uid=2000,gid=1000,rmode=0770,fmode=0660
    mkdir /dev/ffs-diag 0770 shell system
    mount functionfs diag /dev/ffs-diag uid=2000,gid=1000,rmode=0770,fmode=0660,no_disconnect=1
    mkdir /dev/ffs-diag-1 0770 shell system
    mount functionfs diag_mdm /dev/ffs-diag-1 uid=2000,gid=1000,rmode=0770,fmode=0660,no_disconnect=1
    mkdir /dev/ffs-diag-2 0770 shell system
    mount functionfs diag_mdm2 /dev/ffs-diag-2 uid=2000,gid=1000,rmode=0770,fmode=0660,no_disconnect=1
    //设置MTP设备类型为3
    setprop sys.usb.mtp.device_type 3
    //执行脚本
    exec u:r:vendor_qti_init_shell:s0 -- /vendor/bin/init.qcom.usb.sh

1.2.2 在post-fs和vendor.usb.use_ffs属性为1的条件

on post-fs && property:vendor.usb.use_ffs_mtp=1
   mkdir /config/usb_gadget/g1/functions/ffs.mtp
   mkdir /config/usb_gadget/g1/functions/ffs.ptp
   mkdir /dev/usb-ffs/mtp 0770 mtp mtp
   mount functionfs mtp /dev/usb-ffs/mtp rmode=0770,fmode=0660,uid=1024,gid=1024,no_disconnect=1
   mkdir /dev/usb-ffs/ptp 0770 mtp mtp
   mount functionfs ptp /dev/usb-ffs/ptp rmode=0770,fmode=0660,uid=1024,gid=1024,no_disconnect=1
  • post-fs阶段是文件系统已挂载,可以创建设备节点。
  • vendor.usb.use_ffs_mtp=1表示仅当启用FFS版的MTP时才支持。
  • 主要操作:
  1. 创建usb_gadget/g1实例下的功能目录functions/ffs.mtp和functions/ffs.ptp
  2. 创建用户空间访问目录/dev/usb-ffs/mtp,权限是rwxrwx---,所属用户和组均是mtp
  3. mount functionfs mtp /dev/usb-ffs/mtp ...:mount把内核functions把USB底层时间打包成文件交给用户空间。
  4. 同理ptp配置
参数 含义
mount Linux 系统调用,挂载一个文件系统
functionfs 特殊文件系统,用于用户空间与 USB Gadget 通信
mtp 挂载源(对应 /config/usb_gadget/g1/functions/ffs.mtp
/dev/usb-ffs/mtp 挂载点
rmode=0770 目录权限
fmode=0660 文件权限
uid=1024,gid=1024 强制所有者(通常是 mtp 用户)
no_disconnect=1 关键参数:防止用户空间服务重启时USB断开

1.2.3 各种 USB 功能(Functions)

功能 类型 用途
mass_storage.0 内核态 大容量存储(U盘模式)
mtp.gs0ptp.gs1 内核态 文件传输(MTP)、相机传输(PTP)
accessory.gs2 内核态 Android Accessory 模式(AOA)
audio_source.gs3 内核态 音频输入(如 USB 麦克风)
midi.gs5 内核态 MIDI 设备
uac2.0 内核态 USB Audio Class 2.0
uvc.0 内核态 USB Video Class(摄像头)
ffs.adb 用户态 ADB 调试(通过 FunctionFS)
ffs.diagffs.diag_mdm 用户态 高通诊断端口(diag)
cser.dun.0cser.nmea.1 内核态 串口功能(DUN 拨号、NMEA GPS)
gsi.rmnetgsi.rndisgsi.dpl 内核态 GSI(Generic Signaling Interface)网络
qdss.qdssqdss.qdss_mdm 内核态 QDSS( Qualcomm Debug Support)
rndis.rndisrndis_bam.rndis 内核态 RNDIS(以太网)
rmnet_bam.rmnetrmnet_bam.dpl 内核态 RMNET(高通专有网络)
ncm.gs6 内核态 NCM(网络控制模型)
ccid.ccid 内核态 智能卡接口设备

2 充电模式下USB子系统的启动

适用场景:手机关机但插 USB 线充电,电量极低自动进入充电模式,长按电源键 + 音量下进入“充电画面”。此时 Zygote、System Server、SurfaceFlinger 等核心服务未启动,系统处于极简状态。

  • 将内核的configfs文件系统挂载到/config
  • 只创建Gadget实例g1
  • 设置设备描述符(Strings相关操作)
  • 设置USB协议版本,0x200表示USB2.0,0x300表示USB3.0
  • 只创建mass_storage.0大容量存储功能
  • 创建配置#1
  • 执行脚本/vendor/bin/init.qcom.usb.sh
  • 启用USB大容量存储功能和设置configfs标志
on charger
    mount configfs none /config
    mkdir /config/usb_gadget/g1 0770
    mkdir /config/usb_gadget/g1/strings/0x409 0770
    write /config/usb_gadget/g1/bcdUSB 0x0200
    write /config/usb_gadget/g1/strings/0x409/serialnumber ${ro.serialno}
    write /config/usb_gadget/g1/strings/0x409/manufacturer ${ro.product.manufacturer}
    mkdir /config/usb_gadget/g1/functions/mass_storage.0
    mkdir /config/usb_gadget/g1/configs/b.1 0770
    mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770
    write /config/usb_gadget/g1/configs/b.1/MaxPower 900
    exec u:r:vendor_qti_init_shell:s0 -- /vendor/bin/init.qcom.usb.sh
    write /config/usb_gadget/g1/strings/0x409/product ${vendor.usb.product_string}
    setprop sys.usb.config mass_storage
    setprop sys.usb.configfs 1

3 USB配置切换

高通的usb配置和谷歌默认的init.usb.configfs.rc中动态配置USB状态的方式基本上是一致的,差别有:QC多了很好USB功能,常规功能参考init.usb.configfs.rc的USB动态配置中5.1 sys.usb.config取值

3.1 高通专有的USB配置

取值 含义 用途
diag Qualcomm Diagnostics Port,诊断

读取 Modem、AP、BP 的日志(dmesgerrlog

发送诊断命令(如重启、读寄存器)

获取电池、温度、电压等传感器数据

刷写 EFS、NV 数据

diag_cnss

Diag for CNSS (Connectivity SubSystem)

专门用于 Wi-Fi / Bluetooth / GNSS(GPS)子系统 的诊断。

用于wifi驱动调试,蓝牙连接、GPS定位、射频校准等问题

diag_mdm Diag for Modem (mdm=Mobile Data Modem)

专门用于与基带处理器(modem)通信的诊断通道

读取 Modem 的 dmesgerrlog

获取蜂窝网络日志(RRC、NAS、PHY 层)

抓取通话、短信、注册过程日志

diag_mdm2 Diag for Modem (mdm=Mobile Data Modem)

同diag_mdm,多个诊断是为了支持多SIM卡或者多Modem实例。

diag_mdm:主modem,通常是SIM1

diag_mdm2:副modem,通常是SIM2

serial_cdev

cser(Character Serial)

创建一个虚拟串口设备,

提供类似 UART 的字符设备接口,类似插入一个USB转串口设备

rmnet Remote Networking 高通专有的网络传输通道,这是“通过 USB 使用蜂窝数据上网”的底层通道

dpl

Device Porting Layer

高通专有的高速数据下载通道

刷机(Flashing):下载 boot.imgsystem.img 等

固件升级

qdss

Qualcomm Debug Support Subsystem

芯片级性能分析和跟踪

抓取 CPU 执行轨迹(Instruction Trace)

监控内存访问

分析功耗热点

实时性能 profiling

qdss_mdm QDSS for Modem 

为 Modem 处理器 提供 芯片级性能跟踪和调试

抓取 Modem CPU 的指令执行流

监控内存访问

分析 Modem 任务调度延迟

定位 5G PHY 层性能瓶颈

3.2 高通SOC中多处理器介绍

高通芯片SOC中有多个独立的处理器,运行不同的OS,通过共享内存和IPC通信。

处理器 代号 作用
AP Apps Processor (A55/A7xx) 运行 Android 系统
MP Modem Processor (MDM) 处理 2G/3G/4G/5G 通信
LPASS Audio Subsystem 处理音频
CNSS Connectivity Subsystem 处理 Wi-Fi/蓝牙
SPSS Security Subsystem 处理安全加密

3.3 USB动态配置

以diag,adb的配置为例

  • 更新configuration为”diag_adb“
  • 删除配置#1中链接到functions的符号f1-f9
  • 创建配置#1的软连接,将os_desc/b.1指向configs/b.1
  • 配置USB描述符,将os_desc/b.1指向configs/b.1
  • 将b.1/f1执行内核的diag function
  • 将b.1/f2指向内核的ffs.adb function
on property:sys.usb.ffs.ready=1 && property:sys.usb.config=diag,adb && property:sys.usb.configfs=1
    write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "diag_adb"
    rm /config/usb_gadget/g1/configs/b.1/f1
    rm /config/usb_gadget/g1/configs/b.1/f2
    rm /config/usb_gadget/g1/configs/b.1/f3
    rm /config/usb_gadget/g1/configs/b.1/f4
    rm /config/usb_gadget/g1/configs/b.1/f5
    rm /config/usb_gadget/g1/configs/b.1/f6
    rm /config/usb_gadget/g1/configs/b.1/f7
    rm /config/usb_gadget/g1/configs/b.1/f8
    rm /config/usb_gadget/g1/configs/b.1/f9
    symlink /config/usb_gadget/g1/configs/b.1 /config/usb_gadget/g1/os_desc/b.1
    write /config/usb_gadget/g1/idVendor 0x05C6
    write /config/usb_gadget/g1/idProduct 0x901D
    write /config/usb_gadget/g1/functions/diag.diag/pid 0x901d
    symlink /config/usb_gadget/g1/functions/${vendor.usb.diag.func.name}.diag /config/usb_gadget/g1/configs/b.1/f1
    symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
    write /config/usb_gadget/g1/UDC ${sys.usb.controller}
    setprop sys.usb.state ${sys.usb.config}