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

    2. Android上的现状

    (1)prelink-linux-arm.map

    这个文件在Android源码中好像自2009年之后就不存在了,最后的一个见:https://gerrit.unlegacy-android.org/plugins/gitiles/Unlegacy-Android/android_build/+/8f83fce7f1084c5dff2f8fa99d3fdff6e045726b/core/prelink-linux-arm.map

    (2)LOCAL_PRELINK_MODULE

    这个是Android编译时mk文件里面可以指定的,可以决定编译so时是否启用prelink,该值设置为true要生效的前提是要在prelink-link-arm.map中定义so的偏移位置,但是好像Android 4.2之后就没有这个map文件了。(引用:《Android build系统中常用的LOCAL_变量》)

    (3)仅适用于系统应用开发者,原因是这种机制必须要有系统支持才行实现

    适用于Android的系统开发者,用来定制系统级的动态库,加速定制的android的系统的启动及加载速度。由于嵌入式设备尤其是android设备,目前的升级比较频繁,一旦prelink过的库函数修改过了,要求所有引用该库函数的可执行文件也要被重新编译。这就要求系统开发者谨慎的修改系统代码,毕竟每次OTA升级的代价还是很大的。

    (4)主要由于安全性方面的考虑,在最新版本的各个系统中都已经放弃了prelink技术:

      参考PPT内容:《Dynamic-prelink》《Dynamic-prelink yoon esa14 slides

    3. 一点体会

    这种prelink机制的核心原理是由Android系统Linker(或者Linux系统的prelink进程)去帮忙做地址的预先分配与计算,省去一般动态库那种动态so地址分配以及导出符号表的地址查找与计算的过程,这样一来每个so中存储的导出符号都是预先已经计算好的符号绝对地址了,而不是未决的(导出)偏移地址。从而起到提高动态库加载速度的目的。

    正因为如此,必须要系统级的支持才能实现,不可能由某个应用级APP来自行控制。

  • 相关阅读:
    数据库之完整性约束
    数据库之数据类型
    数据库之表操作,数据操作
    mysql数据库之基本操作和存储引擎
    MySQL数据库之安装
    并发编程之socketserver模块
    python并发编程之IO模型
    [BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】
    [BZOJ 1046] [HAOI2007] 上升序列 【DP】
    [BZOJ 1816] [Cqoi2010] 扑克牌 【二分答案】
  • 原文地址:https://www.cnblogs.com/kuliuheng/p/12195960.html
Copyright © 2011-2022 走看看