33ios系统内核xnuapp如何加载_第1页
33ios系统内核xnuapp如何加载_第2页
33ios系统内核xnuapp如何加载_第3页
33ios系统内核xnuapp如何加载_第4页
33ios系统内核xnuapp如何加载_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

33|iOSXNU:App20190525 在专栏的第2篇文章《App启动速度怎么做优化与监控?》更新完之后,我看到很多同学对启动加载App的底层原理表示出了浓厚兴趣。所谓工欲善其事,必先利其器,相信有着好奇心的你,一定也会对支撑着App运行的操作系统有着各种各样的疑问。我曾在专栏的第5篇文章《链接器:符号是怎么绑定到地址上的?》中,和你分享了链接之前,系统是怎么加载App的。iOSiOSiOSiOS系统是基于ARMSpringBoard、Spotlight、第二层是应用框架层,是开发者会用到的。这一层包含了开发框架CocoaTouch架、Metal等。Darwin核XNU、驱动等。图1iOSAppDarwin是用户态的下层支撑,是iOS系统的核心。DarwinXNU,XNUUNIXXNU所以接下来,我们就一起看看XNUXNUMach、BSDAPIIOKitlibkern、libsa、PlatformExpert。如下图所示:图2XNU其中,Mach是作为UNIX内核的替代,主要解决UNIX一切皆文件导致抽象机制不足的问题,为现代操作系统做了进一步的抽象工作。Mach负责操作系统最基本的工作,包括进程MachMachTask,MachTask地址空间、IPC空间、处理器资源、调度控制、线程容器。BSDBSDProcess,BSDProcessMachTask,增加了进程ID、信号信息等,BSDProcess里面包含了扩展MachThread结构的Uthread。Mach的模块包括进程和线程都是对象,对象之间不能直接调用,只能通过MachMsg进行通信,也就是mach_msg()架层和核心框架层中,你可以通过mach_msg_trap()函数触发陷阱,从而切至MachMachmach_msg()NSHipster章“Inter-ProcessCommunication”。每个MachThread表示一个线程,是Mach里的最小执行单位。MachThread有自己的状态,包括机器状态、线程栈、调度优先级(有128个,数字越大表示优先级越高)、调度策略、内核Port、异常Port。MachThread既可以由MachTask处理,也可以扩展为Uthread,通过BSDProcess处理。这是因为XNU采用的是微内核Mach和宏内核BSD的混合内核,具备微内核和宏内Mach是微内核,可以将操作系统的核心独立在进程上运行,不过,内核层和用户态各层之间切换上下文和进程间消息传递都会降低性能。为了提高性能,苹果深度定制了BSD宏内核,使其和Mach混合使用。宏内核BSD是对MachOperatingSystemInterfaceofUNIX,可移植操作系统接口)兼容。BSDUNIXBSDUNIXXNUBSD来源于FreeBSD内核,经过深度定制而成。IEEE为了保证软件可以在各个UNIX系POSIX,iOSBSDPOSIXUNIX系BSD提供了更现代、更易用的内核接口,以及POSIX的兼容,比如通过扩展MachTask进程结构为BSDProcess。对于Mach使用mach_msg_trap()函数触发陷阱来处理异常消息,BSD则在异常消息机制的基础上建立了信号处理机制,用户态产生的信号会先被Mach转换成异常,BSD将异常再转换成信号。对于进程和线程,BSD会构建UNIX进程模型,创建POSIX兼容的线程模型pthread。iOS6后,为了增强系统安全,BSD实行了ASLR(AddressSpaceLayoutRandomization,地址空间布局随机化)iPhone核,BSDGCDBSD还从TrustdBSD引入了MAC框架以增强权限entitlement机制的安全。除了微内核Mach和宏内核BSD外,XNU还有IOKit。IOKit境,包含电源、内存、CPUIOKitlibkernC++EmbeddedC++编写了驱动程序基类,比如OSObject、OSArray、OSString等,新驱动可以继承这些基了解了XNUXNU怎么加载AppXNUiOSMach-OAPPMach-OMach-Oheader1structmach_header_64264位还是323CPU类型,比如arm或4CPU子类型,比如56loadcommands7loadcommands89106432magic、CPUcputype、CPU类型cpusubtype、文件类型filetype、描述文件在虚拟内存中逻辑结构和布局的loadcommands数量和大小等文件信息。filetypeMach-OMach-OOBJECT,指的是.o文件或者.aEXECUTE,指的是IPA拆包后的文件;DYLIB,.dylib.frameworkDYLINKER,Mach-Ofork内存、为进程创建主线程、代码签名等。用户态dyld会对Mach-O文件做库加载和符号苹果公司已经将XNU开源,并在GitHub上创建了镜像。要想编译XNU,你可以查看“BuildingtheXNUkernelonMacOSXSierra(10.12.X)”这篇文章;要想调试XNU,可以查看“SourceLevelDebuggingtheXNUKernel”这篇文章。forkMach-OXNUdarwin-xnu/bsd/kern/kern_exec.c,地址是https://githubcom/apple/darwin-xnu/blob/master/bsd/kern/kernexec.c,相关代码在_mac_execve函数里,代码如1mac_execve(proc_tp, mac_execve_args*uap,int32_t2345intis_64=6structvfs_context7structuthread*uthread;//8task_tnew_task= //Mach9context.vc_thread=context.vc_ucred=//分配大块内存,不用堆栈是因为Mach-OMALLOC(bufp,char*,(sizeof(*imgp)+sizeof(*vap)+sizeof(*origvap)),M_TEMP,imgp=(structimage_params*)//初始化imgputhread=if(uthread->uu_flag&UT_VFORK)imgp->ip_flags|=in_vfexec=}else//程序如果是启动态,就需要forkimgp->ip_flags|=//forkimgp->ip_new_thread=NULL,p,FALSE,p->p_flag&P_LP64,new_task=get_threadtask(imgp-context.vc_thread=imgp-}69

