linux内核启动Android系统启动过程详解
Android的本地启动流程1
![Android的本地启动流程1](https://img.taocdn.com/s3/m/505c4e45cf84b9d528ea7a56.png)
本地部分启动流程
在 Android 系统运行的通常情况下,根文件系统 只是一个较小的部分,例如包括 init 、 init.rc 和少数 的几个目录。其他的文件系统通常需要由 init 根据 init.rc 脚本的中内容进行挂接。 默认的文件系统挂接方法:
mount mount mount mount yaffs2 yaffs2 yaffs2 yaffs2 mtd@system /system mtd@system /system ro remount mtd@userdata /data nosuid nodev mtd@cache /cache nosuid nodev
Android 的本地启动流程
韩 超 @ Android 技术
本地部分启动流程
Android 系统的启动流程为: BootLoader 启动(标准) Linux 内核启动(标准) 内核加载根文件系统 init 进程启动 运行 init.rc 脚本 加载 system 和 data 文件系统 启动各种可执行程序
谢谢!
本地部分启动流程
Linux 内核在加载完成根文件系统后,将运行根文 件系统中的一个名称为 init 的可执行程序,作为用户 空间的第一个进程。 在 Android 中,这个 init 就是根目录中的 init 可执 行程序,它被内核启动后,作为系统的用户空间的第 一个进程来运行。 init 可执行程序运行后,系统的用 户空间部分进入了 Android 系统特定环境。 init 程序运行后,程序将会在根目录中找到名称为 init.rc 的文件作为启动脚本。在不同的平台中, init.rc 脚本中的内容可能有自定义的部分。
# cat /proc/cmdline qemu=1 console=ttyS0 android.checkjni=1 android.qemud=ttyS1 ndns=-1
Android系统完整的启动过程
![Android系统完整的启动过程](https://img.taocdn.com/s3/m/3471684c33687e21af45a94f.png)
Android系统完整的启动过程,从系统层次角度可分为Linux系统层、Android系统服务层、Zygote进程模型三个阶段;从开机到启动Home Launcher完成具体的任务细节可分为七个步骤,下面就从具体的细节来解读Android系统完整的初始化过程。
一、启动BootLoaderAndroid 系统是基于Linux操作系统的,所以它最初的启动过程和Linux一样。
当设备通电后首先执行BootLoader引导装载器,BootLoader是在操作系统内核运行之前运行的一段小程序。
通过这段小程序初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境引导进入合适的状态,以便为最终调用操作系统内核准备好正确的运行环境。
而Linux系统启动时:1)首先要加载BIOS的硬件信息,并获取第一个启动设备的代号2)读取第一个启动设备的MBR的引导加载程序(lilo、grub等)的启动信息。
3)加载核心操作系统的核心信息,核心开始解压缩,并且尝试驱动所有的硬件设备。
…………在嵌入式系统中,通常不会有像BIOS那样的固件程序,因此整个系统的加载任务都是通过BootLoader完成的。
二、加载系统内核Linux内核映像通常包括两部分代码,分别为实模式代码和保护模式代码。
当BootLoader装载内核映像到代码段内存时,分别放置实模式代码和保护模式代码到不同的位置,然后进入实模式代码执行,实模式代码执行完成后转入保护模式代码。
实模式和保护模式的概念再次不做过多解释,读者可以自行查阅资料。
三、启动Init进程当系统内核加载完成之后,会首先启动Init守护进程,它是内核启动的第一个用户级进程,它的进程号总是1。
Init进程启动完成之后,还负责启动其他的一些重要守护进程,包括:Usbd进程(USB Daemon):USB连接后台进程,负责管理USB连接。
adbd 进程(Android Debug Bridge Daemon):ADB连接后台进程,负责管理ADB连接。
Android 开机启动流程
![Android 开机启动流程](https://img.taocdn.com/s3/m/13370a3b27d3240c8447efa4.png)
Android的开机流程1. 系统引导bootloader1) 源码:bootable/bootloader/*2) 说明:加电后,CPU将先执行bootloader程序,此处有三种选择a) 开机按Camera+Power启动到fastboot,即命令或SD卡烧写模式,不加载内核及文件系统,此处可以进行工厂模式的烧写b) 开机按Home+Power启动到recovery模式,加载recovery.img,recovery.i mg包含内核,基本的文件系统,用于工程模式的烧写c) 开机按Power,正常启动系统,加载boot.img,boot.img包含内核,基本文件系统,用于正常启动手机(以下只分析正常启动的情况)2. 内核kernel1) 源码:kernel/*2) 说明:kernel由bootloader加载3. 文件系统及应用init1) 源码:system/core/init/*2) 配置文件:system/rootdir/init.rc,3) 说明:init是一个由内核启动的用户级进程,它按照init.rc中的设置执行:启动服务(这里的服务指linux底层服务,如adbd提供adb支持,vold提供SD卡挂载等),执行命令和按其中的配置语句执行相应功能4. 重要的后台程序zygote1)源码:frameworks/base/cmds/app_main.cpp等2) 说明:zygote是一个在init.rc中被指定启动的服务,该服务对应的命令是/system/bin/app_processa)建立Java Runtime,建立虚拟机b) 建立Socket接收ActivityManangerService的请求,用于Fork应用程序c) 启动System Server5. 系统服务system server1)源码:frameworks/base/services/java/com/android/server/SystemServer.jav a2) 说明:被zygote启动,通过SystemManager管理android的服务(这里的服务指frameworks/base/services下的服务,如卫星定位服务,剪切板服务等)6. 桌面launcher1)源码:ActivityManagerService.java为入口,packages/apps/launcher*实现2) 说明:系统启动成功后SystemServer使用xxx.systemReady()通知各个服务,系统已经就绪,桌面程序Home就是在ActivityManagerService.systemReady()通知的过程中建立的,最终调用()启launcher7. 解锁1) 源码:frameworks/policies/base/phone/com/android/internal/policy/impl/*lock* 2) 说明:系统启动成功后SystemServer调用wm.systemReady()通知WindowManagerService,进而调用PhoneWindowManager,最终通过LockPatternKeyguardView显示解锁界面,跟踪代码可以看到解锁界面并不是一个Activity,这是只是向特定层上绘图,其代码了存放在特殊的位置8. 开机自启动的第三方应用程序1) 源码:ﻫframeworks/base/services/java/com/android/server/am/ActivityManagerService.java2) 说明:系统启动成功后SystemServer调用ActivityManagerNative.getDefa ult().systemReady()通知ActivityManager启动成功,ActivityManager会通过置变量mBooting,通知它的另一线程,该线程会发送广播android.intent.action.BOOT_COMPLETED以告知已注册的第三方程序在开机时自动启动。
android启动流程
![android启动流程](https://img.taocdn.com/s3/m/f38da98cdb38376baf1ffc4ffe4733687f21fc7f.png)
android启动流程Android启动流程:Android是一款广泛使用的移动操作系统,其启动流程是一个相对复杂的过程,涉及到多个模块的加载和启动。
下面将详细介绍Android的启动流程。
1、开机自检(Boot)当手机开机时,首先进行开机自检。
在这个阶段,系统会检测硬件设备的状态,包括电池是否齐全、屏幕是否正常等。
如果硬件设备通过了自检,系统将会开始启动。
2、引导加载程序(Bootloader)开机自检完成后,系统会加载引导加载程序(Bootloader)。
引导加载程序是硬件平台的一部分,其主要作用是启动操作系统。
在加载引导加载程序的过程中,系统会自动检测手机的存储器设备,确定存储设备中是否有可用的引导文件。
3、Linux内核加载一旦引导加载程序找到可用的引导文件,系统将会加载Linux内核。
Linux内核是Android系统的核心组件,负责管理内存、文件系统、驱动程序等。
4、文件系统加载一旦Linux内核加载完成,系统将会加载文件系统。
Android系统使用的是基于Linux的文件系统,在这个过程中,系统会加载并初始化各个文件系统,包括根文件系统、系统文件系统、数据文件系统等。
5、初始化进程(Init)一旦文件系统加载完成,系统将会启动初始化进程(Init)。
初始化进程是Android系统的第一个进程,其作用是启动系统的各个进程和服务。
6、启动用户空间(System Server)在初始化进程启动后,系统会启动用户空间,加载系统的用户界面等组件。
7、启动应用程序一旦用户空间加载完成,系统将会启动应用程序。
应用程序是Android系统的核心功能,包括系统应用程序和用户安装的应用程序。
系统应用程序包括电话、短信、浏览器等,而用户安装的应用程序则是用户根据自己的需求下载和安装的。
8、应用程序启动完成一旦应用程序启动完成,系统将进入正常运行状态,用户可以通过界面操作手机。
总结:Android系统的启动流程是一个复杂而严密的过程,经过开机自检、引导加载程序、Linux内核加载、文件系统加载、初始化进程、启动用户空间、启动应用程序等多个步骤,最终实现用户界面的显示和应用程序的运行。
androidstartup原理
![androidstartup原理](https://img.taocdn.com/s3/m/bdc5d4866037ee06eff9aef8941ea76e59fa4a5b.png)
androidstartup原理Android是由Google开发的一套开放源代码的操作系统,主要用于移动设备和嵌入式系统。
它被广泛应用于智能手机、平板电脑、智能电视等移动设备中。
Android系统的启动过程是一个复杂的过程,涉及到很多不同的模块和组件。
下面将详细介绍Android系统的启动原理。
Android系统的启动过程主要包括五个阶段:引导加载程序、Linux内核初始化、系统服务初始化、应用程序启动和进程初始化。
首先是引导加载程序阶段。
当设备开机时,引导加载程序会被加载并执行。
引导加载程序主要负责初始化硬件设备,并加载第二阶段的引导加载程序。
在这个阶段,设备会进行一些硬件自检和初始化操作,确保设备能够正常运行。
接着是Linux内核初始化阶段。
在这个阶段,Linux内核会被加载并执行。
Linux内核是Android系统的核心部分,它负责管理系统的各种硬件资源和提供系统服务,同时也是Android系统与硬件之间的桥梁。
在这个阶段,Linux内核会初始化一些重要的子系统,如内存管理、文件系统、网络协议栈等。
然后是系统服务初始化阶段。
在这个阶段,系统服务会被加载并启动。
系统服务是Android系统中的一些核心组件,它们负责提供各种系统功能和服务,如Activity管理、通知管理、电源管理、输入管理等。
在这个阶段,系统服务会被初始化,并通过Binder机制提供接口供应用程序调用。
接下来是应用程序启动阶段。
在这个阶段,一些重要的应用程序会被加载并启动。
Android系统中有一些应用程序是系统级别的,它们在系统启动过程中会被优先加载和启动,如Launcher、Settings等。
在这个阶段,应用程序会被启动,并进入到运行状态。
最后是进程初始化阶段。
在这个阶段,Android系统会创建并初始化一些重要的进程。
Android系统采用了一种轻量级的进程模型,每个应用程序对应一个独立的进程,各个进程之间通过IPC机制进行通信。
Linux-Android系统启...
![Linux-Android系统启...](https://img.taocdn.com/s3/m/0bc4c8c66e1aff00bed5b9f3f90f76c661374ca2.png)
Linux-Android系统启...Linux-Android系统启动之INIT进程和system v init 收藏Linux系统启动之INIT进程和system v init一. Linux系统启动之INIT进程和system v init1. 首先介绍一下INIT进程init进程在Start_kernel执行完毕之后,也就是Kernel初始化完毕之后启动,是系统所有进程的起点,内核在完成核内引导以后,即在本线程(进程)空间内加载init程序,它的进程号是1。
如果是使用system v init启动的话,实际上system v init就是一个INIT进程.2. 接下来介绍一下/etc/inittab文件init程序需要读取/etc/inittab文件作为其行为指针,inittab是以行为单位的描述性(非执行性)文本,每一个指令行都具有以下格式: id:runlevel:action:process其中 id为入口标识符,runlevel为运行级别,action为动作代号,process为具体的执行程序。
id一般要求4个字符以内,对于getty或其他login程序项,要求id与tty的编号相同,否则getty程序将不能正常工作。
runlevel 是init所处于的运行级别的标识,一般使用0-6以及S 或s。
0、1、6运行级别被系统保留,0作为shutdown动作,1作为重启至单用户模式,6 为重启;S和s意义相同,表示单用户模式,且无需inittab文件,因此也不在inittab中出现,实际上,进入单用户模式时,init直接在控制台 (/dev/console)上运行/sbin/sulogin。
在一般的系统实现中,都使用了2、3、4、5几个级别,在Redhat系统中,2表示无NFS支持的多用户模式,3表示完全多用户模式(也是最常用的级别),4保留给用户自定义,5表示XDM图形登录方式。
7-9级别也是可以使用的,传统的unix系统没有定义这几个级别。
高通Andriod开机流程与镜像说明
![高通Andriod开机流程与镜像说明](https://img.taocdn.com/s3/m/e65a374d302b3169a45177232f60ddccda38e6cf.png)
⾼通Andriod开机流程与镜像说明Android镜像说明Android设备刷机时都需要ROM包,ROM包下⾯有很多的.img和其他的相关镜像⽂件,其中这⾥⾯包含了Android很多的分区,Android镜像⽂件是通过源码编译⽣成的,下⾯是ROM包各个镜像的作⽤:镜像⽂件说明boot.img boot分区,包括内核⽂件和虚拟内存盘Ramdisk,负责设备开机,可在recovery模式进⾏擦除,重新安装带有boot分区的新系统system.img system分区,包含Android系统的⽤户界⾯以及设置上的⼀些预装系统应⽤recovery.img recovery分区,替代启动分区,执⾏恢复和维护系统的⼀些操作userdata.img data分区,⽤于保存⽤户的数据,例如联系⼈,短信,设置偏好和应⽤程序存放的地⽅cache.img cache分区,⽤于放置系统频繁访问的数据和应⽤程序组件的分区persist.img persist分区包含了设备的传感器和信号部分的驱动程序,例如wifi,蓝⽛连接都有关系splash.img开机画⾯⽂件NON-HLOS.bin modem image负责处理通讯协议相关的基带镜像prog_emmc_firehose_8953_ddr.mbn QFIL软件烧录系统的时候,需要⽤到此⽂件,应该是关于EMMC、DDR的配置参数相关的sbl1.mbn硬件的初始化,并且保存加载其他模块信息的顺序tz.mbn trustzone是ARM TrustZone® 技术是系统范围的安全⽅法,基于安全需求和引导模式配置XPU,NAND MPU,它和其他模块代码运⾏在相互隔离的区域,主要实现底层很多安全性特性emmc_appsboot.mbn bootloader⽂件,进⼊fastboot模式相关⽂件rpm.mbn电源管理器,是⾼通MSM平台另外加的⼀块芯⽚,虽然与AP芯⽚打包在⼀起,但其是⼀个独⽴的ARM Core。
详解Android(安卓)手机系统启动过程
![详解Android(安卓)手机系统启动过程](https://img.taocdn.com/s3/m/8c783979f46527d3240ce0a4.png)
最近打算自己移植MIUI,所以自学了不少东西,分享一下,recovery刷机模式中启动到过程吧,一下所有内容均有我略读相关源码得到和总结得来,不一定完全正确,不对之处还望海涵:当我们只是按下电源键开机时,会进入正常启动模式。
Secondary stage bootloader 会从boot 分区开始启动。
Boot 分区的格式是固定的,首先是一个头部,然后是Linux 内核,最后是用作根文件系统的ramdisk。
当Linux 内核启动完毕后,就开始执行根文件系统中的init 程序,init 程序会读取启动脚本文件(init.rc 和init.goldfish)。
现在就来说一下,init.rc到底在做些什么,我会在附件上传有关init_rc脚本语法和自己阅读是坐下到笔记,希望对各位有所帮助。
1.on boot-pause2. exec sbin/chargerlogo #运行sbin/chargerlogo(此运行在内核目录下)3.4.on early-init5. start ueventd #调用sbin/uventd链接所指的可执行程序,其源码位于system/core/init/ueventd.c,为设备赋予权限6.7.on init #源码位于system/core/init/init.c8.#主要完成一下的工作9.#清空umask、创建并挂载一些基本的目录(/dev-设备、/proc-系统信息、/sys-系统信息、/dev/pts-终端控制字,用于执行adb、/dev/socket)10.11.sysclktz 0 #把硬件时钟当成本地时间(GMT时区)12.13.loglevel 3 #讲系统LOG设置成可见,0为(NONE)14.15. write /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"performance"16.17.# setup the global environment 设置全局变量18. export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin#PATH变量19. export LD_LIBRARY_PATH /vendor/lib:/system/lib #库20. export ANDROID_BOOTLOGO 121. export ANDROID_CACHE /cache #cache目录22. export ANDROID_ROOT /system #安卓系统root分区-->/system23. export ANDROID_ASSETS /system/app #安卓系统可访问到-->/system/app(这就是为什么没有root权限不能删除/system/app下到文件)24. export ANDROID_DATA /data #安卓data区25. export DOWNLOAD_CACHE /cache/download #下载缓存为/cache/download26. export EXTERNAL_STORAGE /mnt/sdcard #附加存储-->sdcard卡27. export ASEC_MOUNTPOINT /mnt/asec #asec根文件目录28. export LOOP_MOUNTPOINT /mnt/obb29. export SD_EXT_DIRECTORY /sd-ext #sdcard挂载格式30. export BOOTCLASSPATH/system/framework/core.jar:/system/framework/bouncycastle.jar:/system/f ramework/ext.jar:/system/framework/framework.jar:/system/framework/andr oid.policy.jar:/system/framework/services.jar:/system/framework/core-ju nit.jar #bootclasspath31. export DSP_PATH /system/lib/dsp #dsp(数字信号处理器) path32. export DEFAULT_BASEIMAGE /system/lib/dsp/baseimage.dof33. export QOSDYN_FILE /system/lib/dsp/qosdyn_3430.dll64P34.35.# Backward compatibility #反向兼容,确保对以前版本到兼容?(不缺定)36. symlink /system/etc /etc #在/etc下创建链接到/system/etc到链接37. symlink /sys/kernel/debug /d38.39.# Right now vendor lives on the same filesystem as system,40.# but someday that may change.41. symlink /system/vendor /vendor42.43.# create mountpoints44. mkdir /mnt 0775 root system45. #给system赋予0775的权限,也就是rwx-rwx-rw-现在详细解释如下46. #此权限数值对应为:47. #u(用户):r(读)-w(写)-x(执行)48. #g(群组):r(读)-w(写)-x(执行)49. #0(其他):r(读)-w(写)-50. #对应到2进制数值为:51. #1 1 1 :111 ---752. #1 1 1 :111 ---753. #1 1 0 :110 ---554. #55. mkdir /mnt/sdcard 0000 system system56.57.# Create cgroup mount point for cpu accounting #为cpu创建58. mkdir /acct59. mount cgroup none /acct cpuacct60. mkdir /acct/uid61.62.# Backwards Compat - XXX: Going away in G*63. symlink /mnt/sdcard /sdcard64.65. mkdir /system66. mkdir /data 0771 system system67. mkdir /cache 0771 system cache68. mkdir /config 0500 root root69.70. mkdir /sqlite_stmt_journals 01777 root root71. mount tmpfs tmpfs /sqlite_stmt_journals size=4m72.73. # Directory for putting things only root should see.#创建用于存放root用户才能可见到文件夹74. mkdir /mnt/secure 0700 root root75.76. # Directory for staging bindmounts #伺服器根文件目录77. mkdir /mnt/secure/staging 0700 root root78.79. # Directory-target for where the secure container80. # imagefile directory will be bind-mounted81. mkdir /mnt/secure/asec 0700 root root82.83. # Secure container public mount points.84. mkdir /mnt/asec 0700 root system85. mount tmpfs tmpfs /mnt/asec mode=0755,gid=100086.87. # Filesystem image public mount points.88. mkdir /mnt/obb 0700 root system89. mount tmpfs tmpfs /mnt/obb mode=0755,gid=100090.91. mkdir /sd-ext 0771 system system92.93. write /proc/sys/kernel/panic_on_oops 194. write /proc/sys/kernel/hung_task_timeout_secs 095. write /proc/cpu/alignment 496. write /proc/sys/kernel/sched_latency_ns 1000000097. write /proc/sys/kernel/sched_wakeup_granularity_ns 200000098. write /proc/sys/kernel/sched_compat_yield 199. write /proc/sys/kernel/sched_child_runs_first 0100.101.# Create cgroup mount points for process groups102. mkdir /dev/cpuctl103. mount cgroup none /dev/cpuctl cpu104. chown system system /dev/cpuctl105. chown system system /dev/cpuctl/tasks106. chmod 0777 /dev/cpuctl/tasks107. write /dev/cpuctl/cpu.shares 1024108.109. mkdir /dev/cpuctl/fg_boost110. chown system system /dev/cpuctl/fg_boost/tasks111. chmod 0777 /dev/cpuctl/fg_boost/tasks112. write /dev/cpuctl/fg_boost/cpu.shares 1024113.114. mkdir /dev/cpuctl/bg_non_interactive115. chown system system /dev/cpuctl/bg_non_interactive/tasks 116. chmod 0777 /dev/cpuctl/bg_non_interactive/tasks117. # 5.0 %118. write /dev/cpuctl/bg_non_interactive/cpu.shares 52119.120.#[LGE_start] hyunwoong.ahn121. mkdir /dvp 0771 system system122. mkdir /dvp/hwkey 0771 system system123. mkdir /dvp/userdata 0771 system system124.#[LGE_end] hyunwoong.ahn125.126. chown system system /sys/class/leds/lcd-backlight/als 127.128. # Increase readahead buffers on MMC devices129. write /sys/block/mmcblk0/bdi/read_ahead_kb 1024130. write /sys/block/mmcblk1/bdi/read_ahead_kb 1024131.132.on fs133.# mount mtd partitions134. # Mount /system rw first to give the filesystem a chance to save a checkpoint135. mount ext4 /dev/block/mmcblk0p8 /system ro noatime barrier=1 wait 136. # We chown/chmod /data again so because mount is run as root + defaults 137. mount ext4 /dev/block/mmcblk0p9 /data nosuid nodev noatime barrier=1 wait138. chown system system /data139. chmod 0771 /data140.141.#[LGE_star]Hyunwoong.ahn^M142. mount ext3 /dev/block/mmcblk0p6 /dvp/hwkey nosuid nodev143. chown system system /dvp/hwkey144. chown system divxdrm /dvp/hwkey/key.hw145. chmod 0660 /dvp/hwkey/key.hw146. mount ext3 /dev/block/mmcblk0p6 /dvp/userdata nosuid nodev147. chown system divxdrm /dvp/userdata148. chmod 0770 /dvp/userdata149. chown system system /dev/block/mmcblk0p5150. chown system system /dev/block/mmcblk0p12151. chmod 0777 /dev/block/mmcblk0p5152. chmod 0777 /dev/block/mmcblk0p12153.154. mount ext4 /dev/block/mmcblk0p10 /cache nosuid nodev noatime barrier=1 wait155.156. mkdir /lgdrm 0770 lgdrm lgdrm_acc157. mount ext3 /dev/block/mmcblk0p5 /lgdrm nosuid nodev158.159.160.161.162.163.on post-fs164.165. # once everything is setup, no need to modify /166. mount rootfs rootfs / ro remount167.168. # We chown/chmod /data again so because mount is run as root + defaults 169. chown system system /data170. chmod 0771 /data171.172. # Mount compressed filesystems173. mount squashfs loop@/system/lib/modules/modules.sqf/system/lib/modules ro174. mount squashfs loop@/system/xbin/xbin.sqf /system/xbin ro175.176. # Create dump dir and collect dumps.177. # Do this before we mount cache so eventually we can use cache for 178. # storing dumps on platforms which do not have a dedicated dump partition.179.180. mkdir /data/dontpanic181. chown root log /data/dontpanic182. chmod 0750 /data/dontpanic183.184. # Collect apanic data, free resources and re-arm trigger185. copy /proc/apanic_console /data/dontpanic/apanic_console186. chown root log /data/dontpanic/apanic_console187. chmod 0640 /data/dontpanic/apanic_console188.189. copy /proc/apanic_threads /data/dontpanic/apanic_threads190. chown root log /data/dontpanic/apanic_threads191. chmod 0640 /data/dontpanic/apanic_threads192.193. write /proc/apanic_console 1194.195. # Same reason as /data above196. chown system cache /cache197. chmod 0771 /cache198.199. # This may have been created by the recovery system with odd permissions 200. chown system cache /cache/recovery201. chmod 0770 /cache/recovery202.203. #change permissions on vmallocinfo so we can grab it from bugreports 204. chown root log /proc/vmallocinfo205. chmod 0440 /proc/vmallocinfo206.207. #change permissions on kmsg & sysrq-trigger so bugreports can grab kthread stacks208. chown root system /proc/kmsg209. chmod 0440 /proc/kmsg210. chown root system /proc/sysrq-trigger211. chmod 0220 /proc/sysrq-trigger212.213.# create basic filesystem structure214. mkdir /data/misc 01771 system misc215. mkdir /data/misc/bluetoothd 0770 bluetooth bluetooth216. mkdir /data/misc/bluetooth 0770 system system217. mkdir /data/misc/keystore 0700 keystore keystore218. mkdir /data/misc/vpn 0770 system system219. mkdir /data/misc/systemkeys 0700 system system220. mkdir /data/misc/vpn/profiles 0770 system system221. # give system access to wpa_supplicant.conf for backup and restore 222. mkdir /data/misc/wifi 0770 wifi wifi223. chmod 0770 /data/misc/wifi224. chmod 0660 /data/misc/wifi/wpa_supplicant.conf225. mkdir /data/local 0771 shell shell226. mkdir /data/local/tmp 0771 shell shell227. mkdir /data/local/download 0771 system cache228. mkdir /data/data 0771 system system229. mkdir /data/app-private 0771 system system230. mkdir /data/app 0771 system system231. mkdir /data/property 0700 root root232.233. mkdir /cache/download 0771 system cache234.235. # create dalvik-cache and double-check the perms236. mkdir /data/dalvik-cache 0771 system system237. chown system system /data/dalvik-cache238. chmod 0771 /data/dalvik-cache239.240. mkdir /cache/dalvik-cache 0771 system system241. chown system system /cache/dalvik-cache242. chmod 0771 /cache/dalvik-cache243.244. # create the lost+found directories, so as to enforce our permissions 245. mkdir /data/lost+found 0770246. mkdir /cache/lost+found 0770247.248. # double check the perms, in case lost+found already exists, and set owner249. chown root root /data/lost+found250. chmod 0770 /data/lost+found251. chown root root /cache/lost+found252. chmod 0770 /cache/lost+found253.254. # allow net_raw to have access to /dev/socket directory255. chown root net_raw /dev/socket256. chmod 0775 /dev/socket257.258. # allow system to modify cpufreq control files259. chown root system/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor260. chmod 0664 /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 261. chown root system/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq262. chmod 0664 /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq 263. chown root system/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq264. chmod 0664 /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq 265.266. chmod 0777 /data/misc/wifi/config_mac267. mkdir /data/misc/wifi/sockets 0770 wifi wifi268. mkdir /data/misc/dhcp 0777 dhcp dhcp269. setprop wifi.supplicant_scan_interval 20270. setprop wifi.interface wlan0271.272.on boot273.# basic network init274. ifup lo275. hostname localhost276. domainname localdomain277.278.# set RLIMIT_NICE to allow priorities from 19 to -20279. setrlimit 13 40 40280.281.# Define the oom_adj values for the classes of processes that can be 282.# killed by the kernel. These are used in ActivityManagerService. 283. setprop ro.FOREGROUND_APP_ADJ 0284. setprop ro.VISIBLE_APP_ADJ 1285. setprop ro.PERCEPTIBLE_APP_ADJ 2286. setprop ro.HEAVY_WEIGHT_APP_ADJ 3287. setprop ro.SECONDARY_SERVER_ADJ 4288. setprop ro.BACKUP_APP_ADJ 5289. setprop ro.HOME_APP_ADJ 6290. setprop ro.HIDDEN_APP_MIN_ADJ 7291. setprop ro.EMPTY_APP_ADJ 15292.293.# Define the memory thresholds at which the above process classes will 294.# be killed. These numbers are in pages (4k).295. setprop ro.FOREGROUND_APP_MEM 2048296. setprop ro.VISIBLE_APP_MEM 3072297. setprop ro.PERCEPTIBLE_APP_MEM 4096298. setprop ro.HEAVY_WEIGHT_APP_MEM 4096299. setprop ro.SECONDARY_SERVER_MEM 6144300. setprop ro.BACKUP_APP_MEM 6144301. setprop ro.HOME_APP_MEM 6144302. setprop ro.HIDDEN_APP_MEM 7168303. setprop ro.EMPTY_APP_MEM 8192304.305.# Write value must be consistent with the above properties.306.# Note that the driver only supports 6 slots, so we have combined some of 307.# the classes into the same memory level; the associated processes of higher 308.# classes will still be killed first.309. write /sys/module/lowmemorykiller/parameters/adj 0,1,2,4,7,15310.311. write /proc/sys/vm/overcommit_memory 1312. write /proc/sys/vm/min_free_order_shift 4313. write /sys/module/lowmemorykiller/parameters/minfree 2048,3072,4096,6144,7168,8192314.315. # Set init its forked children's oom_adj.316. write /proc/1/oom_adj -16317.318. # Tweak background writeout319. write /proc/sys/vm/dirty_expire_centisecs 200320. write /proc/sys/vm/dirty_background_ratio 5321.322. # Permissions for System Server and daemons.323. chown radio system /sys/android_power/state324. chown radio system /sys/android_power/request_state325. chown radio system /sys/android_power/acquire_full_wake_lock 326. chown radio system /sys/android_power/acquire_partial_wake_lock 327. chown radio system /sys/android_power/release_wake_lock328. chown radio system /sys/power/state329. chown radio system /sys/power/wake_lock330. chown radio system /sys/power/wake_unlock331. chmod 0660 /sys/power/state332. chmod 0660 /sys/power/wake_lock333. chmod 0660 /sys/power/wake_unlock334. chown system system /sys/class/timed_output/vibrator/enable335. chown system system /sys/class/leds/keyboard-backlight/brightness 336. chown system system /sys/class/leds/lcd-backlight/brightness 337. chown system system /sys/class/leds/button-backlight/brightness 338. chown system system /sys/class/leds/jogball-backlight/brightness 339. chown system system /sys/class/leds/red/brightness340. chown system system /sys/class/leds/green/brightness341. chown system system /sys/class/leds/blue/brightness342. chown system system /sys/class/leds/red/device/grpfreq343. chown system system /sys/class/leds/red/device/grppwm344. chown system system /sys/class/leds/red/device/blink345. chown system system /sys/class/leds/red/brightness346. chown system system /sys/class/leds/green/brightness347. chown system system /sys/class/leds/blue/brightness348. chown system system /sys/class/leds/red/device/grpfreq349. chown system system /sys/class/leds/red/device/grppwm350. chown system system /sys/class/leds/red/device/blink351. chown system system /sys/class/timed_output/vibrator/enable352. chown system system /sys/module/sco/parameters/disable_esco353. chown system system /sys/kernel/ipv4/tcp_wmem_min354. chown system system /sys/kernel/ipv4/tcp_wmem_def355. chown system system /sys/kernel/ipv4/tcp_wmem_max356. chown system system /sys/kernel/ipv4/tcp_rmem_min357. chown system system /sys/kernel/ipv4/tcp_rmem_def358. chown system system /sys/kernel/ipv4/tcp_rmem_max359. chown root radio /proc/cmdline360.361.# Define TCP buffer sizes for various networks362.# ReadMin, ReadInitial, ReadMax, WriteMin, WriteInitial, WriteMax, 363. setprop net.tcp.buffersize.default4096,87380,110208,4096,16384,110208364. setpropnet.tcp.buffersize.wifi 4095,87380,110208,4096,16384,110208365. setpropnet.tcp.buffersize.umts 4094,87380,110208,4096,16384,110208366. setprop net.tcp.buffersize.edge 4093,26280,35040,4096,16384,35040 367. setpropnet.tcp.buffersize.hspa 4094,87380,110208,4096,16384,110208368. setprop net.tcp.buffersize.gprs 4092,8760,11680,4096,8760,11680 369.370. chmod 0660 /sys/class/rfkill/rfkill0/state371. chmod 0660 /sys/class/rfkill/rfkill0/type372. chmod 0660 /sys/class/rfkill/rfkill1/state373. chmod 0660 /sys/class/rfkill/rfkill1/type374. chmod 0666 /sys/devices/platform/bd_address/bdaddr_if375. chown bluetooth bluetooth /sys/class/rfkill/rfkill0/state376. chown bluetooth bluetooth /sys/class/rfkill/rfkill0/type377. chown bluetooth bluetooth /sys/class/rfkill/rfkill1/state378. chown bluetooth bluetooth /sys/class/rfkill/rfkill1/type379. write /sys/class/rfkill/rfkill0/state 0380.381. chown system system /sys/devices/platform/motion_sensor/accel_onoff 382. chown system system /sys/devices/platform/motion_sensor/accel_delay 383. chown system system /sys/devices/platform/motion_sensor/compass_onoff 384. chown system system /sys/devices/platform/motion_sensor/compass_delay 385. chown system system /sys/devices/platform/motion_sensor/tilt_onoff 386. chown system system /sys/devices/platform/motion_sensor/tilt_delay 387. chown system system /sys/devices/platform/motion_sensor/gyro_onoff 388. chown system system /sys/devices/platform/motion_sensor/gyro_delay 389. chown system system /sys/bus/i2c/drivers/hub_proxi/3-0044/onoff 390. chown system system /sys/bus/i2c/drivers/hub_proxi/3-0044/delay 391. chown system system /sys/devices/platform/motion_sensor/shake_onoff 392. chown system system /sys/bus/i2c/drivers/kxtf9/3-000f/shake_onoff 393. chown system system /sys/devices/platform/motion_sensor/snap_onoff 394. chown system system /sys/bus/i2c/drivers/kxtf9/3-000f/snap_onoff 395. chown system system /sys/devices/platform/motion_sensor/flip_onoff 396. chown system system /sys/bus/i2c/drivers/kxtf9/3-000f/flip_onoff 397. chown system system /sys/devices/platform/motion_sensor/tap_onoff 398. chown system system /sys/bus/i2c/drivers/kxtf9/3-000f/tap_onoff 399. chown system system/sys/devices/platform/motion_sensor/yawimage_onoff400. chown system system/sys/devices/platform/i2c-gpio.7/i2c-adapter/i2c-7/7-001c/checkresult 401. chown system system/sys/devices/platform/i2c-gpio.7/i2c-adapter/i2c-7/7-001c/checkopmode 402. chmod 0666 /sys/devices/platform/motion_sensor/accel_onoff403. chmod 0666 /sys/devices/platform/motion_sensor/accel_delay404. chmod 0666 /sys/devices/platform/motion_sensor/compass_onoff 405. chmod 0666 /sys/devices/platform/motion_sensor/compass_delay 406. chmod 0666 /sys/devices/platform/motion_sensor/tilt_onoff407. chmod 0666 /sys/devices/platform/motion_sensor/tilt_delay408. chmod 0666 /sys/devices/platform/motion_sensor/gyro_onoff409. chmod 0666 /sys/devices/platform/motion_sensor/gyro_delay410. chmod 0666 /sys/bus/i2c/drivers/hub_proxi/3-0044/onoff411. chmod 0666 /sys/bus/i2c/drivers/hub_proxi/3-0044/delay412. chmod 0666 /sys/devices/platform/motion_sensor/shake_onoff413. chmod 0666 /sys/bus/i2c/drivers/kxtf9/3-000f/shake_onoff414. chmod 0666 /sys/devices/platform/motion_sensor/snap_onoff415. chmod 0666 /sys/bus/i2c/drivers/kxtf9/3-000f/snap_onoff416. chmod 0666 /sys/devices/platform/motion_sensor/flip_onoff417. chmod 0666 /sys/bus/i2c/drivers/kxtf9/3-000f/flip_onoff418. chmod 0666 /sys/devices/platform/motion_sensor/tap_onoff419. chmod 0666 /sys/bus/i2c/drivers/kxtf9/3-000f/tap_onoff420. chmod 0666 /sys/devices/platform/motion_sensor/yawimage_onoff 421. chmod 0666/sys/devices/platform/i2c-gpio.7/i2c-adapter/i2c-7/7-001c/checkresult 422. chmod 0666/sys/devices/platform/i2c-gpio.7/i2c-adapter/i2c-7/7-001c/checkopmode 423.424. chmod 0666 /sys/devices/platform/omapdss/display0/name425. chmod 0666 /sys/devices/platform/omapdss/display1/name426. chmod 0666 /sys/devices/platform/omapdss/display0/enabled427. chmod 0666 /sys/devices/platform/omapdss/display1/enabled428. chmod 0666 /sys/devices/platform/omapdss/display0/timings429. chmod 0666 /sys/devices/platform/omapdss/display1/timings430. chmod 0666 /sys/devices/platform/omapdss/overlay0/manager431. chmod 0666 /sys/devices/platform/omapdss/overlay1/manager432. chmod 0666 /sys/devices/platform/omapdss/overlay2/manager433. chmod 0666 /sys/devices/platform/omapdss/overlay0/zorder434. chmod 0666 /sys/devices/platform/omapdss/overlay1/zorder435. chmod 0666 /sys/devices/platform/omapdss/overlay2/zorder436. chmod 0666 /sys/devices/platform/omapdss/overlay0/enabled437. chmod 0666 /sys/devices/platform/omapdss/overlay1/enabled438. chmod 0666 /sys/devices/platform/omapdss/overlay2/enabled439. chmod 0666 /sys/devices/platform/omapdss/manager0/display440. chmod 0666 /sys/devices/platform/omapdss/manager1/display441. chmod 0666 /sys/devices/platform/omapdss/manager0/trans_key_enabled 442. chmod 0666 /sys/devices/platform/omapdss/manager1/trans_key_enabled 443. chmod 0666 /sys/devices/platform/omapdss/manager0/trans_key_type 444. chmod 0666 /sys/devices/platform/omapdss/manager1/trans_key_type 445. chmod 0666 /sys/devices/platform/omapdss/manager0/trans_key_value 446. chmod 0666 /sys/devices/platform/omapdss/manager1/trans_key_value 447. chmod 0666/sys/devices/platform/omapdss/manager0/alpha_blending_enabled448. chmod 0666/sys/devices/platform/omapdss/manager1/alpha_blending_enabled449. write /sys/devices/platform/omapdss/manager0/alpha_blending_enabled 1450.451.# MMS: Create log directory for fw3a_core452. mkdir /data/log/fw3A 0775 root root453.454.# change permissions for alsa nodes455. symlink /dev/snd/pcmC0D0c /dev/pcmC0D0c456. symlink /dev/snd/pcmC0D0p /dev/pcmC0D0p457. symlink /dev/snd/controlC0 /dev/controlC0458. symlink /dev/snd/timer /dev/timer459. chmod 0777 /dev/pcmC0D0c460. chmod 0777 /dev/pcmC0D0p461. chmod 0777 /dev/controlC0462. chmod 0777 /dev/timer463.464. chmod 0664/sys/devices/platform/i2c_omap.2/i2c-2/2-0060/leds/lcd-backlight/als 465. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-0060/leds/lcd-backlight/als 466.467. # Batt gauge error detection468. chmod 0666/sys/bus/platform/drivers/twl4030_bci/twl4030_bci/gauge_if469.470. # Enabling sleep in idle path471. write /sys/power/sleep_while_idle 1472.473. # Enabling Off mode474. write /sys/power/enable_off_mode 1475.476. # Enabling voltage off while idle477. write /sys/power/voltage_off_while_idle 1478.479. # Permissions for setting the DSP Frequency480. chown media root /sys/power/dsp_freq481. chown media system /sys/devices/platform/omap3isp/isp_reserve 482.483.# Include extra init file484. import /system/etc/init.local.rc485.486.# gps permissions487. chown system system /sys/devices/platform/hub_gps_gpio/poweron 488. chown system system /sys/devices/platform/hub_gps_gpio/reset 489. mkdir /data/gps490. chmod 777 /data/gps491. mkdir /data/gps/var492. chmod 777 /data/gps/var493. mkdir /data/gps/var/run494. chmod 777 /data/gps/var/run495. mkdir /data/gps/log496. chmod 777 /data/gps/log497. mkdir /data/cache498. chmod 777 /data/cache499.500. ## Torch perms501. chown system camera /sys/class/leds/rt8515/brightness502. chmod 0660 /sys/class/leds/rt8515/brightness503.504. ## liblights505. chown system system /sys/class/leds/lcd-backlight/brightness 506. chown system system /sys/class/leds/lcd-backlight/onoff 507. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/led_brightness 508. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/led_onoff509. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/led_sync510. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/blink_enable511. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/0x06512. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/0x07513. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/0x0D514. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/0x0E515. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/0x10 516. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/0x11 517. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/0x03 518. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/0x04 519. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/0x09 520. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/0x0A 521. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/0x13 522. chown system system/sys/devices/platform/i2c_omap.2/i2c-2/2-001a/0x14 523.524.# Run sysinit525. exec /system/bin/sysinit526.527. class_start default528.529.## Daemon processes to be run by init.530.##531.service ueventd /sbin/ueventd532. critical533.534.service prb /sbin/prb535. user root536. disabled537. oneshot538. keycodes 114 116539.540.service console /system/bin/sh541. console542. disabled543. user shell544. group log545.546.on property:ro.secure=0547. start console548.549.# adbd is controlled by the persist.service.adb.enable system property 550.service adbd /sbin/adbd551. disabled552.553.# adbd on at boot in emulator554.on property:ro.kernel.qemu=1555. start adbd556.557.on property:persist.service.adb.enable=1558. start adbd559.560.on property:persist.service.adb.enable=0561. stop adbd562.563.service pvrsrvinit /system/bin/pvrsrvinit564. user root565. oneshot566.567.# load DSP firmware 防火墙568.service baseimage /system/bin/cexec.out /system/lib/dsp/baseimage.dof 569. user root570. group audio571. oneshot572.573.service fw3a /system/bin/fw3a_core --dbgport=6660 --dbgremote --dbgpath=/data/log/fw3A574. user root575. group root576.577.service servicemanager /system/bin/servicemanager578. user system579. critical580. onrestart restart zygote581. onrestart restart media582.583.service vold /system/bin/vold584. socket vold stream 0660 root mount585. ioprio be 2586.587.service netd /system/bin/netd588. socket netd stream 0660 root system589. socket dnsproxyd stream 0660 root inet590.591.service debuggerd /system/bin/debuggerd592.593.service ril-daemon /system/bin/rild594. socket rild stream 660 root radio595. socket rild-debug stream 660 radio system596. user root597. group radio cache inet misc audio sdcard_rw net_admin net_raw 598.599.service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server600. socket zygote stream 666601. onrestart write /sys/android_power/request_state wake602. onrestart write /sys/power/state on603. onrestart restart media604. onrestart restart netd605.606.service media /system/bin/mediaserver607. user media608. group system audio camera graphics inet net_bt net_bt_admin net_raw 609. ioprio rt 4610.611.service bootanim /system/bin/bootanimation612. user graphics613. group graphics614. disabled615. oneshot616.617.service dbus /system/bin/dbus-daemon --system --nofork618. socket dbus stream 660 bluetooth bluetooth619. user bluetooth620. group bluetooth net_bt_admin621.622.service bluetoothd /system/bin/bluetoothd -n623. socket bluetooth stream 660 bluetooth bluetooth624. socket dbus_bluetooth stream 660 bluetooth bluetooth625. # init.rc does not yet support applying capabilities, so run as root and626. # let bluetoothd drop uid to bluetooth with the right linux capabilities 627. group bluetooth net_bt_admin misc628. disabled629.630.service hfag /system/bin/sdptool add --channel=10 HFAG631. user bluetooth。
Android 6.0启动过程详细解析
![Android 6.0启动过程详细解析](https://img.taocdn.com/s3/m/2cd22e333169a4517723a3a0.png)
Android 6.0启动过程详细解析从代码角度仔细学习Android系统的启动过程,同时,学习Android启动过程中的初始化脚本语言,即init.rc中的语言语法。
在这里,不在详细介绍Linux内核的启动过程,主要学习从Linux内核启动之后,init初始化是如何工作的,他是如何启动Android系统的第一个进程–Zygote进程。
并且还会继续了解后面其他的进程是如何通过Zygote进程启动的。
话不多说,我们现在就来气Android系统启动之路。
## Android系统启动流程图我们都知道,Android系统内核是基于Linux内核,所以在Android系统启动过程中,首先启动Linux内核,Bootloader加载并启动Linux内核,内核启动完成之后,内核开始启动Android系统的init进程,然后init进程通过init.rc启动脚本语言的执行,来启动Zygote进程,作为Android其他进程的父进程,Zygote进程做完初始化工作之后,启动SystemServer 来启动其他系统服务。
下面我们从init进程的启动开始学习。
int main(int argc, char** argv) {if (!strcmp(basename(argv[0]), "ueventd")) {return ueventd_main(argc, argv);}if (!strcmp(basename(argv[0]), "watchdogd")) {return watchdogd_main(argc, argv);}// Clear the umask.umask(0);add_environment("PA TH", _PATH_DEFPATH);bool is_first_stage = (argc == 1) || (strcmp(argv[1], "--second-stage") != 0);// Get the basic filesystem setup we need put together in the initramdisk// on / and then we'll let the rc file figure out the rest.if (is_first_stage) {mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");mkdir("/dev/pts", 0755);mkdir("/dev/socket", 0755);mount("devpts", "/dev/pts", "devpts", 0, NULL);mount("proc", "/proc", "proc", 0, NULL);mount("sysfs", "/sys", "sysfs", 0, NULL);}// We must have some place other than / to create the device nodes for// kmsg and null, otherwise we won't be able to remount / read-only// later on. Now that tmpfs is mounted on /dev, we can actually talk// to the outside world.open_devnull_stdio();klog_init();klog_set_level(KLOG_NOTICE_LEVEL);NOTICE("init%s started!\n", is_first_stage ? "" : " second stage");if (!is_first_stage) {// Indicate that booting is in progress to background fw loaders, etc.close(open("/dev/.booting", O_WRONL Y | O_CREAT | O_CLOEXEC, 0000));property_init();// If arguments are passed both on the command line and in DT,// properties set in DT always have priority over the command-line ones.process_kernel_dt();process_kernel_cmdline();// Propogate the kernel variables to internal variables// used by init as well as the current required properties.export_kernel_boot_props();}// Set up SELinux, including loading the SELinux policy if we're in the kernel domain. selinux_initialize(is_first_stage);// If we're in the kernel domain, re-exec init to transition to the init domain now// that the SELinux policy has been loaded.if (is_first_stage) {if (restorecon("/init") == -1) {ERROR("restorecon failed: %s\n", strerror(errno));security_failure();}char* path = argv[0];char* args[] = { path, const_cast<char*>("--second-stage"), nullptr };if (execv(path, args) == -1) {ERROR("execv(\"%s\") failed: %s\n", path, strerror(errno));security_failure();}}// These directories were necessarily created before initial policy load// and therefore need their security context restored to the proper value.// This must happen before /dev is populated by ueventd.INFO("Running restorecon...\n");restorecon("/dev");restorecon("/dev/socket");restorecon("/dev/__properties__");restorecon_recursive("/sys");epoll_fd = epoll_create1(EPOLL_CLOEXEC);if (epoll_fd == -1) {ERROR("epoll_create1 failed: %s\n", strerror(errno));exit(1);}signal_handler_init();property_load_boot_defaults();start_property_service();init_parse_config_file("/init.rc");action_for_each_trigger("early-init", action_add_queue_tail);// Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");// ... so that we can start queuing up actions that require stuff from /dev.queue_builtin_action(mix_hwrng_into_linux_rng_action,"mix_hwrng_into_linux_rng");queue_builtin_action(keychord_init_action, "keychord_init");queue_builtin_action(console_init_action, "console_init");// Trigger all the boot actions to get us started.action_for_each_trigger("init", action_add_queue_tail);// Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random// wasn't ready immediately after wait_for_coldboot_donequeue_builtin_action(mix_hwrng_into_linux_rng_action,"mix_hwrng_into_linux_rng");// Don't mount filesystems or start core system services in charger mode.char bootmode[PROP_V ALUE_MAX];if (property_get("ro.bootmode", bootmode) > 0 && strcmp(bootmode, "charger") == 0) {action_for_each_trigger("charger", action_add_queue_tail);} else {action_for_each_trigger("late-init", action_add_queue_tail);}// Run all property triggers based on current state of the properties.queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");while (true) {if (!waiting_for_exec) {execute_one_command();restart_processes();}int timeout = -1;if (process_needs_restart) {timeout = (process_needs_restart - gettime()) * 1000;if (timeout < 0)timeout = 0;}if (!action_queue_empty() || cur_action) {timeout = 0;}bootchart_sample(&timeout);epoll_event ev;int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));if (nr == -1) {ERROR("epoll_wait failed: %s\n", strerror(errno));} else if (nr == 1) {((void (*)()) ev.data.ptr)();}}return 0;}该文件位于system/core/init/init.cpp中,我们来看看init进程都做了哪些工作。
linux内核启动Android系统启动过程详解
![linux内核启动Android系统启动过程详解](https://img.taocdn.com/s3/m/de4b2665ad51f01dc281f1ef.png)
linux内核启动+Android系统启动过程详解第一部分:汇编部分Linux启动之linux-rk3288-tchip/kernel/arch/arm/boot/compressed/head.S分析这段代码是linux boot后执行的第一个程序,完成的主要工作是解压内核,然后跳转到相关执行地址。
这部分代码在做驱动开发时不需要改动,但分析其执行流程对是理解android的第一步开头有一段宏定义这是gnu arm汇编的宏定义。
关于GUN 的汇编和其他编译器,在指令语法上有很大差别,具体可查询相关GUN汇编语法了解另外此段代码必须不能包括重定位部分。
因为这时一开始必须要立即运行的。
所谓重定位,比如当编译时某个文件用到外部符号是用动态链接库的方式,那么该文件生成的目标文件将包含重定位信息,在加载时需要重定位该符号,否则执行时将因找不到地址而出错#ifdef DEBUG//开始是调试用,主要是一些打印输出函数,不用关心#if defined(CONFIG_DEBUG_ICEDCC)……具体代码略#endif宏定义结束之后定义了一个段,.section ".start", #alloc, #execinstr这个段的段名是 .start,#alloc表示Section contains allocated data, #execinstr表示Sectioncontains executable instructions.生成最终映像时,这段代码会放在最开头.alignstart:.type start,#function /*.type指定start这个符号是函数类型*/.rept 8mov r0, r0 //将此命令重复8次,相当于nop,这里是为中断向量保存空间.endrb 1f.word 0x016f2818 @ Magic numbers to help the loader.word start @ absolute load/run zImage//此处保存了内核加载和运行的地址,实质上也是本函数的运行地址address.word _edata@ 内核结束地址//注意这些地址在顶层vmlixu.lds(具体在/kernel文件夹里)里进行了定义,是链接的地址,加载内核后可能会进行重定位1: mov r7, r1 @ 保存architecture ID,这里是从bootload传递进来的mov r8, r2 @ 保存参数列表atags指针r1和r2中分别存放着由bootloader传递过来的architecture ID和指向标记列表的指针。
linux 内核启动过程以及挂载android 根文件系统的过程
![linux 内核启动过程以及挂载android 根文件系统的过程](https://img.taocdn.com/s3/m/4cf3a22fbd64783e09122b52.png)
主要介绍linux 内核启动过程以及挂载android 根文件系统的过程,以及介绍android 源代码中文件系统部分的浅析。
主要源代码目录介绍Makefile (全局的Makefile)bionic (Bionic 含义为仿生,这里面是一些基础的库的源代码)bootable (引导加载器)build (build 目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具)dalvik (JAVA 虚拟机)development (程序开发所需要的模板和工具) external (目标机器使用的一些库)frameworks (应用程序的框架层)hardware (与硬件相关的库)packages (Android 的各种应用程序)prebuilt (Android 在各种平台下编译的预置脚本)recovery (与目标的恢复功能相关)system (Android 的底层的一些库)out (编译完成后产生的目录,也就是我们移植文件系统需要的目录)host 目录的结构如下所示:out/host/|-- common| `-- obj (JAVA 库)`-- linux-x86|-- bin (二进制程序)|-- framework (JAVA 库,*.jar 文件)|-- lib (共享库*.so)`-- obj (中间生成的目标文件)host 目录是一些在主机上用的工具,有一些是二进制程序,有一些是JAVA 的程序。
target 目录的结构如下所示:out/target/|-- common| |-- R (资源文件)| |-- docs| `-- obj (目标文件)`-- product`-- generic其中common 目录表示通用的内容,product 中则是针对产品的内容。
在common 目录的obj 中,包含两个重要的目录:APPS 中包含了JAVA 应用程序生成的目标,每个应用程序对应其中一个子目录,将结合每个应用程序的原始文件生成Android 应用程序的APK包。
九浅一深_Android_kernel的启动
![九浅一深_Android_kernel的启动](https://img.taocdn.com/s3/m/6a5febca5fbfc77da269b1bb.png)
地址 无关 编译
test_e=(test_a+test_b)%6;
return test_e; }
.text 0x00000000: 0x00000002: 0x00000004: 0x00000006: 0x00000008: 0x0000000a: 0x0000000c: 0x0000000e: 0x00000010: 0x00000012: 0x00000014: 0x00000016: 0x00000018: 0x0000001a: 0x0000001c: 0x0000001e: 0x00000020: 0x00000022: 0x00000024: 0x00000026: 0x00000028: 0x0000002a:
究浅意深android之实战篇系列
Android
Qualcomm MSM7X27 平台
Linux系统(kernel)的启动
林耕书
Agenda
1.Kernel镜像bootimage的内部结构。 2.Kernel的编译过程(zImage的生成过程)。 3.Kernel的启动过程(一直讲到start_kernel)。
z对Image进行压缩
gzip接着对Image这个二进制文件 进行压缩生成piggy.gz文件
而piggy.gz这个文件又被直接以 bin的形式直接include到piggy.S 这个汇编文件中去。
Kernel\arch\arm\boot\compressed\piggy.S
.section .piggydata,#alloc .globl input_data input_data: .incbin “arch/arm/boot/compressed/piggy.gz“ .globl input_data_end input_data_end:
android开机启动流程说明
![android开机启动流程说明](https://img.taocdn.com/s3/m/c1dc8fcc4028915f804dc2f1.png)
android开机启动流程说明第一步:启动linux1.Bootloader2.Kernel第二步android系统启动:入口为init.rc(system\core\rootdir)1./system/bin/service manager: Binder 守护进程;2.Runtime;3.Zygote :app-process/app-main;4.Start VM;5.Start server6.Start android service:Register to service Manager7.Start Launcher第三步:应用程序启动:运行package Managerl Init进程Android系统在启动时首先会启动Linux系统,引导加载Linux Kernel并启动init进程。
Init进程是一个由内核启动的用户级进程,是Android系统的第一个进程。
该进程的相关代码在platform\system\core\init\init.c。
在main 函数中,有如下代码:open_devnull_stdio();log_init();INFO("reading config file\n");init_parse_config_file("/init.rc");/* pull the kernel commandline and ramdisk properties file in */import_kernel_cmdline(0);get_hardware_name(hardware, &revision);snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);init_parse_config_file(tmp);这里会加载解析init.rc和init.hardware.rc两个初始化脚本。
Android 启动过程
![Android 启动过程](https://img.taocdn.com/s3/m/e55df3c9a1c7aa00b52acb2c.png)
第1章Android 启动过程1.1Android 启动介绍众所周知,Android是一款基于linux基础的开放源代码的手机操作系统,是以linux内核为操作系统的内核。
那Android的启动也是在linux内核加载之后进行的。
Linux内核由bootloader加载后,经自解压、初始化、顺序载入内核模块(其中包含驱动程序)等。
在内核加载完成之后,会根据内核的传递参数寻找android的第一个用户态进程,即init进程。
Init进程根据init.rc以及init.$(hardware).rc脚本文件来启动android的必要的服务。
直到完成android 的HOME的启动。
1.1.1启动总体框架1.1.2Linux Kernel启动Start_kernel(/init/main.c),是内核启动的入口函数,它所做的事情很多,比如:中断和内存的初始化,以及内核模块的加载等。
在start_kernel函数的最后调用了rest_init。
static noinline void __init_refok rest_init(void){int pid;……kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);……}注意到在rest_init函数中开启了一个kernel_init的内核线程。
继续看kernel_init。
static int __init kernel_init(void * unused){……init_post();return 0;}static noinline int init_post(void){……run_init_process("/sbin/init");run_init_process("/etc/init");run_init_process("/bin/init");run_init_process("/bin/sh");panic("No init found. Try passing init= option to kernel. ""See Linux Documentation/init.txt for guidance.");}1.1.3Android Init进程Android是基于linux内核的,在内核引导和加载完毕,从上面的代码可以看出init进程是从内核态转换到到用户态的第一个应用程序。
Android系统启动过程-uBoot+Kernel+Android
![Android系统启动过程-uBoot+Kernel+Android](https://img.taocdn.com/s3/m/1fc92eabfc0a79563c1ec5da50e2524de518d04a.png)
Android系统启动过程-uBoot+Kernel+Android摘要:本⽂是参考⼤量⽹上资源在结合⾃⼰查看源代码总结出来的,让⾃⼰同时也让⼤家加深对Android系统启动过程有⼀个更加深⼊的了解!再次强调,本⽂的⼤多数功劳应归功于那些原创者们,同时⼀些必要的参考链接我会⼀⼀附上。
注:由于本⼈采⽤Exynos4412开发板学习,所以本⽂⼤部分资料都是基于此处理器的简介:对于整个Android系统的启动总的来说分为三个阶段: BootLoader引导即uBoot.bin linux内核启动即zImage Android系统启动即ramdisk.img与system.img 以上四个⽂件都是经过⾃⼰编译后⽣成的且通过烧写测试,接下来开始说这三⼤部分的启动过程。
⽬录:⼀、BootLoader的启动 1.汇编部分 2.c部分 ⼆、Kernel的启动 1.zImage解压缩 2.kernel的汇编启动阶段 3.kernel的c启动阶段 三、Android的启动 1.init进程 2.init启动的各种服务 3.android启动图⽰第⼀部分:BootLoader的启动流程 uBoot的第⼀条指令从cpu/arm920t/start.S⽂件开始 1. 设置CPU进⼊SVC模式(系统管理模式),cpsr[4:0]=0xd3。
1 #include <common.h>2 #include <config.h>34/*5 *************************************************************************6 *7 * Jump vector table as in table 3.1 in [1]8 *9 *************************************************************************10*/111213 .globl _start14 _start: b start_code15 ldr pc, _undefined_instruction16 ldr pc, _software_interrupt17 ldr pc, _prefetch_abort18 ldr pc, _data_abort19 ldr pc, _not_used20 ldr pc, _irq21 ldr pc, _fiq2223 _undefined_instruction: .word undefined_instruction24 _software_interrupt: .word software_interrupt25 _prefetch_abort: .word prefetch_abort26 _data_abort: .word data_abort27 _not_used: .word not_used28 _irq: .word irq29 _fiq: .word fiq3031 .balignl 16,0xdeadbeef 接着进⼊Start_code中:设置CPU进⼊SVC模式。
详解Android系统启动过程
![详解Android系统启动过程](https://img.taocdn.com/s3/m/4dbab827effdc8d376eeaeaad1f34693daef10e3.png)
详解Android系统启动过程⽬录计算机是如何启动的引导阶段加载内核阶段Android的启动过程init进程init.rc ⽂件service_manager 进程surface_flinger 进程media_server 进程Zygote 进程system_server 进程ActivityManagerService 启动完整的启动流程图计算机是如何启动的计算机的硬件包括:CPU,内存,硬盘,显卡,显⽰器,键盘⿏标等输⼊输出设备。
所有的软件都是存放在硬盘中,程序执⾏时,需要将程序从硬盘上读取到内存中,然后加载到CPU中来运⾏。
当按下开机键时,内存中什么都没有,因此需要借助某种⽅式,将操作系统加载到内存中,⽽完成这项任务的就是BIOS。
引导阶段BIOS:BIOS是主板芯⽚上的⼀个程序,计算机通电后,第⼀件事情就是读取BIOS。
BIOS⾸先进⾏硬件检测,检查计算机硬件能否满⾜运⾏的基本条件。
如果硬件出现问题,主板发出不同的蜂鸣声,启动停⽌。
如果没有问题,屏幕会显⽰CPU,内存,硬盘等信息。
硬件⾃检完成后,BIOS将控制权交给下⼀个阶段的启动程序。
这时候BIOS需要知道下⼀个启动程序存放在哪个设备中。
也就是BIOS需要⼀个外部存储设备的排序。
优先交给排在前⾯的设备。
这就是我们在BIOS中设置的启动排序。
当第⼀个存储设备被激活后,设备读取设备的第⼀个扇区,也就是前512字节。
如果这512个字节的最后两个字节是0x55和0xAA,表明设备是可以⽤作系统启动的。
如果不是,那么就会顺序启动下⼀个设备。
这前512个字节,就叫做“主引导记录”(缩写MBR)。
它负责磁盘操作系统对硬盘进⾏读写时分区合法型判断、分区引导信息定位。
MBR不属于任何⼀个CIA做系统,它先于操作系统⽽被调⼊内存,并发挥作⽤。
然后才将控制权交给主分区内的操作系统,并⽤主分区信息来管理硬盘。
MBR主要作⽤是告诉计算机到硬盘的哪个位置去找操作系统。
Android 启动过程分析
![Android 启动过程分析](https://img.taocdn.com/s3/m/fc7729375a8102d276a22f13.png)
Android 启动过程分析本文来自moko365的Jollen Chen老师的分析,网络一些文章还有加上个人理解。
不一一写明出处。
首先看看整体开机流程。
这个对于软件开发测试工作非常有用,特别是在项目初期的时候,通常出在驱动或者启动参数上面的问题比较多,比如关机充电,连接charger关机等问题。
一般开机过程大致可以分为三个大阶段:1. OS级别,由bootloader载入linux kernel后(注:bootloader和制造商有关,一般都是自己修改后的bootloader,大同小异,无外乎加载了自己的安全机制,我们可以用最常见的uboot来考虑),kernel开始初始化, 并载入built-in 的驱动程序。
Kernel完成开机后,载入init process,切换至user-space后,结束kernel 的循序过程(sequence),进入排程模式(process scheduling)。
2. Android-level,由init process 开始,读取init.rc,Native 服务启动,并启动重要的外部程序,例如:servicemanager、Zygote以及System Server。
3. Zygote-Mode,Zygote 启动完SystemServer 后,进入Zygote Mode,在Socket 等候命令。
随后,使用者将看到一个桌面环境(Home Screen)。
桌面环境由一个名为[Launcher]的应用程序负责提供。
注:Zygote干嘛用的?主要负责启动system server和执行android程序(APK)。
成功启动system server后会使用socket 方式监听(monitor android apps/prcesses)我们的image都包含什么?Bootloader,system(是Android镜像),data(用户数据/data),kernel(android linux kernel,基础OS,负责process 管理,HAL和一些系统程序),ramdisk(init装载,/system/init/init.c).关于开机时间长短问题,对于产品开机和关机时间长短,直接影响到用户的感受,所以我们需要对开机时间进行评估。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
linux内核启动+Android系统启动过程详解第一部分:汇编部分Linux启动之linux-rk3288-tchip/kernel/arch/arm/boot/compressed/head.S分析这段代码是linux boot后执行的第一个程序,完成的主要工作是解压内核,然后跳转到相关执行地址。
这部分代码在做驱动开发时不需要改动,但分析其执行流程对是理解android的第一步开头有一段宏定义这是gnu arm汇编的宏定义。
关于GUN 的汇编和其他编译器,在指令语法上有很大差别,具体可查询相关GUN汇编语法了解另外此段代码必须不能包括重定位部分。
因为这时一开始必须要立即运行的。
所谓重定位,比如当编译时某个文件用到外部符号是用动态链接库的方式,那么该文件生成的目标文件将包含重定位信息,在加载时需要重定位该符号,否则执行时将因找不到地址而出错#ifdef DEBUG//开始是调试用,主要是一些打印输出函数,不用关心#if defined(CONFIG_DEBUG_ICEDCC)……具体代码略#endif宏定义结束之后定义了一个段,.section ".start", #alloc, #execinstr这个段的段名是 .start,#alloc表示Section contains allocated data, #execinstr表示Sectioncontains executable instructions.生成最终映像时,这段代码会放在最开头.alignstart:.type start,#function /*.type指定start这个符号是函数类型*/.rept 8mov r0, r0 //将此命令重复8次,相当于nop,这里是为中断向量保存空间.endrb 1f.word 0x016f2818 @ Magic numbers to help the loader.word start @ absolute load/run zImage//此处保存了内核加载和运行的地址,实质上也是本函数的运行地址address.word _edata@ 内核结束地址//注意这些地址在顶层vmlixu.lds(具体在/kernel文件夹里)里进行了定义,是链接的地址,加载内核后可能会进行重定位1: mov r7, r1 @ 保存architecture ID,这里是从bootload传递进来的mov r8, r2 @ 保存参数列表atags指针r1和r2中分别存放着由bootloader传递过来的architecture ID和指向标记列表的指针。
这里将这两个参数先保存。
#ifndef __ARM_ARCH_2__/** Booting from Angel - need to enter SVC mode and disable* FIQs/IRQs (numeric definitions fromangel arm.h source).* We only do this if we were in user modeon entry.*/读取cpsr并判断是否处理器处于supervisor模式——从bootload进入kernel,系统已经处于SVC32模式;而利用angel进入则处于user模式,还需要额外两条指令。
之后是再次确认中断关闭,并完成cpsr写入Angel 是ARM的调试协议,一般用的是MULTI-ICE。
ANGLE需要在板子上有驻留程序,然后通过串口就可以调试了。
用过的AXD或trace调试环境的话,对此应该比较熟悉。
not_angel: //若不是通过angel调试进入内核mrs r2, cpsr @ turn off interrupts toorr r2, r2, #0xc0 @ prevent angel from runningmsr cpsr_c, r2 //这里将cpsr中I、F位分别置“1”,关闭IRQ和FIQ#elseteqp pc, #0x0c000003 @ turn off interrupts常用TEQP PC,#(新模式编号)来改变模式#endif另外链接器会把一些处理器相关的代码链接到这个位置,也就是arch/arm/boot/compressed/head-xxx.S文件中的代码。
在高通平台下,这个文件是head-msm.S连接脚是compress/vmlinux.lds,其中部分内容大致如下,在连接时,连接器根据每个文件中的段名将相同的段合在一起,比如将head.S和head-msm.S的.start段合在一起SECTIONS{. = TEXT_START;_text = .;.text : {_start = .;*(.start)*(.text)*(.text.*)*(.fixup)*(.gnu.warning)*(.rodata)*(.rodata.*)*(.glue_7)*(.glue_7t)*(.piggydata). = ALIGN(4);}_etext = .;}下面即进入.text段.textadr r0, LC0 //当前运行时LC0符号所在地址位置,注意,这里用的是adr指令,这个指令会根据目前PC的值,计算符号相对于PC的位置,是个相对地址。
之所以这样做,是因为下面指令用到了绝对地址加载ldmia指令,必须要调整确定目前LC0的真实位置,这个位置也就是用adr来计算ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp}subs r0, r0, r1 @ //这里获得当前LCD0实际地址与链接地址差值//r1即是LC0的连接地址,也即由vmlinux.lds定位的地址//差值存入r0中。
beq not_relocated //如果相等不需要重定位,因为已经在正确的//地址运行了。
重定位的原因是,MMU 单元未使能,不能进行地址映射,必须要手工重定位。
下面举个简单例子说明:如果连接地址是0xc0000000,那么LC0的连接地址假如连接为0xc0000010,那么LC0相对于连接起始地址的差为0x10,当此段代码是从0xc0000000运行的话,那么执行adr r0,LC0的值实际上按下面公式计算:R0=PC+0x10,由于PC=连接处的值,可知,此时是在ram 中运行,同理如果是在不是在连接处运行,则假设是在0x00000000处运行,则R0=0x00000000+0x10,可知,此时不是在ram的连接处运行。
上面这几行代码用于判断代码是否已经重定位到内存中,LC0这个符号在head.S中定义如下,实质上相当于c语言的全局数据结构,结构的每个域存储的是一个指针。
指针本身的值代表不同的代码段,已经在顶层连接脚本vmlinux.lds 里进行了赋值,比如_start是内核开始的地址.type LC0, #objectLC0: .word LC0 @r1 //这个要加载到r1中的LC0是链接时LC0的地址.word __bss_start @ r2.word _end@ r3.word zreladdr @ r4.word _start @ r5.word _got_start @ r6.word _got_end @ ip.word user_stack+4096@ sp通过当前运行时LC0的地址与链接器所链接的地址进行比较判断。
若相等则是运行在链接的地址上。
如果不是运行在链接的地址上,则下面的代码必须修改相关地址,进行重新运行/** r5 - zImage base address* r6 - GOT start* ip - GOT end*///修正实际运行的位置,否则跳转指令就找不到相关代码add r5, r5, r0 //修改内核映像基地址add r6, r6, r0add ip, ip, r0 //修改got表的起始和结束位置#ifndef CONFIG_ZBOOT_ROM/*若没有定义CONFIG_ZBOOT_ROM,此时运行的是完全位置无关代码位置无关代码,也就是不能有绝对地址寻址。
所以为了保持相对地址正确,需要将bss段以及堆栈的地址都进行调整* r2 - BSS start* r3 - BSS end* sp - stack pointer*/add r2, r2, r0add r3, r3, r0add sp, sp, r0//全局符号表的地址也需要更改,否则,对全局变量引用将会出错1: ldr r1, [r6, #0] @ relocate entries in the GOTadd r1, r1, r0 @ table. This fixes up thestr r1, [r6], #4 @ C references.cmp r6, ipblo 1b#else //若定义了CONFIG_ZBOOT_ROM,只对got表中在bss段以外的符号进行重定位1: ldr r1, [r6, #0] @ relocate entries in the GOTcmp r1, r2 @ entry < bss_start ||cmphs r3, r1 @ _end < entryaddlo r1, r1, r0 @ table. This fixes up thestr r1, [r6], #4 @ C references.cmp r6, ipblo 1b#endif如果运行当前运行地址和链接地址相等,则不需进行重定位。
直接清除bss段not_relocated: mov r0, #01: str r0, [r2], #4 @ clear bssstr r0, [r2], #4str r0, [r2], #4str r0, [r2], #4cmp r2, r3blo 1b之后跳转到cache_on处bl cache_oncache_on定义.align 5cache_on: mov r3, #8 @ cache_on functionb call_cache_fn把r3的值设为8。
这是一个偏移量,也就是索引proc_types 中的操作函数。
然后跳转到call_cache_fn。
这个函数的定义如下:call_cache_fn:adr r12, proc_types //把proc_types的相对地址加载到r12中#ifdef CONFIG_CPU_CP15mrc p15, 0, r6, c0, c0 @ get processor ID#elseldr r6, =CONFIG_PROCESSOR_ID#endif1: ldr r1, [r12, #0] @ get valueldr r2, [r12, #4] @ get maskeor r1, r1, r6 @ (real ^ match)tst r1, r2 @是否和CPU ID 匹配?addeq pc, r12, r3 @ 用刚才的偏移量,查找//到cache操作函数,找到后就执行相关操作,比如执行 b __armv7_mmu_cache_on//add r12, r12, #4*5 //如果不相等,则偏移到下个proc_types结构处b 1baddeq pc, r12, r3 @ call cache functionproc_type的定义如下,实质上还是一张数据结构表.type proc_types,#objectproc_types:.word 0x41560600 @ ARM6/610.word 0xffffffe0b __arm6_mmu_cache_off @ works, but slowb __arm6_mmu_cache_offmov pc, lr@ b __arm6_mmu_cache_on@ untested@ b __arm6_mmu_cache_off@ b __armv3_mmu_cache_flush.word 0x00000000 @ old ARM ID.word 0x0000f000mov pc, lrmov pc, lrmov pc, lr.word 0x41007000 @ ARM7/710.word 0xfff8fe00b __arm7_mmu_cache_offb __arm7_mmu_cache_offmov pc, lr.word 0x41807200 @ ARM720T (writethrough).word 0xffffff00b __armv4_mmu_cache_onb __armv4_mmu_cache_offmov pc, lr.word 0x41007400 @ ARM74x.word 0xff00ff00b __armv3_mpu_cache_onb __armv3_mpu_cache_offb __armv3_mpu_cache_flush.word 0x41009400 @ ARM94x.word 0xff00ff00b __armv4_mpu_cache_onb __armv4_mpu_cache_offb __armv4_mpu_cache_flush.word 0x00007000 @ ARM7 IDs.word 0x0000f000mov pc, lrmov pc, lrmov pc, lr@ Everything from here on will be the new ID system..word 0x4401a100 @ sa110 / sa1100.word 0xffffffe0b __armv4_mmu_cache_onb __armv4_mmu_cache_offb __armv4_mmu_cache_flush.word 0x6901b110 @ sa1110.word 0xfffffff0b __armv4_mmu_cache_onb __armv4_mmu_cache_offb __armv4_mmu_cache_flush@ These match on the architecture ID.word 0x00020000 @.word 0x000f0000 //b __armv4_mmu_cache_onb __armv4_mmu_cache_on //指令的地址b __armv4_mmu_cache_offb __armv4_mmu_cache_flush.word 0x00050000 @ ARMv5TE.word 0x000f0000b __armv4_mmu_cache_onb __armv4_mmu_cache_offb __armv4_mmu_cache_flush.word 0x00060000 @ ARMv5TEJ.word 0x000f0000b __armv4_mmu_cache_onb __armv4_mmu_cache_offb __armv4_mmu_cache_flush.word 0x0007b000 @ ARMv6.word 0x0007f000b __armv4_mmu_cache_onb __armv4_mmu_cache_offb __armv6_mmu_cache_flush.word 0 @ unrecognised type.word 0mov pc, lrmov pc, lrmov pc, lr.size proc_types, . - proc_types找到执行的cache函数后,就用上面的addeq pc, r12, r3直接跳转,例如执行下面这个处理器结构的cache函数__armv7_mmu_cache_on:mov r12, lr //注意,这里需要手工保存返回地址!!这样做的原因是下面的bl指令会覆盖掉原来的lr,为保证程序正确返回,需要保存原来lr的值bl __setup_mmumov r0, #0mcr p15, 0, r0, c7, c10, 4 @ drainwrite buffermcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBsmrc p15, 0, r0, c1, c0, 0 @ read control regorr r0, r0, #0x5000 @I-cache enable, RR cache replacementorr r0, r0, #0x0030bl __common_mmu_cache_onmov r0, #0mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBsmov pc, r12 //返回到cache_on这个函数首先执行__setup_mmu,然后清空write buffer、I/Dcache、TLB.接着打开i-cache,设置为Round-robin replacement。