Android设备的启动必须经历3个阶段,即Boot Loader、Linux Kernel和Android系统服务。
init是Linux系统中用户空间的第一个进程,pid = 1。init进程将通过解析init.rc来启动其他关键的系统服务进程——zygote、systemserver、servicemanager。
目录
6. AndroidRuntime.register_jni_procs()
一、.rc语法
我们在HAL层实现HIDL service或者Native service时都会编写.rc文件,所以此处介绍下.rc文件的语法。
一个rc文件由action、command、service、option四种类型组成。action和service表示一个新语句的开始,这两个关键字后会跟着command和option。
1.Action常见的trigger
Trigger | Description |
boot | 这是init程序启动后触发的第一个事件 |
<name>=<value> | 条件成立时触发 |
device-added-<path> devicce-removed-<path> | 设备节点添加/删除时触发 |
service-exited-<name> | 当指定服务<name>存在时触发 |
2.常见的command
exec <path> [<argument>] | Fork并执行一个路径为path的程序。该指令会阻塞,直到该程序启动完成。 |
chmod <octal-mode><path> | 更改文件的访问权限 |
class_start <serviceclass> | 启动由<serviceclasss>类名指定的所有相关服务,若该service不在运行状态。 |
class_stop <serviceclass> | 停止<servicceclass>指定的服务,若他们正在运行时。 |
setprop <name><value> | 设置系统属性<name>的值为value。 |
export <name> <value> | 设置环境变量,对全局有效。 |
mount <type><device><dir> [<mountoption>] | 在指定路径上挂载一个设备 |
3.service格式
service <name> <pathname> [<argument>] <option> ...
4.常见的option
Option | Description |
critical | 关键服务,如果该服务在4min中退出超过4次,则设备进入recovery mode。 |
disable | 该服务不会自启动,需要显式调用服务名来启动。 |
oneshot | 当该服务退出时,不会自动重启。 |
onrestart | 当该服务重启时,执行某些命令 |
setenv <name><value> | 设置环境变量 |
class <name> | 为该服务指定一个class名。同一个class的所有服务必须同时start或stop。默认class名为default。 |
user <username> | 启动该服务前将用户切换至<username>,默认user为root |
group <groupname> [<groupname>] | 启动该服务前将用户切换到groupname |
二、init.rc文件
1.路径:/system/core/rootdir/init.rc
on zygote-start && property:ro.crypto.state=unencrypted
wait_for_prop odsign.verification.done 1
# A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted
start statsd
start netd
start zygote
start zygote_secondary
2.根据设备支持32位或者64位的不同,会分别启动不同的Zygote,所以会有init.zygote64.rc、init.zygote64_32.rc、init.zygote32.rc。下边是即支持32bit和64bit的设备的init.zygote64_32.rc文件内容:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
socket usap_pool_primary stream 660 root system
onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
task_profiles ProcessCapacityHigh MaxPerformance
critical window=${zygote.critical_window.minute:-off} target=zygote-fatal
service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
class main
priority -20
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system
socket usap_pool_secondary stream 660 root system
onrestart restart zygote
task_profiles ProcessCapacityHigh MaxPerformance
三、Zygote进程启动过程
c++路径为:/frameworks/base/cmds/app_process/app_main.cpp。
java路径为:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
1. zygote启动时序图
2. app_process的Android.bp
cc_binary {
name: "app_process",
srcs: ["app_main.cpp"],
multilib: {
lib32: {
suffix: "32",
},
lib64: {
suffix: "64",
},
},
shared_libs: [
"libandroid_runtime",
"libbinder",
"libcutils",
"libdl",
"libhidlbase",
"liblog",
"libnativeloader",
"libsigchain",
"libutils",
"libwilhelm",
],
compile_multilib: "both",
...
}
3. app_main.cpp的main()
// init启动zygote传递的参数个数argc=6,
// argv=[/system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote]
int main(int argc, char* const argv[])
{
//构造函数,初始化AppRuntime对象
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
//忽略第一参数,zygote bin路径
argc--;
argv++;
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i; // Skip unused "parent dir" argument.
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
//zygote.rc中参数部分有“--start-system-server”, 所以该参数为true
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
Vector<String8> args;
if (!className.isEmpty()) {
//不在zygote mode里,需要传递给runtimeInit的唯一参数是application参数。
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
} else {
// We're in zygote mode.
maybeCreateDalvikCache();
if (startSystemServer) {
args.add(String8("start-system-server"));
}
char prop[PROP_VALUE_MAX];
if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
//const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist64"
LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",ABI_LIST_PROPERTY);
return 11;
}
String8 abiFlag("--abi-list=");
abiFlag.append(prop);
args.add(abiFlag);
/在zygote模式下,把剩下的argus都传递给zygote的main()
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
if (!niceName.isEmpty()) {
runtime.setArgv0(niceName.string(), true /* setProcName */);
}
if (zygote) {
//启动zygote,把构造的参数传递给ZygoteInit的main()
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
4. AndroidRuntime.start()
通过上述main()方法知道,调用AndroidRuntime.start()的参数中className="com.android.internal.os.ZygoteInit",options为["start-system-server", "--abi-list=", "abi-lists属性值", "--socket-name=zygote"]
start的主要工作:
- startVm()启动Dalvik Virtual Machine;
- 并为VM注册Android native方法;
- 查找ZygoteInit.main(),并调用该方法。此后Zygote进程进入Java层。
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
static const String8 startSystemServer("start-system-server");
//只有primary_zygote才会fork systemserver进程
bool primary_zygote = false;
for (size_t i = 0; i < options.size(); ++i) {
if (options[i] == startSystemServer) {
//option中有字符串和starSystemServer相同
primary_zygote = true;
/* track our progress through the boot sequence */
const int LOG_BOOT_PROGRESS_START = 3000;
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
}
}
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
rootDir = "/system";
if (!hasDir("/system")) {
LOG_FATAL("No root directory specified, and /system does not exist.");
return;
}
//设置android_root为/system路径
setenv("ANDROID_ROOT", rootDir, 1);
}
//校验是否有ART root/I18N_ROOT/TZDATA_ROOT目录
const char* artRootDir = getenv("ANDROID_ART_ROOT");
if (artRootDir == NULL) {
LOG_FATAL("No ART directory specified with ANDROID_ART_ROOT environment variable.");
return;
}
const char* i18nRootDir = getenv("ANDROID_I18N_ROOT");
if (i18nRootDir == NULL) {
LOG_FATAL("No runtime directory specified with ANDROID_I18N_ROOT environment variable.");
return;
}
const char* tzdataRootDir = getenv("ANDROID_TZDATA_ROOT");
if (tzdataRootDir == NULL) {
LOG_FATAL("No tz data directory specified with ANDROID_TZDATA_ROOT environment variable.");
return;
}
/* start the virtual machine,启动虚拟机 */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);
//注册Android函数
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
} else {
//查找ZygoteInit.main()方法
jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
} else {
//调用ZygoteInit.main()
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
}
free(slashClassName);
}
5. AndroidRuntime.startReg()
该方法是注册native方法的,各种JNI方法统一由register_jni_procs()完成动态注册。
int AndroidRuntime::startReg(JNIEnv* env)
{
ALOGV("--- registering native functions ---\n");
env->PushLocalFrame(200); //创建一个200容量的本地引用作用域
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
env->PopLocalFrame(NULL); //释放所有的本地引用
return 0;
}
6. AndroidRuntime.register_jni_procs()
调用该方法的第一个参数gRegJNI为
#define REG_JNI(name) { name }
struct RegJNIRec {
int (*mProc)(JNIEnv*); //函数指针
};
//zygote启动期间调用的注册JNI的方法
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
REG_JNI(register_android_os_SystemClock),
REG_JNI(register_android_util_CharsetUtils),
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
REG_JNI(register_android_util_MemoryIntArray),
REG_JNI(register_android_app_admin_SecurityLog),
REG_JNI(register_android_content_AssetManager),
REG_JNI(register_android_content_StringBlock),
REG_JNI(register_android_content_XmlBlock),
REG_JNI(register_android_content_res_ApkAssets),
REG_JNI(register_android_text_AndroidCharacter),
REG_JNI(register_android_text_Hyphenator),
REG_JNI(register_android_view_InputDevice),
REG_JNI(register_android_view_KeyCharacterMap),
REG_JNI(register_android_os_Process),
REG_JNI(register_android_os_SystemProperties),
REG_JNI(register_android_os_Binder),
REG_JNI(register_android_os_Parcel),
REG_JNI(register_android_os_PerformanceHintManager),
REG_JNI(register_android_os_HidlMemory),
REG_JNI(register_android_os_HidlSupport),
REG_JNI(register_android_os_HwBinder),
REG_JNI(register_android_os_HwBlob),
REG_JNI(register_android_os_HwParcel),
REG_JNI(register_android_os_HwRemoteBinder),
REG_JNI(register_android_os_NativeHandle),
REG_JNI(register_android_os_ServiceManager),
REG_JNI(register_android_os_storage_StorageManager),
REG_JNI(register_android_os_VintfObject),
REG_JNI(register_android_os_VintfRuntimeInfo),
REG_JNI(register_android_service_DataLoaderService),
REG_JNI(register_android_view_DisplayEventReceiver),
REG_JNI(register_android_view_InputApplicationHandle),
REG_JNI(register_android_view_InputWindowHandle),
REG_JNI(register_android_view_Surface),
REG_JNI(register_android_view_SurfaceControl),
REG_JNI(register_android_view_SurfaceControlFpsListener),
REG_JNI(register_android_view_SurfaceControlHdrLayerInfoListener),
REG_JNI(register_android_view_SurfaceSession),
REG_JNI(register_android_view_CompositionSamplingListener),
REG_JNI(register_android_view_TextureView),
REG_JNI(register_android_view_TunnelModeEnabledListener),
REG_JNI(register_com_google_android_gles_jni_EGLImpl),
REG_JNI(register_com_google_android_gles_jni_GLImpl),
REG_JNI(register_android_opengl_jni_EGL14),
REG_JNI(register_android_opengl_jni_EGL15),
REG_JNI(register_android_opengl_jni_EGLExt),
REG_JNI(register_android_opengl_jni_GLES10),
REG_JNI(register_android_opengl_jni_GLES10Ext),
REG_JNI(register_android_opengl_jni_GLES11),
REG_JNI(register_android_opengl_jni_GLES11Ext),
REG_JNI(register_android_opengl_jni_GLES20),
REG_JNI(register_android_opengl_jni_GLES30),
REG_JNI(register_android_opengl_jni_GLES31),
REG_JNI(register_android_opengl_jni_GLES31Ext),
REG_JNI(register_android_opengl_jni_GLES32),
REG_JNI(register_android_graphics_classes),
REG_JNI(register_android_graphics_BLASTBufferQueue),
REG_JNI(register_android_graphics_GraphicBuffer),
REG_JNI(register_android_graphics_SurfaceTexture),
REG_JNI(register_android_database_CursorWindow),
REG_JNI(register_android_database_SQLiteConnection),
REG_JNI(register_android_database_SQLiteGlobal),
REG_JNI(register_android_database_SQLiteDebug),
REG_JNI(register_android_os_Debug),
REG_JNI(register_android_os_FileObserver),
REG_JNI(register_android_os_GraphicsEnvironment),
REG_JNI(register_android_os_MessageQueue),
REG_JNI(register_android_os_SELinux),
REG_JNI(register_android_os_Trace),
REG_JNI(register_android_os_UEventObserver),
REG_JNI(register_android_net_LocalSocketImpl),
REG_JNI(register_android_os_MemoryFile),
REG_JNI(register_android_os_SharedMemory),
REG_JNI(register_android_os_incremental_IncrementalManager),
REG_JNI(register_com_android_internal_content_om_OverlayConfig),
REG_JNI(register_com_android_internal_net_NetworkUtilsInternal),
REG_JNI(register_com_android_internal_os_ClassLoaderFactory),
REG_JNI(register_com_android_internal_os_Zygote),
REG_JNI(register_com_android_internal_os_ZygoteCommandBuffer),
REG_JNI(register_com_android_internal_os_ZygoteInit),
REG_JNI(register_com_android_internal_security_VerityUtils),
REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
REG_JNI(register_android_hardware_Camera),
REG_JNI(register_android_hardware_camera2_CameraMetadata),
REG_JNI(register_android_hardware_camera2_DngCreator),
REG_JNI(register_android_hardware_camera2_impl_CameraExtensionJpegProcessor),
REG_JNI(register_android_hardware_camera2_utils_SurfaceUtils),
REG_JNI(register_android_hardware_display_DisplayManagerGlobal),
REG_JNI(register_android_hardware_HardwareBuffer),
REG_JNI(register_android_hardware_SensorManager),
REG_JNI(register_android_hardware_SerialPort),
REG_JNI(register_android_hardware_UsbDevice),
REG_JNI(register_android_hardware_UsbDeviceConnection),
REG_JNI(register_android_hardware_UsbRequest),
REG_JNI(register_android_hardware_location_ActivityRecognitionHardware),
REG_JNI(register_android_media_AudioDeviceAttributes),
REG_JNI(register_android_media_AudioEffectDescriptor),
REG_JNI(register_android_media_AudioSystem),
REG_JNI(register_android_media_AudioRecord),
REG_JNI(register_android_media_AudioTrack),
REG_JNI(register_android_media_AudioAttributes),
REG_JNI(register_android_media_AudioProductStrategies),
REG_JNI(register_android_media_AudioVolumeGroups),
REG_JNI(register_android_media_AudioVolumeGroupChangeHandler),
REG_JNI(register_android_media_MediaMetrics),
REG_JNI(register_android_media_MicrophoneInfo),
REG_JNI(register_android_media_RemoteDisplay),
REG_JNI(register_android_media_ToneGenerator),
REG_JNI(register_android_media_midi),
REG_JNI(register_android_opengl_classes),
REG_JNI(register_android_server_NetworkManagementSocketTagger),
REG_JNI(register_android_ddm_DdmHandleNativeHeap),
REG_JNI(register_android_backup_BackupDataInput),
REG_JNI(register_android_backup_BackupDataOutput),
REG_JNI(register_android_backup_FileBackupHelperBase),
REG_JNI(register_android_backup_BackupHelperDispatcher),
REG_JNI(register_android_app_backup_FullBackup),
REG_JNI(register_android_app_Activity),
REG_JNI(register_android_app_ActivityThread),
REG_JNI(register_android_app_NativeActivity),
REG_JNI(register_android_util_jar_StrictJarFile),
REG_JNI(register_android_view_InputChannel),
REG_JNI(register_android_view_InputEventReceiver),
REG_JNI(register_android_view_InputEventSender),
REG_JNI(register_android_view_InputQueue),
REG_JNI(register_android_view_KeyEvent),
REG_JNI(register_android_view_MotionEvent),
REG_JNI(register_android_view_PointerIcon),
REG_JNI(register_android_view_VelocityTracker),
REG_JNI(register_android_view_VerifiedKeyEvent),
REG_JNI(register_android_view_VerifiedMotionEvent),
REG_JNI(register_android_content_res_ObbScanner),
REG_JNI(register_android_content_res_Configuration),
REG_JNI(register_android_animation_PropertyValuesHolder),
REG_JNI(register_android_security_Scrypt),
REG_JNI(register_com_android_internal_content_F2fsUtils),
REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
REG_JNI(register_com_android_internal_os_DmabufInfoReader),
REG_JNI(register_com_android_internal_os_FuseAppLoop),
REG_JNI(register_com_android_internal_os_KernelCpuBpfTracking),
REG_JNI(register_com_android_internal_os_KernelCpuTotalBpfMapReader),
REG_JNI(register_com_android_internal_os_KernelCpuUidBpfMapReader),
REG_JNI(register_com_android_internal_os_KernelSingleProcessCpuThreadReader),
REG_JNI(register_com_android_internal_os_KernelSingleUidTimeReader),
};
static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
for (size_t i = 0; i < count; i++) {
//根据RegJNIRec结构体的定义,array[i].mProc(env)实际上是函数返回值
if (array[i].mProc(env) < 0) {
return -1;
}
}
return 0;
}
注意:该方法中JNI注册方法数组array[]只要有一个方法注册失败,就会返回-1,直接导致Zygote失败,所以该方法中必须是足以影响zygote进程的。