Android集成lrzsz

为啥要移植lrzsz

本文中的lrzsz代码点击此处获取
Hikey开发板有两类USB口,两组USB-TypeA母口作为Host,可以接键盘、鼠标。另一组mini-USB母口,作为devices,可以接到电脑上调试。但目前这两种接口无法同时使用,即通过键盘鼠标操作时不能使用ADB。
虽然可以通过minicom或者putty之类的工具连接串口查看LOG、执行命令。但Android系统中缺少通过串口传输文件的工具,有文件传输需求的时候还需要插上ADB口,通过adb push/pull操作,不是太方便。

通过busybox的rx命令虽然可以接收文件,但无法将系统中的文件传输到主机上。而且rx只支持xmodem协议。一些新的工具如Xshell只能支持Zmodem协议。
lrzsz能够同时支持xmodem、ymodem以及zmodem协议,具备发送接收功能,能满足我们的需要。

交叉编译lrzsz

交叉编译分为以下几步:

  1. 准备交叉编译链。

这里面使用的是arm-linux-gnueabihf-4.9。可以到Linaro的主页下载。将下载到的文件解压缩到/opt/目录,设置好环境变量。

[david@opt]$ cd arm-linux-gnueabihf-4.9/bin/
[david@bin]$ export PATH=`pwd`:$PATH
[david@bin]$ arm-linux-gnueabihf-gcc --version
arm-linux-gnueabihf-gcc (Linaro GCC 4.9-2015.01-3) 4.9.3 20150113 (prerelease)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

2下载lrzsz源码
官方主页下载lrzsz软件包 lrzsz-0.12.20.tar.gz 。解压缩。

[david@Code]$ tar -zxvf lrzsz-0.12.20.tar.gz

3./configure:

[david@lrzsz-0.12.20]$ ./configure --host=arm-linux
creating cache ./config.cache
checking for a BSD compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking whether make sets ${MAKE}... yes
checking for working aclocal... found
checking for working autoconf... found
checking for working automake... found
checking for working autoheader... found
checking for working makeinfo... missing
checking for gcc... gcc
checking whether the C compiler (gcc  ) works... yes
checking whether the C compiler (gcc  ) is a cross-compiler... no
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking how to run the C preprocessor... gcc -E
checking whether gcc needs -traditional... no
checking for ranlib... ranlib
checking for POSIXized ISC... no
checking for AIX... no
checking for minix/config.h... no
checking for gcc option to accept ANSI C... none needed
checking for function prototypes... yes
checking for working const... yes
checking for inline... inline
checking for syslog in -lsocket... no
checking for syslog in -lbe... no
checking for gethostbyname in -lnsl... yes
checking for ANSI C header files... yes
checking for fcntl.h... yes
checking for limits.h... yes
checking for sys/ioctl.h... yes
checking for sys/time.h... yes
checking for unistd.h... yes
checking for sys/times.h... yes
checking for termios.h... yes
checking for sys/termios.h... yes
checking for termio.h... yes
checking for sys/termio.h... no
checking for sgtty.h... yes
checking for termios.h... (cached) yes
checking for sys/termios.h... (cached) yes
checking for termio.h... (cached) yes
checking for sys/termio.h... (cached) no
checking for sgtty.h... (cached) yes
checking for sys/mman.h... yes
checking for utime.h... yes
checking for syslog.h... yes
checking for sys/syslog.h... yes
checking for sys/param.h... yes
checking for sys/select.h... yes
checking for strings.h... yes
checking for arpa/inet.h... yes
checking for size_t... yes
checking for mode_t... yes
checking for off_t... yes
checking for speed_t... yes
checking for st_rdev in struct stat... yes
checking whether time.h and sys/time.h may both be included... yes
checking whether sys/time.h and sys/select.h may both be included... yes
checking whether struct tm is in sys/time.h or time.h... time.h
checking for errno declaration... yes
checking whether setvbuf arguments are reversed... no
checking return type of signal handlers... void
checking for unistd.h... (cached) yes
checking for getpagesize... yes
checking for working mmap... yes
checking for working alloca.h... yes
checking for alloca... yes
checking for gettimeofday... yes
checking for settimeofday... yes
checking for strchr... yes
checking for memcpy... yes
checking for select... yes
checking for vprintf... yes
checking for times... yes
checking for rdchk... no
checking for utime... yes
checking for syslog... yes
checking for siginterrupt... yes
checking for mkdir... yes
checking for mktime... yes
checking for strerror... yes
checking for strstr... yes
checking for strdup... yes
checking for strtoul... yes
checking for strtol... yes
checking for strpbrk... yes
checking for stpcpy... yes
checking for strftime... yes
checking for vasprintf... yes
checking for getopt_long... yes
checking for ftime... yes
checking that ftime works correctly... yes
checking for timezone variable... yes
checking for LOG_UUCP... yes
checking for argz.h... yes
checking for limits.h... (cached) yes
checking for locale.h... yes
checking for nl_types.h... yes
checking for malloc.h... yes
checking for string.h... yes
checking for unistd.h... (cached) yes
checking for values.h... yes
checking for sys/param.h... (cached) yes
checking for getcwd... yes
checking for munmap... yes
checking for putenv... yes
checking for setenv... yes
checking for setlocale... yes
checking for strchr... (cached) yes
checking for strcasecmp... yes
checking for __argz_count... yes
checking for __argz_stringify... yes
checking for __argz_next... yes
checking for LC_MESSAGES... yes
checking whether NLS is requested... yes
checking whether included gettext is requested... no
checking for libintl.h... yes
checking for gettext in libc... yes
checking for msgfmt... /usr/bin/msgfmt
checking for dcgettext... yes
checking for gmsgfmt... /usr/bin/msgfmt
checking for xgettext... /usr/bin/xgettext
checking for catalogs to be installed...  de
updating cache ./config.cache
creating ./config.status
creating Makefile
creating intl/Makefile
creating lib/Makefile
creating testsuite/Makefile
creating man/Makefile
creating po/Makefile.in
creating src/Makefile
creating debian/rules
creating Specfile
creating systype
creating src/lrzszbug
creating config.h

