更全的杂志信息网

Linux程序向Android平台移植的研究

更新时间:2009-03-28

0 引言

Android是Google公司在2007年发布的一款基于Linux内核的开源操作系统。经过不断地发展,该操作系统不仅在移动设备上迅速普及[1],在其它领域的使用率也逐渐增多,延伸到电视盒、桌面设备甚至工控机器。但在这些拓展领域上,Android操作系统的应用生态极为贫乏。如果能够移植现有的Linux程序到Android平台,则能够加速Android平台在各个领域的应用。Linux系统一般情况下指的是GNU/Linux操作系统,它是由GNU工程创建的一系列软件工具包,与Linux内核组合在一起形成的操作系统 [2] ,可安装在各种硬件设备中。Linux系统经过长时间的发展,拥有丰富的软件资源[3],可满足各种领域的需求。

目前Linux程序向Android平台移植主要采用基于交叉编译的方法。基于交叉编译的移植方法为嵌入式系统制作程序的常用方法,就是在一个平台上通过编译器编译另一个平台上的可执行程序的方法[4]。对于Android平台,最常用的交叉编译工具是Google开发的Android NDK或GCC交叉编译器。论文“移植Tcpdump到Android手机捕获无线数据包的方法研究”[5]中就使用Android NDK进行移植。由于Android中的C运行库是Bionic,而Linux程序均使用Glibc库进行编程,Bionic库与Glibc库具有较大不同,所以该方法需要对编译选项和目标程序代码进行适当的修改来适配Android的Bionic库。因此该方法只适合依赖程序库少且代码量较小的程序,对于依赖很多程序库或者代码量太大的程序使用Android NDK移植并不现实。GCC交叉编译器虽然可以使用Glibc库,从而不用大量修改程序的代码,但是它需要程序提供静态编译选项且移植过程繁杂。以Linux系统中的CUPS程序为例,它依赖的程序库数量非常多,并且很多依赖程序甚至没有静态编译选项,以至于无法利用GCC交叉编译器进行静态编译。所以已有的移植方法不能满足移植Linux程序到Android平台的要求,需要一个更可行的移植方法。

针对Linux程序向Android平台移植的问题,本文从应用程序二进制接口(Application Binary Interface,ABI)层面分析了Linux和Android平台的差异,提出一种基于ABI兼容技术的移植方法。

1 平台的ABI差异分析

应用程序二进制接口描述了应用程序和操作系统之间,或一个应用和它的依赖库之间,或应用的组成部分之间的低层接口[6]。ABI包含各种细节:如系统调用约定、可执行程序的格式、程序依赖库、数据类型的规定以及系统目录结构等内容。在ABI兼容的系统中,编译好的程序可以直接运行,无需改动目标程序代码且无需重新编译。比较ABI兼容性的前提是操作系统可以运行在相同处理器架构的硬件兼容环境中,否则无法比较。比如ARM 架构下的 Linux 系统可以与 ARM 架构下的 Android系统比较ABI兼容性。由于 Linux 系统与 Android 系统都能在主流处理器架构下运行,所以不存在某个处理器架构下的Android系统没有对应Linux 系统的情况。因此本文的讨论不限于某个处理器架构,并且只需要在操作系统层面讨论Linux和Android操作系统的ABI差异。

1.1 系统调用

Linux和Android可分为用户态和内核态两个部分,从该角度看Linux和Android的系统架构,如图1所示。应用程序运行在用户态,系统调用是内核态与用户态交互的接口。在内核态中,两种系统使用的都是Linux内核。但Android中的Linux内核与标准Linux内核不完全相同,其保留原有信号等机制的同时添加了Binder IPC、Ashmem等机制[7]。对比Android的Linux内核分支源码和标准Linux内核源码,发现X86、ARM等构架对应的系统调用均完全相同,则说明Android的Linux内核与标准Linux内核的系统调用保持一致。因此在相同处理器架构设备上的Linux系统或者Android系统,其系统调用的约定是一致的。比如:X86上的Linux程序想在X86上的Android系统中运行,系统调用部分是兼容的。

  

图1 Linux和Android系统架构

1.2 系统目录结构

由于Linux系统和Android系统都使用了Linux内核,所以内核态中的ABI基本相同。在用户态,有一个重要ABI差异就是系统目录结构。

Linux中的系统目录结构遵循文件系统层次化标准(Filesystem Hierarchy Standard,FHS)[8]。FHS标准规定了系统不同目录里存放的内容,如:/var目录存放系统运行时要改变的数据、/etc目录用来存放程序配置文件。但是Android没有遵循FHS标准,Android中没有/var目录、应用程序没有/etc目录的读写权限。因此系统目录结构不一致会导致程序运行时出现无法创建或打开文件的错误。

