Android Prelink实现的源码分析

LOCAL_PRELINK_MODULE和prelink-linux-arm.map LOCAL_PRELINK_MODULE         Prelink利用事先链接代替运行时链接的方法来加速共享库的加载,它不仅可以加快起动速度,还可以减少部分内存开销, 是各种Linux架构上用于减少程序加载时间、缩短系统启动时间和加快应用程序启动的很受欢迎的一个工具。程序运行时的 动态链接尤其是重定位(relocation)的开销对于大型系统来说是很大的。         动态链接和加载的过程开销很大,并且在大多数的系统上, 函数库并不会常常被更动, 每次程序被执行时所进行的链接 阅读详情

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.    源码分析

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/1G,2G/2G,1G/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 - 一醉千年 - 优快云博客
http://blog.youkuaiyun.com/yili_xie/archive/2009/12/01/4906865.aspx

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

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

避坑指南:STM32H7不同DMA控制器(MDMA/DMA2D/BDMA)到底该用哪个? 本文深入解析STM32H7系列芯片的DMA控制器选型策略,涵盖MDMA、DMA2D、BDMA等不同控制器的架构原理与性能对比。通过实际项目案例,提供高速TCM数据搬运、GUI加速、低功耗传输等场景的选型决策树,并分享性能优化与调试技巧,帮助工程师避开常见陷阱,提升系统效率。 阅读详情

相关推荐

小智AI MCP协议实战:从语音指令到设备响应的完整链路拆解

本文深入拆解了小智AI MCP协议在智能语音交互中的完整工作流程。通过一个“调节音量”的真实场景,详细阐述了从语音采集、云端AI意图理解与决策,到MCP协议下的工具调用、设备端执行,最终完成语音反馈的每一个技术环节。文章重点分析了MCP协议如何通过标准化的交互模型,解决AI意图与设备控制间的“最后一公里”通信难题,实现高效可靠的设备响应。

defi6farmer的博客 248

Android中的prelink技术

背景<br />  在Android中添加自己的库文件,在编译时会提示:library 'XXX.so' not in prelink map 错误, 这就是表明Android中应用了prelink技术,那么什么是prelink呢,它有什么用? 怎样在Android中添加自己的动态库呢?  好,下面一一解答.<br /> 参考文章<br />http://blog.youkuaiyun.com/ccskyer/archive/2010/06/18/5677553.aspx<br />http://www.eefocus

zzqhost的专栏 5618

本地部署ComfyUI:开源AI生图与视频生成完整实战指南

在生成式AI应用快速普及的今天,云端工具常受制于排队、积分和素材管理等问题,而本地化部署正成为开发者与创作者的高效替代方案。其核心思路是基于开源工作流引擎,将图像生成、视频生成与后期处理整合到同一套可离线运行的系统中。ComfyUI作为当前最受关注的节点式工作流平台,凭借灵活的模块组合和强大的自定义能力,降低了从图像模型调用到视频扩展的工程门槛。本文从环境配置与依赖安装入手,系统讲解如何部署ComfyUI、加载Checkpoint模型、跑通文生图基础流程,再通过自定义节点接入视频生成能力,同时介绍API批量

weixin_30985047的博客 569

使用 Prelink 加速程序启动

一、什么是预链接? 1.1 Prelink 简介 Prelink 是 Red Hat 开发者 Jakub Jelinek 所设计的工具。正如其名字所示,Prelink 利用事先链接代替运行时链接的方法来加速共享库的加载。它不仅可以加快起动速度,还可以减少部分内存开销,是各种 Linux 架构上用于减少程序加载时间、缩短系统启动时间和加快应用程序启动的很受欢迎的一个工具。 Linux 系统运行时的动态链接尤其是重定位 (Relocation) 的开销,对于大型系统来说是很大的。相比之下,早期 UNIX

gezi322的专栏 1753

从S参数到SPICE模型:Cadence Sigrity Boardband SPICE完整使用指南

