`

Android Prelink实现的源码分析

 
阅读更多
 

1.    原理简介

1)        Prelink
Prelink
即预链接技术是利用事先链接以代替运行时链接的技术,以加快共享库的加载速度,它不仅能加快程序启动时间,还可以减少部分内存开销(它能使KDE的启动时间减少50%)。每次程序执行时,进行的链接动作都是一样的,链接相对来说开销很大,尤其是嵌入式系统。

2)        普通Linux系统的Prelink
Redhat
系统中prelink工具(/etc/cron.dialy/prelink)会修改可执行程序,把它与所需库的链接信息加入可执行程序。在程序运行时,使用glibc(glibc > 2.3.1-r2)中的ld-linux.so来进行链接。用此方式,每次更新动态库后,使用它的程序都需要重新prelink,因为新库中的符号信息,地址等很可能与原来不同了。

3)        AndroidPrelink
Android
源码中有一组map文件,其中定义了需要预连接的动态库,其Prelink信息以及对应的逻辑地址(4G地址空间中位置),在动态库编译时,预处理程序apriori根据map文件中的定义,生成预链接信息重定向信息,并加入这些二进制文件lib*.so的末尾。它主要节约了查询函数地址等工作所用的时间,动态库重定位的开销。在运行程序,动态库加载时,加载程序linker判断动态库是否为Prelink的,如果是的话,就在首次使用时将其加载到指定的内存空间,直接使用预编译信息。

2.    源码分析

1)        动态库的编译脚本

a)         源代码
frameworks/base/media/libmedia/Android.mk
等库的编译选项文件

b)        配置
可在Android.mk中设置该库是否需要Prelink,默认是使用Prelink的,也可设置成否,方法如下:
LOCAL_PRELINK_MODULE := false

c)         分析
此设置只用于动态库的编译,编译时用showcommands参数即可看到具体编译使用到的命令行,如在某个库的目录中运行mm showcommands,即可看到相应的Prelink操作,示例如下:
target Prelink: libxxx
out/host/linux-x86/bin/apriori --prelinkmap build/core/prelink-linux-arm-2G.map --locals-only --quiet xxx.so --output xxx.so
如果该库设置为需要prelink,则也需要在map文件中加入相应项,否则编译不通过

2)        内核

a)         源码
kernel/arch/arm/configs/xxx_defconfig
arch/arm/mach-msm/include/mach/vmalloc.h

b)        配置
CONFIG_VMSPLIT_2G=y   
一般默认为3G/1G,此项即设置为2G/2G

c)         分析
xxx_defconfig
为默认的内核配置文件(修改其中的CONFIG_VMSPLIT_*),也可通过make menuconfig配置,与Prelink相关的主要是指定用户空间和内核空间内存如何分配4G的虚拟内存空间(Memory split),一般有三种方式:3G/1G2G/2G1G/3G(user/kernel),一般默认的是用户空间3G(0x0-0xBFFFFFFF),内核空间1G(0xC0000000 - 0xFFFFFFFF)

d)        内存分析示例,以3G/1G为例(build/core/prelink-linux-arm.map)
0xC0000000 - 0xFFFFFFFF Kernel
0xB0100000 - 0xBFFFFFFF Thread 0 static
0xB0000000 - 0xB00FFFFF Linker
0xA0000000 - 0xBFFFFFFF Prelinked System Libraries
0x90000000 - 0x9FFFFFFF Prelinked App Libraries
0x80000000 - 0x8FFFFFFF Non-prelinked Libraries
0x40000000 - 0x7FFFFFFF mmap’s stuff
0x10000000 - 0x3FFFFFFF Thread Stacks
0x00000000 - 0x0FFFFFFF .text / .data / heap

3)        map文件

a)         源代码
build/core/prelink-linux-<arch>*.map

b)        配置
编译时有多个map文件可先,根据不同的硬件平台及内存分配(3G/1G, 2G/2G)修改系统配置device/*/BoardConfig.mk选择使用不同的map文件.
prelink-linux-arm-2G.map, prelink-linux-arm.map
系统中每加入一个需要prelink的动态库,需要在map文件添加相应的项

c)         分析
在用户空间,共定义了三块与链接相关地址间空
系统库分配的内存:Prelinked System Libraries
应用库分配的内存:
Prelinked App Libraries
prelink库分配的内存:Non-prelinked Libraries

d)        map文件规则
需要在 build/core/prelink-linux-arm.map 中加入形如libhellod.so 0x96000000
手工指定某个库相应的prelink地址范围,库应用对齐1M边界,注意库与库之间的间隔数,如果指定不好编译的时候会提示说地址空间冲突的问题。另外,注意排序,这里要把数大的放到前面去,按照大小降序排序。

4)        apriori程序

a)         源代码
build/tools/apriori/*

b)        配置
device/*/BoardConfig.mk
中设置
TARGET_USES_2G_VM_SPLIT := true 
以配置Prelink的地址空间

c)         分析
apriori
中的prelinkmap.c它用根据整个系统设置device/*/BoardConfig.mk的内存分配规则(3G/1G, 2G/2G)来判断map中指定地址是否符合Prelink的地址空间范围,如果正常,则在so的末尾加入prelink信息和标识(文件以PRE结束)
apriori
可以预先为若干共享库确定加载地址,并为有依赖关系的共享库做静态重定位和连接该命令加入参数--verbose,即可显示出prelink的细节。

5)        linker程序

a)         源代码
bionic/linker/*
(bionic
目录中存放一些基础的库,如libc, libstdc++, libthread_db, linker)

b)        分析
linker
Android的专用动态链接库键接器,Linker和传统Linux使用的linker(ld.so,ld-linux.so.2,ld-linux.so.3)有所不同。库的编译参数-dynamic-linker指定了键接器为/system/bin/linker(也可以手动换成别的)该信息将被存放在ELF文件的.interp节中,内核执行目标映像文件前将通过该信息加载并运行相应的解释器程序linker,并链接相应的共享库,共享库以ELF文件的形式保存在文件系统中核心的load_elf_binary会首先将其映像文件映射到内存,然后映射并执行其解释器也就是linker的代码。linker的代码段是进程间共享的,但数据段为各进程私有。
所有外部过程引用都在映像执行之前解析Android中的共享库和可执行映像都默认采用ELF格式的文件程序头表包含了加载到内存中的各种段的索引及属性信息,它将告诉加载器如何加载映像,初始化时,动态链接器首先解析出外部过程引用的绝对地址,一次性的修改所有相应的GOT表项。
linker会在共享库加载时,调用is_prelinked查看该库是否是prelink的,并在alloc_mem_region中检查目的地址是否被占用。如果该库不是prelink的,则库加载的起始地址为零。

3.    参考文档:

1)        动态库优化——Prelink(预连接)技术
http://www.eefocus.com/article/09-04/71629s.html

2)        Android build system note - 一醉千年 - CSDN博客
http://blog.csdn.net/yili_xie/archive/2009/12/01/4906865.aspx

3)        Linux, Android基础知识总结
http://wenku.baidu.com/view/f68fc029647d27284b735100.html

4)        android Linker浅析
http://blog.csdn.net/dinuliang/archive/2010/04/20/5509009.aspx

分享到:
评论

相关推荐

    前端开源库-prelink

    前端开源库-prelink预链接,symlink您的模块,以保持项目使用的干净和独立来源

    2010年谢彦的android笔记

    原创2010年android文档的整理打包的pdf档(含目录) ...4.10 Prelink实现的源码分析 142 4.11 适配硬件平台 145 4.12 其他介绍 147 4.12.1 手机保护Keyguard 147 4.12.2 空中升级Fota 148 4.12.3 Flash分区 149

    Prelink--一种Linux下加速程序启动的技术研究.pdf

    Prelink--一种Linux下加速程序启动的技术研究.pdf

    prelink:用于与 PreLink 实验室信息系统交互的 SOAP Web 服务客户端

    用于与 PreLink 实验室信息系统交互的 SOAP Web 服务客户端 配置 在 config/ 下创建一个 prelink.yml 文件,其中包含以下详细信息: wsdl_url - The URL for the WSDL of the PreLink Server station_id - Your ...

    android笔记.rar

    android笔记.doc ...4.10 Prelink实现的源码分析 ... ...142 4.11 适配硬件平台... .145 4.12 其他介绍... ...147 4.12.1 手机保护Keyguard ... .147 4.12.2 空中升级Fota... .148 4.12.3 Flash分区 ... .149

    prelink-0.5.0-9.el7.x86_64.rpm

    官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装

    openssl-1.0.2o_android_arm64_jnilib

    LOCAL_PRELINK_MODULE := false LOCAL_CPPFLAGS := \ -DWITH_DOM -DWITH_OPENSSL \ -D__ANDROID__ \ -DNULL=0 -DSOCKLEN_T=socklen_t -DNO_SSTREAM -DBSD=1 -DNO_SSTREAM -fexceptions -DANDROID -DXLOCALE_NOT_...

    免费prelink耐克鞋机器人从最好的bots.com。「free prelink Nike shoe bot from best-bots.com」-crx插件

    允许用户添加一个早期的耐克链接,并将添加到购物车当产品可用。 来自BEST-BOTS.COM的免费启动程序最快的早期链接添加到购物车中允许用户添加早期的Nike链接,并在产品可用时使用...支持语言:English (United States)

    free prelink Nike shoe bot from best-bots.com-crx插件

    语言:English (United States) 允许用户添加早期的nike链接,并将添加到购物车添加到购物车(产品可用) free bot frees-bots.com 最快的早期链接加入购物车Bot 允许用户添加早期的耐克链接,并在产品可用时添加到...

    BHE-be-ui-v2

    node .\scripts\prelink.js yarn link @bheui\components 从BHE be v1创建 第一次提交2018-01-17。 待办事项MVP: 设定地区 测验 TODO的下一个功能 文件 刷新令牌功能 页面预加载 更好的数据视图布局

    iHuzuCMS狐族内容管理系统 v1.0 Beta12

    新增上一页、下一页信息内容({ihuzu:prelink}、{ihuzu:prename}、{ihuzu:nextlink}、{ihuzu:nextname}) [1.0.7.2] 优化全站生成系统,使用防出错处理,在未预见的错误出现时能继续运行系统 [1.0.7.3] 优化创建...

    狐族内容管理系统(iHuzuCMS) 1.0 beta12

    新增上一页、下一页信息内容({ihuzu:prelink}、{ihuzu:prename}、{ihuzu:nextlink}、{ihuzu:nextname}) [1.0.7.2] 优化全站生成系统,使用防出错处理,在未预见的错误出现时能继续运行系统 [1.0.7.3] 优化创建...

    苹果8XPC和手机二合一完整版

    ****************************模板规范化管理 开始**************************** ... 每个模版都可定义不同的样式,所以系统内置的功能的相关文件也都放在了模版里,每个模版里存储一份,避免替换系统目录下的其他文件...

Global site tag (gtag.js) - Google Analytics