//加载解析Mach-error=if(imgp->ip_new_thread!=NULL)new_task=get_threadtask(imgp-}if(!error&&!in_vfexec)p=proc_exec_switch_task(p,current_task(),new_task,imgp-should_release_proc_ref=}if(!error){proc_transend(p,0);if(!in_vfexec)proc_inherit_task_role(get_threadtask(imgp->ip_new_thread),}thread_tmain_thread=imgp->ip_new_thread;task_set_main_thread_qos(new_task,main_thread);}可以看出,由于Mach-O文件很大, mac_execve函数会先为Mach-O分配一大块内存imgp,接下来会初始化imgp里的公共数据。内存处理完, mac_execve函数就会通过fork_create_child()函数fork出一个新的进程。新进程fork后,会通过exec_activate_image()函数解析加载Mach-O文件到内存imgp里。最后,使用task_set_main_thread_qos()函数设置新fork出进程的主线程。structexecswint(*ex_imgact)(structimage_paramsconstchar}execsw[]={ "Mach-oBinary"{ "FatBinary"{ "InterpreterScript"{NULL,9Mach-Oexec_mach_imgact()exec_mach_imgact()通过load_machfile()函数加载Mach-O文件,根据解析Mach-O后得到的loadcommandactivate_exec_state()解析加载Mach-O后的结构信息,设置执行App的入口点。设置完入口点后会通过load_dylinker()函数来解析加载dyld,然后将入口点地址改成dyldMach-O态层dyld加载App了。Dyld的入口函数是dyld_start,dyld属于用户态进程,不在XNU里,dyld_start函dylddyldStartup.s文件里。dyld_startApp态库,处理完成后会返回App的入口地址,然后到App的main函数。今天我跟你介绍了iOS系统的内核XNU,以及XNU是如何加载App的。总体来说,XNUMach-OMach-Ofork为Mach-O解析Mach-读取Mach-O遍历loadcommand信息,将Mach-O启动dyld在今天这篇文章中,我主要和你分享的是系统内核加载App的流程,而关于用户态dyld加载过程没有展开说。如果你想了解dyld加载过程的话,可以看看MikeAsh的“dyld:DynamicLinkingOnOSX” 34|iOS黑魔法RuntimeMethodSwizzling背后的原 4MacOSX&IOS 1报错的时候

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论