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

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

内容简介: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#图解教程

索利斯 / 苏林、朱晔 / 人民邮电出版社 / 2009-1 / 65.00元

本书是一本广受赞誉的C# 教程。它以图文并茂的形式,用朴实简洁的文字,并辅之以大量表格和代码示例,精炼而全面地阐述了最新版C# 语言的各种特性,使读者能够快速理解、学习和使用C#。同时, 本书还讲解了C#与VB 、C++ 等主流语言的不同点和相似之处。 本书是一本经典的C# 入门书,不仅适合没有任何编程语言基础的初级读者,而且还是有VB 、C++ 等语言基础的C# 初学者的最佳选择。一起来看看 《C#图解教程》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具