本文详细介绍了Cadence Sigrity Boardband SPICE工具的核心价值与完整使用流程。该工具通过矢量拟合算法,将复杂的多端口S参数文件转化为无源、紧凑且高精度的SPICE等效电路模型,从而极大提升时域仿真效率。指南涵盖了从数据导入、关键参数配置、模型精度验证到集成应用于PowerSI等系统级仿真的全步骤,是信号与电源完整性分析的必备利器。

defi6farmer的博客 432

从零开始利用MATLAB进行FPGA设计(六)用ADC采集信号教程1

用AN9238采集信号的方法(1),包含PLL、FIFO、ILA的基础教程。

WZT725的博客 3094

Linux系统中的内存划分-- VM split

内核内部,尤其是关于内存管理,是一个庞大而复杂的内容,可以说花上一辈子时间来研究内核中内存管理部分都不夸张。

zyqash的博客 1259

WPF实战:HelixToolkit 3D图形开发入门指南

本文详细介绍了如何使用HelixToolkit在WPF中进行3D图形开发,从环境搭建到创建第一个3D程序(如彩色立方体),再到进阶技巧和常见问题排查。通过实战案例和性能优化建议,帮助开发者快速掌握3D场景构建和模型导入技术,提升开发效率。

weixin_29197051的博客 758

Android prelink

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

liusiyun的专栏 1624

YOLOv11+BiFPN双向特征金字塔:全方位解析多尺度检测性能优化指南

飞书链接:https://ecn6838atsup.feishu.cn/wiki/EhRtwBe1CiqlSEkHGUwc5AP9nQe?购买即可解锁800+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,每日更新。函数中添加BiFPN的解析逻辑(找到。链接可用,不要多复制空格了。密码:946m22&8。

FJN110的博客 306

基于Simulink的BCH码编解码仿真建模示例

BCH码是一类循环码,能够纠正一定数量的随机错误。灵活性:可以根据需要选择不同的码长和纠错能力。高效性:适用于短码长和中等码长的场景,广泛用于卫星通信、存储系统等。实现简单:编码和解码过程可以通过硬件或软件高效实现。在本示例中,我们将使用MATLAB/Simulink中的和模块来完成BCH码的编解码操作,并通过仿真验证其误码率(BER)性能。通过本指南,我们介绍了如何基于Simulink搭建一个BCH码的编解码模型,并进行了仿真以验证其性能。背景介绍:理解BCH码的基本原理及其在通信系统中的应用。

xiaoheshang_123的博客 190

Android PreLink 技术简介

1.      原理简介 1)          Prelink Prelink 即预链接技术是利用事先链接以代替运行时链接的技术,以加快共享库的加载速度,它不仅能加快程序启动时间,还可以减少部分内存开销(它能使 KDE 的启动时间减少 50% )。每次程序执行时,进

dssxk的专栏 814

GEE 案例:利用多源遥感数据计算RUSLE(Revised Universal Soil Loss Equation)土壤侵蚀

该数据集提供了全球范围内以250至500米的空间分辨率获取的多光谱图像数据,用于监测地表覆盖和变化。RUSLE模型的基本原理是通过考虑土壤侵蚀的主要驱动因素,来估计土壤侵蚀的速率。该数据集提供了全球范围内以10至60米的空间分辨率获取的多光谱图像数据,用于监测地表覆盖和变化。它对农业和土地资源管理者提供了一种评估和预测土壤侵蚀风险的工具,以制定适当的土壤保护措施和决策。2. soil(土壤)是来自OpenLandMap的土壤纹理分类数据,使用了USDA(美国农业部)土壤纹理分类系统。

此星光明博客 803

Android Prelink

<br />      1.    原理简介<br />1)        Prelink<br /> Prelink即预链接技术是利用事先链接以代替运行时链接的技术,以加快共享库的加载速度,它不仅能加快程序启动时间,还可以减少部分内存开销(它能使KDE的启动时间减少50%)。每次程序执行时,进行的链接动作都是一样的,链接相对来说开销很大,尤其是嵌入式系统。<br />2)        普通Linux系统的Prelink<br /> Redhat系统中prelink工具(/etc/cron.dialy

SkyGray的专栏 2732

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

上一篇: ubuntu rar文件解压中文乱码问题
下一篇: 关于双屏显示的一些问题解释
huber
博客等级 码龄15年 79粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值