1.3 可执行程序的格式

中间的ABI兼容层由三个子模块组成,分别是Change Root模块 、Bash环境模块和程序依赖模块。Change Root模块通过Proot工具重定向目录结构,在一个封闭的环境里提供与Linux系统一致的目录结构;Bash环境模块使用Busybox工具集[12]提供满足POSIX标准的Shell环境,提供程序所需的Shell命令;程序依赖模块通过程序依赖关系分析技术提供Linux目标程序所需的全部动态依赖库。三个模块共同组成的ABI兼容层提供了Linux目标程序完整的执行环境,使得Linux目标程序能够在Android平台正常运行。

1)脚本程序即用Shell等脚本语言编写的程序。脚本程序通常被其它程序调用,来辅助完成其它程序的功能。Linux上的脚本程序遵循POSIX标准。POSIX表示可移植操作系统接口,是UNIX系统的一个设计标准,其中包括对Shell脚本的规定。对于这类程序,需要使用脚本解释器执行,比如:Bash解释器可以用来解释执行Shell脚本。脚本解释器文件本身则属于第二种ELF程序类别。因此Linux程序在Android平台运行需要解决的是ELF程序的执行。

1)以目标程序编译后的输出文件夹为起点,扫描里面所有的ELF动态链接文件;

图3中的步骤描述如下:

1.4 程序依赖库

程序依赖库指的是一系列为了简化编程复杂度、提高开发效率,对系统调用进行包装的函数集合。程序依赖库在Linux中编译后就是后缀为so的ELF共享库文件。ELF共享库文件也被称为动态链接库,因为动态链接的ELF可执行文件在启动的时候需要加载链接其依赖的共享库文件。例如:图1中的Glibc和Bionic库。Linux中程序的C运行库是Glibc,而Android中的C运行库则是Bionic。基于Glibc库开发的动态链接程序要想在Android平台上运行,如果不修改源代码适配Bionic库,就必须把Glibc共享库文件也移植过去。

ELF动态链接程序的文件结构如图2所示,包含ELF头(ELF header)、程序头表(Program header table)、中间若干段section和节区头表(Section header table)。其中.dynamic段记录了该ELF程序动态链接信息。该段里的DT_NEED类型的项记录了其依赖的共享库文件的位置,动态链接库解释器通过该项字段便能找到其依赖的全部动态链接库。

  

图2 ELF动态链接程序文件结构

2 ABI兼容的关键技术分析

通过前面的分析可知,Linux和Android平台程序的ABI兼容问题主要是系统目录结构一致性问题和可执行程序的加载和链接问题。这两个问题分别可以通过目录结构重定向技术和程序依赖关系分析技术解决。

2.1 目录结构重定向

为了解决系统目录结构的差异,可使用目录结构重定向技术在Android上构造Linux中的系统目录结构。目录结构重定向指改变程序执行时包括根目录在内的目录文件位置,或使得程序只看见指定的目录文件。在Linux系统里有两个机制能够重定向目录结构,Namespace机制和Change Root机制。

Namespace是Linux内核里的一种机制,提供一种包括目录在内的资源隔离功能,但是由于很多Android设备厂商在编译内核时没有开启namespace机制,所以使用Namespace机制不能保证对所有Android设备可用。

Change Root机制指改变程序执行根目录的机制。Change Root机制最常见的实现是Chroot,它是Unix类系统中的一个操作命令。在Linux系统中,它的功能由Linux内核实现,通过系统调用的形式提供,并且使用者需要拥有Root权限。Chroot工具通常用来限制程序的可读写文件,保护系统安全。如“在Solaris环境下通过实现Chroot增进系统安全性”论文中的应用[10],正是利用Chroot的特性创建一个封闭的环境,在里面提供程序所需的所有文件。

但是Chroot有个限制,它需要Root权限才能够使用。相比之下,可以使用一个名为Proot的工具[11],能够在用户态实现Chroot的功能。它的原理与Chroot不同,它通过Ptrace系统调用,实现父进程控制子进程的执行过程,从而改变运行时的根目录。Proot的出现拓宽了Change Root机制的应用场景。尤其在Android系统中,应用程序通常无法获取Root权限,这时可以使用Proot工具代替Chroot完成目录结构重定向的功能。

