Native进程的运行过程

一般程序的启动步骤,可以用下图描述。程序由内核加载分析,使用linker链接需要的共享库,然后从c运行库的入口开始执行。

通常,native进程是由shell或者init启动,启动的过程如下:

Shell接收到命令,启动一个程序,此时shell首先会fork一个新的进程

新fork的进程,通过execve系统调用,陷入到内核中,内核检查和加载需要执行的二进制映像文件,检验其合法性及权限。通常用户态进程要启动一个新的程序(如shell),fork后,execve要紧跟着执行,这样会有更好的效率(由于使用COW技术,这样可以避免页表复制,而execve后,之前进程中的所有内容都是无用的,若execve紧跟fork后,可以避免COW引起的拷贝);

通常二进制文件都会要依赖一些系统动态库,此时kernel会启动加载器/system/bin/linker,执行linker的__linker_init()

Linker的linker_init(),会分析二进制的elf文件,加载依赖的动态库文件,然后转入二进制映像的入口函数__start中执行

__start会调用C库的初始化函数__libc_init()

__libc_init()会调用映像的main函数,这个main函数也就是用户app的入口函数

main() 函数执行完毕后,通过exit()退出进程执行

需要注意的是,Android bionic提供的加载器是/system/bin/linker,而普通linux系统用的glibc是/lib/ld-linux-xx.so.2。这也是为何其他linux平台同指令架构的二进制文件,不能在android上运行的原因之一:启动用户进程的加载器这个程序运行的第一步就出错了。

Java进程的运行过程

Java进程的启动比较特殊,Java进程是zygote启动的,zygote在folk进程之后,并没有执行execve指令,因此是共享了zygote的代码段和数据段。其它的java进程,可以看做都是zygote的克隆,克隆之后的进程,各自根再据自己的需求(java代码),解释java语言。

也就是说:Android的所有进程,从native角度看都是zygote。 其对应的程序都是 /system/bin/app_process,虚拟机是运行在其中的。

那为何java进程又如此的不同呢? 实际上,从native的角度看,不同的各种java程序,可以如此理解:只是/system/bin/app_process 这个程序,因为不同的输入(Java dex字节码)而引起的。

上图中,user APK实际上市zygote的一个克隆(启动->进入main等之前的流程没有画出, app进程没有这个步骤,是从zygote进程中克隆过来),差别主要在dvm虚拟机执行的java代码的不同导致的表现的行为差异巨大。

Java进程没有执行exec调用,这样有一个很大的好处:使用linux的COW(copy on Write)技术,就可以在多个java进程间,共享内存资源——主要是java的核心库。

Java程序也可以使用native库,此时的native库需要通过dlopen来打开(即java中,使用System.loadLibrary()方法加载so库,虚拟机对应会调用的C库方法),dlopen加载so库的过程中,依旧会通过linker分析处理so库的elf信息,加载其它依赖的动态库。

(注:zygote实际上是/system/bin/app_process,zygote只是app_process的别名)