4交叉编译

[[email protected]]$ make CC=arm-linux-gnueabihf-gcc LDFLAGS=-static
make all-recursive
make[1]: 正在进入目录 `/data/zx8200/Code/lrzsz-0.12.20'
Making all in lib
make[2]: 正在进入目录 `/data/zx8200/Code/lrzsz-0.12.20/lib'
arm-linux-gnueabihf-gcc -DHAVE_CONFIG_H -I. -I. -I..   -g -O2 -c long-options.c
long-options.c: In function 'parse_long_options':
long-options.c:65:4: warning: incompatible implicit declaration of built-in function 'exit'
    exit (0);
    ^
arm-linux-gnueabihf-gcc -DHAVE_CONFIG_H -I. -I. -I..   -g -O2 -c xstrtol.c
arm-linux-gnueabihf-gcc -DHAVE_CONFIG_H -I. -I. -I..   -g -O2 -c xstrtoul.c
arm-linux-gnueabihf-gcc -DHAVE_CONFIG_H -I. -I. -I..   -g -O2 -c error.c
rm -f libzmodem.a
ar cru libzmodem.a long-options.o xstrtol.o xstrtoul.o error.o 
ranlib libzmodem.a
make[2]:正在离开目录 `/data/zx8200/Code/lrzsz-0.12.20/lib'
Making all in intl
make[2]: 正在进入目录 `/data/zx8200/Code/lrzsz-0.12.20/intl'
make[2]: 没有什么可以做的为 `all'。
make[2]:正在离开目录 `/data/zx8200/Code/lrzsz-0.12.20/intl'
Making all in src
make[2]: 正在进入目录 `/data/zx8200/Code/lrzsz-0.12.20/src'
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c lrz.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c timing.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c zperr.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c zreadline.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c crctab.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c rbsb.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c zm.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c protname.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c tcp.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c lsyslog.c
lsyslog.c: In function 'lsyslog':
lsyslog.c:67:4: warning: incompatible implicit declaration of built-in function 'sprintf'
    sprintf(uid_string,"#%lu",(unsigned long) uid);
    ^
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c canit.c
arm-linux-gnueabihf-gcc -g -O2 -static -o lrz  lrz.o timing.o zperr.o zreadline.o crctab.o rbsb.o zm.o protname.o tcp.o lsyslog.o canit.o ../lib/libzmodem.a  -lnsl 
lsyslog.o:在函数‘lsyslog’中:
/home/zx8200/data_zx8200/Code/lrzsz-0.12.20/src/lsyslog.c:61: 警告: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
tcp.o:在函数‘tcp_connect’中:
/home/zx8200/data_zx8200/Code/lrzsz-0.12.20/src/tcp.c:143: 警告: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c lsz.c
arm-linux-gnueabihf-gcc -g -O2 -static -o lsz  lsz.o timing.o zperr.o zreadline.o crctab.o rbsb.o zm.o protname.o tcp.o lsyslog.o canit.o ../lib/libzmodem.a  -lnsl 
lsyslog.o:在函数‘lsyslog’中:
/home/zx8200/data_zx8200/Code/lrzsz-0.12.20/src/lsyslog.c:61: 警告: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
tcp.o:在函数‘tcp_connect’中:
/home/zx8200/data_zx8200/Code/lrzsz-0.12.20/src/tcp.c:143: 警告: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
make[2]:正在离开目录 `/data/zx8200/Code/lrzsz-0.12.20/src'
Making all in po
make[2]: 正在进入目录 `/data/zx8200/Code/lrzsz-0.12.20/po'
make[2]:正在离开目录 `/data/zx8200/Code/lrzsz-0.12.20/po'
Making all in man
make[2]: 正在进入目录 `/data/zx8200/Code/lrzsz-0.12.20/man'
make[2]: 没有什么可以做的为 `all'。
make[2]:正在离开目录 `/data/zx8200/Code/lrzsz-0.12.20/man'
Making all in testsuite
make[2]: 正在进入目录 `/data/zx8200/Code/lrzsz-0.12.20/testsuite'
make[2]: 没有什么可以做的为 `all'。
make[2]:正在离开目录 `/data/zx8200/Code/lrzsz-0.12.20/testsuite'
make[1]:正在离开目录 `/data/zx8200/Code/lrzsz-0.12.20'

5 编译结果
编译结果位于src目录下,两个静态链接的可执行程序lrz、lsz

[david@lrzsz-0.12.20]$ cd src/
[david@src]$ ls
ansi2knr.1  crctab.c  lrz.o        lsyslog.o  Makefile     protname.o  tcp.o     zglobal.h  zperr.c
ansi2knr.c  crctab.o  lrzszbug     lsz        Makefile.am  rbsb.c      timing.c  zm.c       zperr.o
canit.c     lrz       lrzszbug.in  lsz.c      Makefile.in  rbsb.o      timing.h  zm.o       zreadline.c
canit.o     lrz.c     lsyslog.c    lsz.o      protname.c   tcp.c       timing.o  zmodem.h   zreadline.o
[david@src]$ file lsz
lsz: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, BuildID[sha1]=a81519d2b16f6c6e1cabce75b239567069548047, not stripped
[david@src]$ file lrz
lrz: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, BuildID[sha1]=31108b6d6dceb3f7c44c8d55916ad40628e20406, not stripped
[david@src]$ 

Android集成lrzsz

从前面的编译LOG,我们可以看到lrz、lsz的编译分为下面3个阶段:

  1. 编译libzmodem.a
arm-linux-gnueabihf-gcc -DHAVE_CONFIG_H -I. -I. -I..   -g -O2 -c long-options.c
arm-linux-gnueabihf-gcc -DHAVE_CONFIG_H -I. -I. -I..   -g -O2 -c xstrtol.c
arm-linux-gnueabihf-gcc -DHAVE_CONFIG_H -I. -I. -I..   -g -O2 -c xstrtoul.c
arm-linux-gnueabihf-gcc -DHAVE_CONFIG_H -I. -I. -I..   -g -O2 -c error.c
rm -f libzmodem.a
ar cru libzmodem.a long-options.o xstrtol.o xstrtoul.o error.o 
ranlib libzmodem.a
  1. 编译lrz
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c lrz.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c timing.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c zperr.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c zreadline.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c crctab.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c rbsb.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c zm.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c protname.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c tcp.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c lsyslog.c
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c canit.c
arm-linux-gnueabihf-gcc -g -O2 -static -o lrz  lrz.o timing.o zperr.o zreadline.o crctab.o rbsb.o zm.o protname.o tcp.o lsyslog.o canit.o ../lib/libzmodem.a  -lnsl 
  1. 编译lsz
arm-linux-gnueabihf-gcc -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/usr/local/share/locale\" -I.. -I. -I../src -I../intl -I../lib  -g -O2 -c lsz.c
arm-linux-gnueabihf-gcc -g -O2 -static -o lsz  lsz.o timing.o zperr.o zreadline.o crctab.o rbsb.o zm.o protname.o tcp.o lsyslog.o canit.o ../lib/libzmodem.a  -lnsl 

我们很容易将其翻译为如下的Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
    lib/long-options.c \
    lib/xstrtol.c \
    lib/xstrtoul.c \
    lib/error.c 
LOCAL_MODULE := libzmodem
LOCAL_MODULE_TAGS := optional

LOCAL_C_INCLUDES := $(LOCAL_PATH)

LOCAL_CFLAGS := -DHAVE_CONFIG_H
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
    src/lrz.c \
    src/timing.c \
    src/zperr.c \
    src/zreadline.c \
    src/crctab.c \
    src/rbsb.c \
    src/zm.c \
    src/protname.c \
    src/tcp.c \
    src/lsyslog.c \
    src/canit.c 


LOCAL_MODULE := lrz
LOCAL_MODULE_TAGS := optional tests
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
    $(LOCAL_PATH)/src \
    $(LOCAL_PATH)/lib \
    $(LOCAL_PATH)/intl 

LOCAL_STATIC_LIBRARIES := libc \
    libzmodem \
    libnsl 
LOCAL_CFLAGS := -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/system/etc/locale/\"
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
    src/lsz.c \
    src/timing.c \
    src/zperr.c \
    src/zreadline.c \
    src/crctab.c \
    src/rbsb.c \
    src/zm.c \
    src/protname.c \
    src/tcp.c \
    src/lsyslog.c \
    src/canit.c 


LOCAL_MODULE := lsz
LOCAL_MODULE_TAGS := optional tests
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
    $(LOCAL_PATH)/src \
    $(LOCAL_PATH)/lib \
    $(LOCAL_PATH)/intl 

LOCAL_STATIC_LIBRARIES := libc \
    libzmodem \
    libnsl 

LOCAL_CFLAGS := -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/system/etc/locale/\"
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)

但编译时出现如下的错误,原因是Android系统中没有libnsl库,所以修改config.h,将

#define HAVE_LIBNSL 1

修改为:

#define HAVE_LIBNSL 0

同时删除 Android.mk 中所有的libnsl,即可通过。
最终的Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
    lib/long-options.c \
    lib/xstrtol.c \
    lib/xstrtoul.c \
    lib/error.c 
LOCAL_MODULE := libzmodem
LOCAL_MODULE_TAGS := optional

LOCAL_C_INCLUDES := $(LOCAL_PATH)

LOCAL_CFLAGS := -DHAVE_CONFIG_H
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
    src/lrz.c \
    src/timing.c \
    src/zperr.c \
    src/zreadline.c \
    src/crctab.c \
    src/rbsb.c \
    src/zm.c \
    src/protname.c \
    src/tcp.c \
    src/lsyslog.c \
    src/canit.c 


LOCAL_MODULE := lrz
LOCAL_MODULE_TAGS := optional tests
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
    $(LOCAL_PATH)/src \
    $(LOCAL_PATH)/lib \
    $(LOCAL_PATH)/intl 

LOCAL_STATIC_LIBRARIES := libc \
    libzmodem 
LOCAL_CFLAGS := -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/system/etc/locale/\"
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
    src/lsz.c \
    src/timing.c \
    src/zperr.c \
    src/zreadline.c \
    src/crctab.c \
    src/rbsb.c \
    src/zm.c \
    src/protname.c \
    src/tcp.c \
    src/lsyslog.c \
    src/canit.c 


LOCAL_MODULE := lsz
LOCAL_MODULE_TAGS := optional tests
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
    $(LOCAL_PATH)/src \
    $(LOCAL_PATH)/lib \
    $(LOCAL_PATH)/intl 

LOCAL_STATIC_LIBRARIES := libc \
    libzmodem 

LOCAL_CFLAGS := -DNFGVMIN -DHAVE_CONFIG_H -DLOCALEDIR=\"/system/etc/locale/\"
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)

编译结果:

[david@bin]$ file l*z
lrz: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (SYSV), statically linked, BuildID[md5/uuid]=b140e0a8004a7a3f7f0afaef0a5665d4, stripped
lsz: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (SYSV), statically linked, BuildID[md5/uuid]=b9b832b9b0c416f6980d8492eaed4889, stripped

lrzsz的使用

将前面编译好的lrz、lsz push到hikey开发板上,添加可执行权限。

adb root
adb remount
adb push lrz /system/bin/lrz
adb push lsz /system/bin/lsz
adb shell chmod 777 /system/bin/lrz
adb shell chmod 777 /system/bin/lsz

Windows

Windows系统上常用的串口工具有Xshell、SecureCRT、超级终端、putty等。下面以Xshell为例,描述通过lrz、lsz收发文件的过程。
xshell配置好串口端口号、波特率等参数,连接上串口。

接收文件

在命令行中输入lrz,回车,xshell弹出如下的文件选择界面,
这里写图片描述
选择文件后,点击 open,开始文件传送。
这里写图片描述

发送文件

文件发送流程与前面的接收类似,在命令行中输入”lsz filename”,xshell会自动打开文件保存对话框,选择保存位置。
这里写图片描述
选好存储位置后,点击OK,开始文件发送流程。
这里写图片描述

Linux

Linux可以使用minicom作为串口连接工具。文件收发的流程与xshell基本类似,不过minicom不会自动弹出文件选择/保存对话框,所以稍微繁琐一点。

接收文件

在命令行中输入 lrz,回车。
按快捷键 “CTRL-A Z”,进入minicom的菜单,选择S,发送文件,选择Zmodem协议,在弹出的文件选择界面中,用空格键标记说要传输的文件,按回车开始文件传输流程。
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

发送文件

在命令行输入 “lsz filename”,minicom会自动接收文件.
这里写图片描述

lrzsz的局限性

受限于UART的传输速率,串口的速度很低,按波特率115200计算,每秒理论传输14KB的数据,因此只适合于传输比较小的文件,比如几十KB的文件,大量的文件传输还是需要通过网络或者adb进行。

猜你喜欢

转载自blog.csdn.net/sunao2002002/article/details/52261621