iOS App启动流程——理论知识篇

栏目: IOS · 发布时间: 5年前

内容简介:Mach-O文件可以分成segment。通常大写字母表示,例如

一、Mach-O结构

1. Mach-O术语:

  • Executable (可执行文件)
  • Dylib (动态库)
  • Bundle —— iOS特有的动态库,不可链接,只能运行时使用dlopen()

Image —— Executable、Dylib、Bundle都是 Image

Framework —— 带有特殊目录结构的Dylib,用来保存资源和头文件。

2. Mach-O内部结构

Mach-O文件可以分成segment。通常大写字母表示,例如 __TEXT , __DATA , __LINKEDIT

iOS App启动流程——理论知识篇

segment的大小由硬件决定的,是页大小的整数倍。arm64的页大小是16KB,其他的是4KB。

  • __TEXT :__TEXT位于文件的头部,包含Mach header,机器指令以及readonly的常量,例如c字符串。
  • __DATA :readwrite,包含全局变量
  • __LINKEDIT :包含函数的名称和地址相关的信息

3. Mach-O通用文件

为32位和64位设备编译会分别获得一个Mach-O文件。将两个文件合并后会获得一个Mach-O通用文件,可以同时运行在32位和64位的设备上。

iOS App启动流程——理论知识篇

Fat Header记录其中的架构以及偏移位置。

二、虚拟内存

every problem can be solved by adding a level of indirection.

虚拟内存解决的问题是,多进程系统如何管理物理内存。

每个进程是由物理内存页映射的逻辑地址空间。 这种映射并 不是一一对应的 ,例如 有的逻辑地址不对应物理内存空间 ,也有 可能不同的逻辑地址对应着相同的物理内存

Page fault

有些逻辑地址没有对应的内存空间,当程序访问该逻辑地址时,会触发page fault。

此时内核就会停下当前的线程,来xxxxx

共享内存

不同的进程中的逻辑地址空间可以映射相同的物理内存空间,这两个进程共享内存中的内容。

file backed pages

可以通过mmap()调用,告诉虚拟内存,将文件中的某一片段映射到进程中的某段地址空间,而不是将整个文件都读进内存。没当第一次访问之前没有访问过的地址空间,都会触发一个page fault,内核会从文件中读取一页。从而实现了文件的懒读取,提升加载速度。

copy on write

当两个进程访问__DATA内容的时候,一个进程只读,一个进程想要写,这是就会出现copy on write。内核会将这一页copy到新的地址空间,然后重新映射。这时,进程都有自己copy出来的这一页。只读的那一页是clean page,拷贝出来的进行写操作的这一页叫做dirty page。dirty page意味着其中包含了进程相关的信息。对于clean page,内核之后可以重新生成,重新从硬盘中读取。dirty page代价更为昂贵。

加载动态库的过程

iOS App启动流程——理论知识篇

假设动态库的大小为8页,两个进程需要加载这个动态库。

进程1:

  1. dyld需要加载Mach-O的header,即图中RAM1。发现没有映射,所以触发page fault,将RAM1读取到物理内存中,然后映射到进程1的虚拟内存中。
  2. dyld读取Mach-O header,然后发现还需要一些信息在__LINKEDIT中。此时加载__LINKEDIT中的信息,触发page fault,将RAM2读取到物理内存中,然后映射到进程1的虚拟内存中。
  3. dyld读取__LINKEDIT内容,需要修改__DATA page的内容使动态库可运行。此时同上,加载__DATA中的信息,触发page fault,将RAM3读取到物理内存中,然后映射到进程1的虚拟内存中。
  4. 当dyld要往__DATA page中写内容的时候,就会触发copy on write。RAM3就变成的dirty page。

进程2:

  1. dyld需要加载Mach-O的header,即图中RAM1。内核会告诉dyld,内存中已经有这个页了。直接映射到进程2的虚拟内存中,无需IO。
  2. 同理,RAM2也是。
  3. 读取RAM3的时候,内核会查看RAM3的clean page依然在内存中,如果在,直接映射,如果不在,重新加载进内存。当dyld需要往__DATA page中写内容的时候,就会触发copy on write。RAM3就变成的dirty page。

只有dyld加载动态库的时候,才会需要__LINKEDIT,一旦完成后,__LINKEDIT中的内容可以回收。

此时,一共用了2个dirty page 和1个clean page。如果是直接读取整个文件到内容中,则一共产生了16个dirty page!

两个安全技术

  1. ASLR(address space layout randomization):地址空间布局随机化,将加载地址随机化。
  2. code sign:为了在运用时验证文件,整个文件在运行时重新读取,所以Mach-O中的每一页都有独立的code sign,存放在__LINKEDIT中。这样就能保证每一页都没有被篡改。

参考


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C语言基础

C语言基础

安博教育集团 / 2012-2 / 37.00元

《C语言基础》深入浅出地介绍了C语言程序设计的基础知识,内容涉及C语言基础、算法基础、变量、数据类型、运算符、输入/输出相关函数、选择结构、循环结构、各种表达式、数组、字符串、指针、函数、结构体、ISO C99的扩展语法等。全书内容丰富,结构严谨,层次清晰,语言生动,论述精准而深刻,实例丰富而实用。 《C语言基础》不仅适合用做计算机职业培训的首选教材,也可作为普通高校教材使用,更是C语言初学......一起来看看 《C语言基础》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具