为了使Linux动态编译的程序能够在Android平台上运行,首先需要移植Linux中的动态链接库解释器“ld-linux.so”,Linux动态编译的程序便能通过它在Android平台上加载进入内存。其次,动态链接库解释器会链接其依赖的全部动态链接库文件。本文使用程序依赖关系分析技术来解决程序的依赖文件问题。

从图2中已经了解到ELF动态链接文件和共享库的依赖信息记录在.dynamic段里。在Linux系统中有一个ldd命令,它能够调用程序动态链接库解释器查看该文件.dynamic段里的动态链接信息。借助ldd命令便能分析出程序的依赖关系。但存在ELF文件里的动态链接信息所指向的目标是一个软链接,软链接经过若干次链接,指向最终的动态链接文件。因此程序依赖关系分析的流程如图3所示。

2.2 程序依赖关系分析

为了确保铁路运输企业全面预算管理的顺利推进,应该强化铁路运输企业全面预算管理的基础工作。铁路运输企业的管理层在管理过程中应该坚持全面预算管理理念,充分运用全面预算管理这种集成管理模式,对铁路运输企业的业务管理和财务管理活动进行整合。同时,应该完善铁路运输企业的内部控制管理制度、财务会计核算制度、全面预算管理制度等,加强对与预算相关的各项基础数据的全面记录、统计以及核算分析等,为预算管控提供良好基础。此外,还应该加强内部的信息化管理,对预算编制、执行、监控以及评估进行动态管理。

综上所述,为膝关节前交叉韧带断裂患者采取核磁共振成像技术的效果较好,能够较为准确的进行诊断,值得临床推广和运用。

这里给出依赖关系的数学描述:设有关系模式R(U),其中U{A1A2,...,An}是关系的属性全集,XYU的属性子集,设tu是关系R上的任意两个元组,如果tuX的投影t[X]=u[X]推出t[Y]=u[Y],即:t[X]=u[X]=>t[Y]=u[Y],则称X决定Y,或Y依赖于X。记为X->Y

在Linux中,ELF动态链接程序之间的依赖关系表现为,关系模式R(U),其中U{A1,A2,...,An}是系统全部的ELF动态链接程序,XYU中任意两个ELF动态链接程序子集,如果在某个条件t下总能从t[X]=u[X]推出t[Y]=u[Y],则说明两个动态链接程序具有依赖关系。这样的依赖关系在ELF程序间普遍存在,依赖关系的实现依靠ELF动态链接程序文件里的动态链接信息和软链接文件。

翅片减薄之后满足了产品重量以及性能的需求,却增加了生产制造的难度,如果翅片设计不合理,在实际钎焊过程中,将导致产品垮塌,增加生产制造的难度。因此,如何增加减薄翅片的强度十分关键,这也是铝质板翅式换热器生产制造的关键工艺技术之一。

11月7日至9日,三天两夜,来自76个国家和地区的政府代表、国际组织代表、中外互联网企业领军人物、知名专家学者等约1500名嘉宾齐聚乌镇,纵论全球互联的历史,共话数字世界的未来。“物联网”“数字经济”“5G”“人工智能”成为第五届世界互联网大会中最耀眼的名词,它们让人类与未来连接,并由此畅想未来。

  

图3 程序依赖关系分析流程图

在Android应用层,采用的是Android应用程序包(Android application package,APK)格式,它在安装到系统后由ART虚拟机解释执行,而Android底层仍然使用ELF可执行文件,且ELF文件格式和Linux系统中的相同。由于Android中的动态链接库解释器与Linux系统中的解释器不同,并且缺少对应的动态链接库,实际上Linux中的大部分ELF程序并不能在Android系统直接执行。

2)Linux系统里的ELF程序主要是指利用C/C++等语言编写的程序,这类程序需要经过编译链接,生成ELF格式文件才能执行。ELF文件有三类:可执行文件、共享库文件和重定位文件[9]。其中的可执行文件和共享库文件是程序运行时需要的文件,ABI兼容需要解决这两种文件的执行问题。ELF可执行程序在编译链接时有动态链接和静态链接两种方式。静态链接的程序将依赖函数与程序本身打包在一起,而动态链接的程序需要在启动的时候读取指定路径的共享库文件才可以运行。

2.营造青年价值观教育的有利环境。青年的价值观总是在现实的具体的环境中形成和发展的,环境因素对青年价值观的形成、发展和青年价值观教育活动起着重要作用。环境因素的影响,既有物质层次的也有精神层次的。社会政治因素可以明显地引起价值观的变化,文化因素则是潜移默化地感染青年的思想观念。比如,“钓鱼岛事件”会使青年特意关注政治问题,激发青年的爱国主义热情,在这个时机给予青年正确的价值观教育,往往事半功倍。而中国的传统文化长期以来以风俗习惯、道德观念等形式积淀在社会成员心中,并在日常生活中始终发挥着作用。

