• 旧版本源码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> "
      
  • 相关阅读:
    tushare包使用案例
    Matplotlib模块:绘图和可视化
    pandas使用
    django 表操作
    元数据Meta
    django关系类型字段
    django项目模型字段
    django项目mysite 2
    django安装使用xadmin
    GCC版本中没有GLIBCXX_3.4.15错误
  • 原文地址:https://www.cnblogs.com/chenj-nry/p/14118944.html
Copyright © 2020-2023  润新知