旧版本源码usbip的移植

前言

  • 由于工作需要usb透传功能,所以记录下移植usbip过程中遇到的难题和解决办法,可以给自己以后的移植工作做个参考,也可以给正在移植usbip的困惑者给点帮助。

  • 这里先玩玩usbip的功能,后续博客再对usbip的原理进行解析

概述

  • usbip是一种利用以太网,将usb设备(键鼠、U盘等)共享到另一端网络驱动,提供了USB透传的功能(类似于USB延长线)

  • usbip刚开始是一个独立的项目(http://usbip.sourceforge.net),后来合并到linux分支下

    • 旧版本Linux源码中在drivers/staging/usbip,用户测试源码在该目录下的userspace/目录下

    • 新版本Linux源码中在drivers/usb/usbip,用户测试源码在tools/usb/usbip下

    • 对于windows下,也有类似的开源项目,可能Windows上的用途会比较广,github路径为:https://github.com/cezanne/usbip-win

移植工作

准备工作

  • 材料: Ubuntu12.04、 3352板子(内核源码3.2.0)、 交叉编译工具(这里是TI源码6.0.0中的4.7.3交叉编译工具)

  • 虚拟机和3352板子需要先ping通,百度上很多文章有讲到,这里不多说

3352移植(遇见的问题在下边汇总)

  • 编译驱动:

    • 可以选择编进内核或者编成模块,在源码根目录执行make menuconfig,在 Device Drivers ---> [*] Staging drivers ---> --- Staging drivers 下进行选择

    • 编进内核的话将新内核镜像烧写到板子上,编成模块则有usbip-core.ko,usbip-host.ko和vhci-hcd.ko,insmod到板子上

  • 编译用户测试源码:

    • 事先安装一些依赖文件
     sudo apt-get install autoconf automake libtool libudev-dev libsysfs-dev
    
    • 进入用户测试程序目录userspace/下,运行./autogen.sh,生成configure

    • 接下来执行经典“三部曲”:./configure、make和make install, 重点需要对configure的参数进行配置正确,不然会出现很多问题,我自己参考ti写了一个配置脚本build.sh(结尾有ti脚本的内容),执行./build.sh

        #!/bin/sh
        # build the CDVS Test Model
        # with full optimizations and multithreading:
        export CFLAGS=" -march=armv7-a  -marm -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8 --sysroot=/home/book/sysroots/armv7ahf-vfp-neon-3.2-oe-linux-gnueabi"
        export LDFLAGS=' --sysroot=/home/book/sysroots/armv7ahf-vfp-neon-3.2-oe-linux-gnueabi'
        export CPATH="/home/book/sysroots/armv7ahf-vfp-neon-3.2-oe-linux-gnueabi/usr/include"
        export PATH="$PATH:/home/book/sysroots/armv7ahf-vfp-neon-3.2-oe-linux-gnueabi/usr/bin:/home/book/sysroots/i686-arago-linux/usr/bin"
      
        mkdir -p build
        CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ LD=arm-linux-gnueabihf-ld AR=arm-linux-gnueabihf-ar AS=arm-linux-gnueabihf-as NM=arm-linux-gnueabihf-nm STRIP= RANLIB=arm-linux-gnueabihf-strip       OBJDUMP=arm-linux-gnueabihf-objdump ./configure  --target=arm-linux-gnueabihf  --host=arm-linux-gnueabihf --build=i686-linux --with-libtool-sysroot=/home/book/sysroots/armv7ahf-vfp-neon-3.2-oe-linux-gnueabi   --prefix=$HOME/usbip_build
      
        # build all binaries
        make
        # install all binaries in $HOME/bin (no need of admin priviledges)
        make install
      
    • 交叉编译工具的详细信息

        book@www.100ask.org:~$ arm-linux-gnueabihf-gcc -v
        Using built-in specs.
        COLLECT_GCC=/home/book/sysroots/i686-arago-linux/usr/bin/arm-linux-gnueabihf-gcc
        COLLECT_LTO_WRAPPER=/home/book/sysroots/i686-arago-linux/usr/bin/../libexec/gcc/arm-linux-gnueabihf/4.7.3/lto-wrapper
        Target: arm-linux-gnueabihf
        Configured with: /cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/src/gcc-linaro-4.7-2013.03/configure 
        --build=i686-build_pc-linux-gnu 
        --host=i686-build_pc-linux-gnu
        --target=arm-linux-gnueabihf
        --prefix=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/install 
        --with-sysroot=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/install/arm-linux-gnueabihf/libc 
        --enable-languages=c,c++,fortran 
        --enable-multilib 
        --with-arch=armv7-a 
        --with-tune=cortex-a9 
        --with-fpu=vfpv3-d16 
        --with-float=hard 
        --with-pkgversion='crosstool-NG linaro-1.13.1-4.7-2013.03-20130313 - Linaro GCC 2013.03' 
        --with-bugurl=https://bugs.launchpad.net/gcc-linaro 
        --enable-__cxa_atexit 
        --enable-libmudflap 
        --enable-libgomp 
        --enable-libssp 
        --with-gmp=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static 
        --with-mpfr=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static 
        --with-mpc=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static 
        --with-ppl=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static 
        --with-cloog=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static 
        --with-libelf=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static 
        --with-host-libstdcxx='-L/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/.build/arm-linux-gnueabihf/build/static/lib -lpwl' 
        --enable-threads=posix 
        --disable-libstdcxx-pch 
        --enable-linker-build-id 
        --enable-gold 
        --with-local-prefix=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-linux/install/arm-linux-gnueabihf/libc 
        --enable-c99 
        --enable-long-long 
        --with-mode=thumb
        Thread model: posix
        gcc version 4.7.3 20130226 (prerelease) (crosstool-NG linaro-1.13.1-4.7-2013.03-20130313 - Linaro GCC 2013.03)
      
    • 脚本说明:

      • 首先是CFLAGS,该选项为C编译器选项,里边定义的变量为后续configure需要用到的,-march选项是交叉编译工具中选项--with-arch的值armv7-a;选项-marm指定arm指令集; 选项-mthumb-interwork是生成的目标文件允许在ARM和Thumb之间交叉调用; -mfloat-abi对应交叉编译工具选项--with-float的值hard; 选项-mfpu是CPU类型编译器,根据自己需求选择; 选项-mtune指定的是目标处理器的名称,这里3352板子是cortex-a8; 由于ti的交叉编译工具是将执行文件和库文件分开,因此需要特别指定库文件根目录,即设置参数--sysroot,该选项是指定逻辑目录,在这里是/home/book/sysroots/armv7ahf-vfp-neon-3.2-oe-linux-gnueabi。(重点是选项-match、-mtune和--sysroot,其他的选项视实际情况指定)

      • 常用的CPU类型编译器选项

      • LDFLAGS添加库搜索目录,CPATH添加头文件搜索目录,PATH添加交叉编译工具的执行目录

      • --target和--host指定目标机的运行环境,这里为arm-linux-gnueabihf, --build选项是指定在哪里编译该环境,这里是Ubuntu12.04,为i686(命令uname -a可以查看),--prefix指定编译后的安装目录

      • 到这里配置结束,之后make、 make install 完成编译和安装,一般都不会正常的结束,出现的问题在后边进行汇总

    • 编译成功后在配置时选项prefix的指定目录下有相应文件,将整个文件打包到3352开发板上,进入sbin目录下执行文件,若出现链接不到库文件的情况,将usbip目录中的lib路径加到/etc/ld.so.conf中,执行ldconfig即可

Ubuntu12.04上的编译

  • Ubuntu12.04本机上已经有usbip驱动了(目录:/lib/modules/`uname -r`/kernel/drivers/staging/usbip),所以不用自己编译成模块

  • 对于想自己手动编译内核的话,进入usbip/目录,将Makefile修改后编译即可

     KERN_DIR = /usr/src/linux-headers-3.5.0-25-generic/  #源码目录
    
     all:
             make -C $(KERN_DIR) M=`pwd` modules
     clean:
             make -C $(KERN_DIR) M=`pwd` modules clean
             rm -rf modules.ordes
    
     ccflags-y := -DDEBUG
    
     obj-m += usbip-core.o
     usbip-core-y := usbip_common.o usbip_event.o
    
     obj-m += vhci-hcd.o
     vhci-hcd-y := vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o
    
     obj-m += usbip-host.o
     usbip-host-y := stub_dev.o stub_main.o stub_rx.o stub_tx.o
    
    
  • 编译用户测试源码:

    • 由于Ubuntu12.04的版本比较旧,如果直接执行 sudo apt-get install usbip来安装usbip的话,可能会出现版本不兼容的情况,因此需要手动安装

    • 安装对应板子内核版本的源码(3.2.0),并执行初始化配置

        sudo apt-get install linux-source-3.2.0
      
        sudo tar -xjvf /usr/src/linux-source-3.2.0/linux-source-3.2.0.tar.bz2
      
        cd linux-source-3.2.0/drivers/staging/usbip/userspace
      
        sudo ./autogen.sh
      
    • 接下来就是配置和安装了,但有个注意点,就是./configure后会产生一个config.h文件,里边包含了一些版本的信息,需要对版本信息进行确认,在3352板子上执行usbip version可以查到信息,我这里是usbip (usbip-utils 1.1.1),因此不需要改动,如果网络两边的版本不一致,可能会出现“usbip: debug: usbip_network.c:149:[usbip_net_recv_op_common] version mismatch: 262 273”通讯不了的情况

    • 配置和安装

        # sudo sed -i 's%USBIP_VERSION 0x00000111%USBIP_VERSION 0x00000106%g'  config.h (这里示范:1.1.1版本改为1.0.6,不需要改动的可以跳过)
      
        # sudo ./configure --prefix=/usr --sysconfdir=/etc
      
        # sudo make install
      
    • 加载模块

        modprobe -l |grep usbip
      
        sudo modprobe -a usbip-core usbip-host vhci-hcd
      
    • 需要进行开机设定的可以写入/etc/modules

        # sudo vim /etc/modules
      
        #+++++++++++++++++++++++++++++++++++++++++
        usbip-core
        usbip-host
        vhci-hcd
        #+++++++++++++++++++++++++++++++++++++++++
      

测试例子

说明

  • 服务端是插入Usb设备的一端,而客户端是获取usb设备信息的一端,例如,在服务端插入USB鼠标,当客户端和服务端连接后,就可以在服务端上操作客户端桌面,类似远程连接

Server

  • 服务端需要插入的模块是usbip-core.ko和usbip-host.ko

  • 命令解析

    usbipd -D  #启动后台守护进程
    
    usbip list -l  #罗列插入的usb设备,注意busid(2-1.1)
    - busid 2-1.1 (046d:c077)
      Logitech, Inc. : M105 Optical Mouse (046d:c077)
    
    usbip bind -b 2-1.1  #绑定设备
    usbip: info: bind device on busid 2-1.1: complete
    
    usbip unbind -b 2-1.1  #解绑设备
    usbip: info: unbind device on busid 2-1.1: complete
    

client

  • 客户端需要插入的模块是usbip-core.ko和vhci-hcd.ko

  • 命令解析

    #usbip list –r <server端ip地址>
    usbip list -r 192.168.202.150
    
    #usbip attach -r <server端ip地址> -b <busid>
    usbip attach -r 192.168.202.150 -b 2-1.1
    
    #usbip detach-p <port>
    usbip detach -p 0
    

测试结果

  • 在服务端3352板子上插入USB设备,可以对客户端的Ubuntu进行操作,换做U盘时出现Ubuntu识别到挂接,但找不到挂载点(猜想是虚拟机VM的问题),暂时没解决

  • 在服务端Ubuntu上挂接U盘,在客户端3352板子上可以看到挂接的目录和文件内容

缺陷

  • 将服务端的USB设备拔插,需要重新执行连接命令才能使用,热拔插支持不是很好

问题汇总

运行./autogen.sh时出现 Missing /usr/include/sysfs/libsysfs.h

  • 缺少相关的库,运行sudo apt-get install libsysfs-dev

  • 对于头文件的缺失,由于头文件的名字是以lib开头的,可以大胆猜测是缺少某些库,百度下就会有

  • 如果安装后还出现找不到的情况,检查对应路径文件是否存在,存在则用sudo增加权限

configure配置时出现的错误

  • configure执行不成功时会把错误信息保留在config.log文件中

  • 对于找不到一些类似于.o、-lc链接不上的情况,看下configure时链接库路径有没有出错

  • pkg-config版本太老的问题,执行sudo apt-get install pkg-config 更新pkg配置,并且将PATH环境变量中将自己添加的部分放在系统变量的后边

运行时出现cannot open "/usr/share/hwdata/usb.ids", No such file or directory

  • 这个没影响的,只是用于识别设备驱动的名称

  • 解决办法:将Ubuntu12.04相应位置的usb.ids复制到开发板相应位置上即可

连接时出现error: recv op_common

  • 出现这个问题一般就是断连的情况

  • 检查客户端是否绑定成功,再运行下绑定设备的命令,确定是否绑定成功

  • 检查USB硬件上是否松动,执行多次罗列设备的命令,看看是否会出现经常查不到当前USB设备的情况(我自己的USB设备硬件就是松动,多次查询后就找不到设备)

连接时出现error:sorry, it's a bug!

  • 这个在移植过程中只碰到过一次,猜想是库文件的问题,可能要考虑重新编译用户测试程序

Ti的参考脚本

  • Ti的东西有很多是可以学习的,不妨去看看Ti的SDK

  • 环境初始化脚本

    SDK_PATH="/home/aspeed/ti-sdk-am335x-evm-06.00.00.00/linux-devkit"
    if [ -z "$ZSH_NAME" ] && [ "x$0" = "x./environment-setup" ]; then
       echo "Error: This script needs to be sourced. Please run as \". ./environment-setup\""
       exit 1
    else
       if [ -n "$BASH_SOURCE" ]; then
           SDK_PATH="`dirname $BASH_SOURCE`"
       fi
       SDK_PATH=`readlink -f "$SDK_PATH"`
       export SDK_PATH
    fi
    export SDK_SYS=i686-arago-linux
    export TARGET_SYS=armv7ahf-vfp-neon-3.2-oe-linux-gnueabi
    export TOOLCHAIN_SYS=arm-linux-gnueabihf
    export TOOLCHAIN_PREFIX=$TOOLCHAIN_SYS-
    export SDK_PATH_NATIVE=$SDK_PATH/sysroots/$SDK_SYS
    export SDK_PATH_TARGET=$SDK_PATH/sysroots/$TARGET_SYS
    export PATH=$SDK_PATH_NATIVE/usr/bin:$PATH
    export CPATH=$SDK_PATH_TARGET/usr/include:$CPATH
    export PKG_CONFIG_SYSROOT_DIR=$SDK_PATH_TARGET
    export PKG_CONFIG_PATH=$SDK_PATH_TARGET/usr/lib/pkgconfig
    export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1
    export CONFIG_SITE=$SDK_PATH/site-config-$TARGET_SYS
    export CC=${TOOLCHAIN_PREFIX}gcc
    export CXX=${TOOLCHAIN_PREFIX}g++
    export GDB=${TOOLCHAIN_PREFIX}gdb
    export CPP="${TOOLCHAIN_PREFIX}gcc -E"
    export NM=${TOOLCHAIN_PREFIX}nm
    export AS=${TOOLCHAIN_PREFIX}as
    export AR=${TOOLCHAIN_PREFIX}ar
    export RANLIB=${TOOLCHAIN_PREFIX}ranlib
    export OBJCOPY=${TOOLCHAIN_PREFIX}objcopy
    export OBJDUMP=${TOOLCHAIN_PREFIX}objdump
    export STRIP=${TOOLCHAIN_PREFIX}strip
    export CONFIGURE_FLAGS="--target=$TARGET_SYS --host=$TARGET_SYS --build=i686-linux --with-libtool-sysroot=$SDK_PATH_TARGET"
    export CPPFLAGS=" -march=armv7-a    -marm -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8 --sysroot=$SDK_PATH_TARGET"
    export CFLAGS="$CPPFLAGS"
    export CXXFLAGS="$CPPFLAGS"
    export LDFLAGS=" --sysroot=$SDK_PATH_TARGET"
    export OECORE_NATIVE_SYSROOT=$SDK_PATH_NATIVE
    export OECORE_TARGET_SYSROOT=$SDK_PATH_TARGET
    export OECORE_ACLOCAL_OPTS="-I $SDK_PATH_NATIVE/usr/share/aclocal"
    export OECORE_DISTRO_VERSION="2013.05"
    export OECORE_SDK_VERSION="2013.05"
    export OE_QMAKE_CFLAGS="$CFLAGS"
    export OE_QMAKE_CXXFLAGS="$CXXFLAGS"
    export OE_QMAKE_LDFLAGS="$LDFLAGS"
    export OE_QMAKE_CC=$CC
    export OE_QMAKE_CXX=$CXX
    export OE_QMAKE_LINK=$CXX
    export OE_QMAKE_AR=$AR
    export OE_QMAKE_LIBDIR_QT=$SDK_PATH_TARGET/usr/lib
    export OE_QMAKE_INCDIR_QT=$SDK_PATH_TARGET/usr/include/qtopia
    export OE_QMAKE_MOC=$SDK_PATH_NATIVE/usr/bin/moc4
    export OE_QMAKE_UIC=$SDK_PATH_NATIVE/usr/bin/uic4
    export OE_QMAKE_UIC3=$SDK_PATH_NATIVE/usr/bin/uic34
    export OE_QMAKE_RCC=$SDK_PATH_NATIVE/usr/bin/rcc4
    export OE_QMAKE_QDBUSCPP2XML=$SDK_PATH_NATIVE/usr/bin/qdbuscpp2xml4
    export OE_QMAKE_QDBUSXML2CPP=$SDK_PATH_NATIVE/usr/bin/qdbusxml2cpp4
    export OE_QMAKE_QT_CONFIG=$SDK_PATH_TARGET/usr/share/qtopia/mkspecs/qconfig.pri
    export OE_QMAKE_STRIP="echo"
    export QMAKESPEC=$SDK_PATH_TARGET/usr/share/qtopia/mkspecs/linux-g++
    #export PS1="\[\e[32;1m\][linux-devkit]\[\e[0m\]:\w> "
    
posted @ 2020-12-11 17:38  回忆浅唱  阅读(1436)  评论(0编辑  收藏  举报