linux加载内核后如何运行app,Android app启动过程相关推荐

  1. web页面到ajax,页面使用ajax加载页面后如果运行其中的js,webpack如何多页面展示...

    1.页面使用了sui-mobile这个框架,其中的页面路由部分会使用ajax加载页面.虽然每次都能加载到下一个页面,但是会出现加载到的页面中的js不去执行的情况. 2.页面打包使用了webpack,现 ...

  2. Android提前加载unity程序,Unity项目嵌入Android App实现过程

    1.编写自己的Unity APP,完成后,导出为Android 工程(参数和步骤截图如下),unity版本为:2019.4.16 2.导出的文件夹内容如下截图:我们只使用unityLibrary这个文 ...

  3. k n:linux kernel 从开机,到加载内核镜像到内存

    原文地址: linux的内核运行原理是怎么样的呢?如何从开机,到加载内核镜像到内存? linux的内核运行原理是怎么样的呢?如何从开机,到加载内核镜像到内存? 最佳答案 本回答由提问者推荐 头像 匿名 ...

  4. linux内核加载卡主,请教mx6,linux3.0.35,tf卡能启动uboot但是无法加载内核问题

    请教mx6,linux3.0.35,tf卡能启动uboot但是无法加载内核问题 cpu:mcimx6u5dvm10AB 硬件上,我把wp和cd都直接接地了,这次新加工的核心板,以及重新设计一个新项目的 ...

  5. html页面加载完成后会触发的事件_前端隐秘角落 - 页面渲染

    前言 如图所示,webkit内核浏览器的渲染过程(解析HTML,构建DOM树,解析CSS,构建CSSOM树 ,构建render树,布局layout,绘制painting),这些过程理解起来可能有些抽象 ...

  6. 第五章--加载内核Kernel.bin

    1.Linux系统的安装 和 与宿主计算机共享文件夹 2.global 和 extern 关键字的作用 3.C调用规范(C Calling Convention) 4.ELF文件 5.Loader.b ...

  7. 一步步编写操作系统 48 加载内核1

    其实,我们等了这一刻好久好久,即使我不说,大家也有这样的认识,linux内核是用c 语言写的,咱们肯定也要用c语言.其实...说点伤感情的话,今后的工作只是大部分(99%)都要用c语言来写,还有一些要 ...

  8. 操作系统真象还原实验记录之实验七:加载内核

    操作系统真象还原实验记录之实验七:加载内核 对应书P207 1.相关基础知识总结 1.1 elf格式 1.1.1 c程序如何转化成elf格式 写好main.c的源程序 //main.c int mai ...

  9. 【梅哥的Ring0湿润插入教程】重磅第三课:Ring0下的PE Loader及重加载内核秒杀一切内核级钩子(上篇)...

    [梅哥的Ring0湿润插入教程] Email:mlkui@163.com 转载请注明出处,谢绝喷子记者等,如引起各类不适请自觉滚J8蛋! 第三课:Ring0下PE Loader及重加载内核绕过一切内核 ...

最新文章

  1. C++ 私有成员变量的理解
  2. 社交网络初探——链路预测
  3. php链接javascript,javascript - 添加类=“行为链接”到活动页面 - PHP或JS - SO中文参考 - www.soinside.com...
  4. php数组由哪三部分构成,数据结构研究的主要内容有哪三部分
  5. c语言编译器turbo,C语言编译器TurboC使用技巧解析
  6. 左程云中级提升班-9在有限时间内获得最大奖励以及需要的最少时长问题
  7. 查看CPU和其他硬件温度的软件
  8. matplotlib绘图配色colormap问题
  9. 我来告诉你,一个草根程序员如何逆袭,成功进入BAT!
  10. 区块链Baas平台强势来袭,助力企业快速搭建区块链落地项目
  11. 基于Java swing的多人,图片,语音聊天室
  12. android viewpagerindicator tab,ViewPager系列之顶部滑动indicator+viewPager
  13. jBox----弹出层插件
  14. 问题 C: Fraction 分数类 I
  15. Java调试--排查类工具
  16. 喂,你要多吃点含乳酸菌的食品
  17. Excel如何快速给自家的男宝宝起名字
  18. error:expected '{' at end of input
  19. 【数学建模笔记】【第七讲】多元线性回归分析(一): 回归分析的定义、对于线性的理解以及内生性问题的探究
  20. Android连接不上第三方模拟器(夜神模拟器、海马模拟器、逍遥模拟器、Mumu模拟器)

热门文章

  1. qemu 安装windows_BIOS+MBR启动引导安装双系统
  2. 抽象类可以创建对象吗_【基础篇】java-抽象类与继承的补充
  3. 三菱fx3uplc恢复出厂设置_三菱fx3uplc解密过程与步骤分享
  4. mfc exe 在繁体系统 乱码_成都市招标文件编制及备案系统使用技巧问答
  5. android 分区修改工具_Android刷机包制作工具与教程-大神必备
  6. 一级减速器装配图cad文件_减速器的基本结构,减速箱各组成零件的结构及功用,值得保存...
  7. linux 网络服务器 源码下载,linux下 各类tcp网络服务器的实现源代码.doc
  8. 万用表怎么测量电池容量_家电常识丨万用表的测量应用学习
  9. ICC2 常用快捷键
  10. Java内存模型解析