2)读取.dynamic段里的动态链接信息,依次查找里面记录的依赖文件。

3)将查找到的文件复制到指定位置,如果该文件是ELF文件,则读取该文件里的动态链接信息,进入递归;如果是软链接文件,则找到最终指向的ELF文件,然后递归读取。

3 基于ABI兼容技术的移植方法

3.1 移植方法的实现

基于ABI兼容的移植方法框架如图4所示。整体结构分为左右两个部分,左边是Linux目标程序部分,即需要移植的程序,右边是Android控制程序部分,Android控制程序用于操作目标程序。

最底层是Android系统的Linux内核,移植的程序需要与Android系统共享一个内核。Linux目标程序通过ABI兼容层越过Android Framework层直接与Linux内核进行系统调用操作。

Linux系统中的可执行程序可以分为脚本程序和ELF(Executable and Linking Format)程序两种[9]

  

图4 移植方法的框架

在Linux系统中程序原有的控制方式是命令行,但是在Android系统中以这种用户不友好的方式运行程序不合适,所以本文提出的方法通过编写一个Android应用程序,实现图形界面控制到目标程序命令控制转换的功能,使用者就能够通过Android控制程序这个中间层实现对目标程序的控制操作。

设备维修保养工作的好坏,对设备运行状态有着重要的影响,如透平油的处理,润滑油的加注,设备轮换运行,甚至设备吹灰等清洁工作,每一项都不应该忽视。我厂的调速器为进口产品,对油质要求相当高,因此采取现场循环滤油,故障率比以前明显减少,大大提高了设备的可靠性,延长了设备的寿命周期。对设备存在的缺陷应及时消除处理,做到大缺陷不过天,小缺陷不过班,确保设备处于健康运行状态。对设备进行较全面的状态监督和技术分析,掌握设备的实际运行情况,废除一些不必要的检修项目,从而可以节省大量的检修工期。

图5是目标程序的运行流程。使用者操作Android控制程序,由Android控制程序通过命令行方式直接向内核发送fork系统调用,从而启动Linux目标程序。然后Linux目标程序运行在Change Root模块所创建的进程中,并且能够从程序依赖模块获取所依赖的共享库文件。以及在需要的时候通过Bash环境模块运行Shell命令,从而完成目标程序的全部功能。

陶冶教育法突出表现了受教育者的主体性和教育者的主导性,这两者的作用相互贯通,不可分离。受教育者实现主体性的前提是教师发挥其主导性,教育者主导性的体现就是高中生主体性的发挥。

  

图5 目标程序的运行流程

3.2 CUPS程序移植测试

CUPS是Unix/Linux下的开源打印系统,提供一整套完善的打印方案,拥有USB打印、网络打印等功能。本文以移植Linux中的CUPS程序到OPENTHOS系统为例,验证本文提出的移植方法。OPENTHOS系统是清华大学、同方股份有限公司、一铭软件股份有限公司联合开发以Android-x86为基础的开源桌面操作系统。移植CUPS程序到OPENTHOS系统是整个OPENTHOS项目的一个重要部分,为该系统提供打印功能。

在OPENTHOS中运行移植的CUPS程序,并通过ps命令查询系统中的进程。部分查询结果如图6所示,其中名为cupsd的条目代表CUPS程序的进程,说明CUPS程序正在系统中运行。用USB接口连接上HP P1108打印机,并运行安装在OPENTHOS系统上的文本处理程序WPS,使用其中的打印功能。移植的程序能够正常识别HP P1108打印机,并且成功打印出WPS里的文本,打印结果与预览中的效果一致,说明CUPS打印程序在OPENTHOS系统上运行正常。

在过去的2018年,尽管汽车工业正在发生巨大转型,格劳博仍然成功巩固了牢靠的市场地位,凭借的正是领先的技术和机床,以及传统动力总成技术和新电动驱动设备的优化组合。面对即将到来的2019年,格劳博已经对市场的转变做好了充分的准备,坚信这必将又会是收货满满的一年,并且在未来获得持续成功。     

  

图6 进程列表截图

3.3 移植方法对比

