zoukankan      html  css  js  c++  java
  • 旧版本源码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> "
      
  • 相关阅读:
    洛谷p1017 进制转换(2000noip提高组)
    Personal Training of RDC
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Eurasia
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Peterhof.
    Asia Hong Kong Regional Contest 2019
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Siberia
    XVIII Open Cup named after E.V. Pankratiev. Ukrainian Grand Prix.
    XVIII Open Cup named after E.V. Pankratiev. GP of SPb
    卜题仓库
    2014 ACM-ICPC Vietnam National First Round
  • 原文地址:https://www.cnblogs.com/chenj-nry/p/14118944.html
Copyright © 2011-2022 走看看