通过整理实验数据得到本文方法与基于交叉编译的移植方法的对比表格1。从中可以看到,本文提出的基于ABI兼容的移植方法,相比基于交叉编译的方法,由于需要移植程序依赖的动态库,所以占用空间稍微大了一些,但是本文提出的方法不需要修改目标程序的代码,因此支持更多的程序、降低了移植的复杂度。由于ABI兼容不需要重新编译程序,所以在相同处理器构架下的设备中能够使用闭源程序。但是,本文提出的方法还有一些不足,比如:若目标程序没有提供命令行操作接口,那么这个程序很难使用本文的方法移植,但是这样的程序在Linux系统中很少见。另外在不同的处理器构架下闭源驱动不能使用,这个问题以后可以考虑加入X86等处理器架构的模拟器来运行闭源部分的程序,比如名为Bochs的开源X86平台模拟器可以在ARM上运行X86程序。

 

表1 移植方法的对比

  

基于交叉编译的方法基于ABI兼容的移植方法适用的程序小型程序绝大部分程序闭源程序不支持同构架下支持修改代码需要不需要移植复杂度复杂简单

4 结论

本文首先分析了Linux和Android系统在ABI兼容上的主要差异,然后分析了消除ABI差异的技术:目录结构重定向和程序依赖关系分析技术。在此基础上,本文提出基于ABI兼容技术的移植方法,并将Linux系统中的CUPS程序成功移植到基于Android的OPENTHOS系统。本方法适用于一般的Linux平台的程序,并优于基于交叉编译的移植方法。希望本文提出的改进方法能够对需要把Liunx程序向Android平台移植的工作者提供一点帮助和启示。

虽然很多初中地理教师在进行具体教学的过程中,能够意识到不同学生在智力以及知识接受能力上会有所不同,但却依旧使用最为传统的应试教育方法进行初中地理科目的教学,不能充分认识到针对学生特点应用差异教学方法所发挥的重要作用。同时,在具体教学过程中灵活应用差异教学,需要教师全面了解班级每一位学生的特点,以及学生在地理科目学习中存在的问题,同时还要结合班级的实际情况,将差异教学的理论落实成为教学的有效策略,这些工作对于习惯了应用传统方法进行教学的教师来说难度较大,并不能在短时间内高质量高效率地完成。

参考文献

[1] 贡知洲, 路昭亮. Android发展的分析与研究[J]. 价值工程, 2013, 32(2):185-186.

[2] Mackinnon J G. The Linux operating system: Debian GNU/Linux[J]. Journal of Applied Econometrics, 1999, 14(4):443-52.

[3] 李其锋, 李 兵. 开源软件开发者的演化研究[J]. 计算机科学, 2015, 42(12):43-46.

[4] 张欢庆, 高 丽, 宋承祥. 基于ARM的嵌入式Linux交叉编译环境的研究与实现[J]. 计算机与数字工程, 2012, 40(2):151-153.

[5] 胡锦晖, 胡大斌. 移植Tcpdump到Android手机捕获无线数据包的方法研究[J]. 无线通信技术, 2015, 24(1):6-10.

[6] 黄聪会, 陈 靖, 罗 樵,等. 面向二进制移植的虚拟化技术[J]. 计算机应用研究, 2012, 29(11):4185-4188.

[7] 梁 超. Android内核与标准Linux内核对比分析[J]. 工业设计, 2012(2):74-74.

[8] Hierarchy F S. Linux Standard Base[Z]. 2015.

[9] 黄 进. Linux应用二进制兼容技术的研究与实现[D]. 哈尔滨:国防科学技术大学, 2003.

[10] 苏 雅, 王 钢, 巴特尔. 在Solaris环境下通过实现chroot增进系统安全性[J]. 内蒙古工业大学学报:自然科学版, 2003, 22(4):289-292.

[11] cedric-vincent,Proot项目主页[EB/OL].http://proot.me,2017.

[12] 邵长彬, 李洪亮. 用Busybox制作嵌入式Linux根文件系统[J]. 微计算机信息, 2007, 23(29):48-50.

 
何兴鹏,刘钊远,陶琛嵘
《计算机测量与控制》2018年第05期文献

服务严谨可靠 7×14小时在线支持 支持宝特邀商家 不满意退款

本站非杂志社官网,上千家国家级期刊、省级期刊、北大核心、南大核心、专业的职称论文发表网站。
职称论文发表、杂志论文发表、期刊征稿、期刊投稿,论文发表指导正规机构。是您首选最可靠,最快速的期刊论文发表网站。
免责声明:本网站部分资源、信息来源于网络,完全免费共享,仅供学习和研究使用,版权和著作权归原作者所有
如有不愿意被转载的情况,请通知我们删除已转载的信息 粤ICP备2023046998号