sytemserver的启动过程

时间:2022-01-14 04:32:20

(frameworks/base/cmds/app_process/app_main.cpp)

在 Android中使用启动脚本init.rc,可以在系统的初始化过程中进行一些简单的初始化操作。这个脚本被直接安装到目标系统的根文件系统中,被 init可执行程序解析。 init.rc是在init启动后被执行的启动脚本.

android启动文件系统后调用的第一个应用程序是/init,此文件的很重要的内容是解析了init.rcinit.xxx.rc
两个配置文件,然后执行解析出来的任务。相关代码在android源代码/system/core/init/init.c文件中


Zygote启动在init.rc里面指定

#init.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

前面的关键字service告诉init进程创建一个名为"zygote"的进程,这个zygote进程要执行的程序是/system/bin/app_process,后面是要传给app_process的参数

代码中

int main(int argc, char* const argv[])
{
// These are global variables in ProcessState.cpp
mArgC = argc;
mArgV = argv;

mArgLen = 0;
for (int i=0; i<argc; i++) {
mArgLen += strlen(argv[i]) + 1;
}
mArgLen--;

AppRuntime runtime;
const char* argv0 = argv[0];

// Process command line arguments
// ignore argv[0]
argc--;
argv++;

// Everything up to '--' or first non '-' arg goes to the vm

int i = runtime.addVmArguments(argc, argv); // 参数保存到runtime中,或获取到参数数

// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
const char* parentDir = NULL;
const char* niceName = NULL;
const char* className = NULL;
while (i < argc) {
const char* arg = argv[i++];
if (!parentDir) {
parentDir = arg;
} else if (strcmp(arg, "--zygote") == 0) { // zygote
zygote = true;
niceName = "zygote";
} else if (strcmp(arg, "--start-system-server") == 0) {// systemserver
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {// application
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) { // nichname
niceName = arg + 12;
} else {
className = arg;
break;
}
}

if (niceName && *niceName) {//nicename
setArgv0(argv0, niceName);
set_process_name(niceName);
}

runtime.mParentDir = parentDir; // 为start-system-server
if (zygote) {// zygote
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer ? "start-system-server" : "");
} else if (className) {//不是nicename
// Remainder of args get passed to startup class main()
runtime.mClassName = className;
runtime.mArgC = argc - i;
runtime.mArgV = argv + i;
runtime.start("com.android.internal.os.RuntimeInit",
application ? "application" : "tool");
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
return 10;
}
}

可以看到,app_process 里面定义了三种应用程序类型:

       1.  Zygote:  com.android.internal.os.ZygoteInit

       2.  System Server, 不单独启动,而是由Zygote启动

       3.  其他指定类名的Java 程序,比如说常用的 am. /system/bin/am 其实是一个shell程序,它的真正实现是       

exec app_process $base/bin com.android.commands.am.Am "$@"

这些Java的应用都是通过 AppRuntime.startclassName)开始的,其实AppRuntimeAndroidRuntime的子类

AppRuntime()
: mParentDir(NULL)
, mClassName(NULL)
, mClass(NULL)
, mArgC(0)
, mArgV(NULL)
{
}

AndroidRuntime::AndroidRuntime() :
mExitWithoutCleanup(false)
{
SkGraphics::Init();
// this sets our preference for 16bit images during decode
// in case the src is opaque and 24bit
SkImageDecoder::SetDeviceConfig(SkBitmap::kRGB_565_Config);
// This cache is shared between browser native images, and java "purgeable"
// bitmaps. This globalpool is for images that do not either use the java
// heap, or are not backed by ashmem. See BitmapFactory.cpp for the key
// java call site.
SkImageRef_GlobalPool::SetRAMBudget(512 * 1024);
// There is also a global font cache, but its budget is specified in code
// see SkFontHost_android.cpp

// Pre-allocate enough space to hold a fair number of options.
mOptions.setCapacity(20);// 容器为20

assert(gCurRuntime == NULL); // one per process
gCurRuntime = this;
}

AppRuntimeAndroidRuntime主要初始化了SKGraphics,设置了SkImageDecoderRGB_565,SkImageRef_GlobalPool512KB,两个类都是只做了关于sk图库的一些初始操作

main函数中接着把init.rczygote参数都保存到runtime中,接着开始循环判断条件,如果有nicename则设置当前process name,接着把runtimeparentdir设置为main带来的最后一个参数,假如是zygote则开启zygotecom.android.internal.os.ZygoteInit),并检查是否开启system-server,如果不是则是通过com.android.internal.os.RuntimeInit启动app

 

我们看看start是怎样的

void AndroidRuntime::start(const char* className, const char* options)
{
ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
className != NULL ? className : "(unknown)");

blockSigpipe();

/*
* 'startSystemServer == true' means runtime is obsolete and not run from
* init.rc anymore, so we print out the boot start event here.
*/
if (strcmp(options, "start-system-server") == 0) { // 有start-system-server
/* 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");//获取环境变量androidroot目录位置
if (rootDir == NULL) {//如果没有这个环境变量则设置到system
rootDir = "/system";
if (!hasDir("/system")) {
LOG_FATAL("No root directory specified, and /android does not exist.");
return;
}
setenv("ANDROID_ROOT", rootDir, 1);
}

//const char* kernelHack = getenv("LD_ASSUME_KERNEL");
//ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);

/* start the virtual machine */
JNIEnv* env;
if (startVm(&mJavaVM, &env) != 0) { // 开启java vm
return;
}
onVmCreated(env); // 调用子类的

/*
* Register android functions.
*/
if (startReg(env) < 0) {// 注册回调,并初始化android函数
ALOGE("Unable to register all android natives\n");
return;
}

/*
* We want to call main() with a String array with arguments in it.
* At present we have two arguments, the class name and an option string.
* Create an array to hold them.
*/
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
jstring optionsStr;

stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
strArray = env->NewObjectArray(2, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
optionsStr = env->NewStringUTF(options);
env->SetObjectArrayElement(strArray, 1, optionsStr);

/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
char* slashClassName = toSlashClassName(className);// 把”.”改为”/”
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
// 找到类,执行static main,并把option传递给java static main函数
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
free(slashClassName);

ALOGD("Shutting down VM\n");
if (mJavaVM->DetachCurrentThread() != JNI_OK)
ALOGW("Warning: unable to detach main thread\n");
if (mJavaVM->DestroyJavaVM() != 0)
ALOGW("Warning: VM did not shut down cleanly\n");
}

从这段代码可以看出开启了一个java虚拟机,然后再注册一些android jni(加上javaenv)函数,接着就直接打开了com.android.internal.os.ZygoteInit或者com.android.internal.os.RuntimeInit

 

我们看看com.android.internal.os.ZygoteInitmain函数

(frameworks/base/core/java/com/android/os/ZygoteInit.java)

public static void main(String argv[]) {
try {
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start(); // 启动性能统计

registerZygoteSocket(); // 创建一个LocalServerSocket
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload();// 装载相关类和资源
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());

// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot(); // 在shots目录下生成一个统计文件,统计文件的名称由两部分组成,合起来就是“进程名_开始性能统计的时刻.snapshot”。另外,writeSnapshotfile内部会调用generateSnapshotHeader函数在该统计文件文件头部写一些特定的信息,例如版本号、编译信息

// Do an initial gc to clean up after startup
gc();

// Disable tracing so that forked processes do not inherit stale tracing tags from
// Zygote.
Trace.setTracingEnabled(false);

// If requested, start system server directly from Zygote
if (argv.length != 2) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}

if (argv[1].equals("start-system-server")) {
startSystemServer(); //开启SystemServer
} else if (!argv[1].equals("")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}

Log.i(TAG, "Accepting command socket connections");

runSelectLoop();//进入while循环,由peers创建新的进程。

closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}

可以看出ZygoteInit启动了性能统计,并预先装载了类和资源,然后开启了systemserver,接着就进入了while循环

private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;

int pid;

try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}

/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}

return true;
}

可以看出通过Zygote开启了com.android.server.SystemServer

frameworks/base/services/java/com/android/server/SystemServer.java

public static void main(String[] args) {
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
// If a device's clock is before 1970 (before 0), a lot of
// APIs crash dealing with negative numbers, notably
// java.io.File#setLastModified, so instead we fake it and
// hope that time from cell towers or NTP fixes it
// shortly.
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}

if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server", null); // system_server性能统计写入
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}

// Mmmmmm... more memory!
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();

// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

Environment.setUserRequired(true);

System.loadLibrary("android_servers");// 读取android_servers库
init1(args);//调用native层的init1函数
}

可以看出是调用了native层的init1函数,init1函数调用了system_init函数

(frameworks/base/services/java/jni/com_android_server_SystemServer.cpp)

extern "C" status_t system_init()
{
ALOGI("Entered system_init()");

sp<ProcessState> proc(ProcessState::self());

sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p\n", sm.get());

sp<GrimReaper> grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0); // 当runtime dead的时候杀死进程

char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate(); // 初始化SurfaceFlinger
}

property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the sensor service
SensorService::instantiate(); // 初始化Sensor
}

// And now start the Android runtime. We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes's main(), before calling
// the init function.
ALOGI("System server: starting Android runtime.\n");
AndroidRuntime* runtime = AndroidRuntime::getRuntime();

ALOGI("System server: starting Android services.\n");
JNIEnv* env = runtime->getJNIEnv();
if (env == NULL) {
return UNKNOWN_ERROR;
}
jclass clazz = env->FindClass("com/android/server/SystemServer");
if (clazz == NULL) {
return UNKNOWN_ERROR;
}
jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
if (methodId == NULL) {
return UNKNOWN_ERROR;
}
env->CallStaticVoidMethod(clazz, methodId); // 回调java层的init2

ALOGI("System server: entering thread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
ALOGI("System server: exiting thread pool.\n");

return NO_ERROR;
}

从代码可以看出主要是做了surfaceflingersensor的初始操作,然后调用了java层的init2

 public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}

init2则是开启了ServerThreadServerThread则主要开启一些服务


sytemserver的启动过程



import init.usb.rc

on early-init
# Set init and its forked children's oom_adj.
write /proc/1/oom_adj -16

start ueventd

# create mountpoints
mkdir /mnt 0775 root system
mkdir /mnt/sdcard 0000 system system

on init

sysclktz 0

loglevel 3

# setup the global environment
export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin
export LD_LIBRARY_PATH /vendor/lib:/system/lib
export ANDROID_BOOTLOGO 1
export ANDROID_ROOT /system
export ANDROID_ASSETS /system/app
export ANDROID_DATA /data
export EXTERNAL_STORAGE /mnt/sdcard
export ASEC_MOUNTPOINT /mnt/asec
export LOOP_MOUNTPOINT /mnt/obb
export BOOTCLASSPATH /system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/framework2.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/system/framework/HTCDev.jar:/system/framework/HTCExtension.jar:/system/framework/com.htc.framework.jar:/system/framework/filterfw.jar:/system/framework/com.htc.android.bluetooth.jar:/system/framework/wimax.jar:/system/framework/com.orange.authentication.simcard.jar

# Backward compatibility
symlink /system/etc /etc
symlink /sys/kernel/debug /d
symlink /mnt/sdcard /sdcard

# Right now vendor lives on the same filesystem as system,
# but someday that may change.
symlink /system/vendor /vendor

# Create cgroup mount point for cpu accounting
mkdir /acct
mount cgroup none /acct cpuacct
mkdir /acct/uid

mkdir /system
mkdir /data 0771 system system
mkdir /cache 0770 system cache
mkdir /config 0500 root root

# Directory for putting things only root should see.
mkdir /mnt/secure 0700 root root

# Directory for staging bindmounts
mkdir /mnt/secure/staging 0700 root root

# Directory-target for where the secure container
# imagefile directory will be bind-mounted
mkdir /mnt/secure/asec 0700 root root

# Secure container public mount points.
mkdir /mnt/asec 0700 root system
mount tmpfs tmpfs /mnt/asec mode=0755,gid=1000

# Filesystem image public mount points.
mkdir /mnt/obb 0700 root system
mount tmpfs tmpfs /mnt/obb mode=0755,gid=1000

mkdir /app-cache 0700 root system
mount tmpfs tmpfs /app-cache size=8m,mode=0755,gid=1000

write /proc/sys/kernel/panic_on_oops 1
write /proc/sys/kernel/hung_task_timeout_secs 0
write /proc/cpu/alignment 4
write /proc/sys/kernel/sched_latency_ns 10000000
write /proc/sys/kernel/sched_wakeup_granularity_ns 2000000
write /proc/sys/kernel/sched_compat_yield 1
write /proc/sys/kernel/sched_child_runs_first 0
write /proc/sys/kernel/randomize_va_space 2

# Create cgroup mount points for process groups
mkdir /dev/cpuctl
mount cgroup none /dev/cpuctl cpu
chown system system /dev/cpuctl
chown system system /dev/cpuctl/tasks
chmod 0777 /dev/cpuctl/tasks
write /dev/cpuctl/cpu.shares 1024

mkdir /dev/cpuctl/fg_boost
chown system system /dev/cpuctl/fg_boost/tasks
chmod 0777 /dev/cpuctl/fg_boost/tasks
write /dev/cpuctl/fg_boost/cpu.shares 1024

mkdir /dev/cpuctl/bg_non_interactive
chown system system /dev/cpuctl/bg_non_interactive/tasks
chmod 0777 /dev/cpuctl/bg_non_interactive/tasks
# 5.0 %
write /dev/cpuctl/bg_non_interactive/cpu.shares 52

# Allow everybody to read the xt_qtaguid resource tracking misc dev.
# This is needed by any process that uses socket tagging.
chmod 0644 /dev/xt_qtaguid

on fs
# mount mtd partitions
# Mount /system rw first to give the filesystem a chance to save a checkpoint
mount yaffs2 mtd@system /system
mount yaffs2 mtd@system /system ro remount
mount yaffs2 mtd@userdata /data nosuid nodev
mount yaffs2 mtd@cache /cache nosuid nodev

on post-fs
# once everything is setup, no need to modify /
mount rootfs rootfs / ro remount

# We chown/chmod /cache again so because mount is run as root + defaults
chown system cache /cache
chmod 0770 /cache

# This may have been created by the recovery system with odd permissions
chown system cache /cache/recovery
chmod 0770 /cache/recovery

#change permissions on vmallocinfo so we can grab it from bugreports
chown root log /proc/vmallocinfo
chmod 0440 /proc/vmallocinfo

#change permissions on kmsg & sysrq-trigger so bugreports can grab kthread stacks
chown root system /proc/kmsg
chmod 0440 /proc/kmsg
chown root system /proc/sysrq-trigger
chmod 0220 /proc/sysrq-trigger

# create the lost+found directories, so as to enforce our permissions
mkdir /cache/lost+found 0770 root root

on post-fs-data
# We chown/chmod /data again so because mount is run as root + defaults
chown system system /data
chmod 0771 /data

# create htcfs
mkdir /data/htcfs 0750 media media

# Create dump dir and collect dumps.
# Do this before we mount cache so eventually we can use cache for
# storing dumps on platforms which do not have a dedicated dump partition.
mkdir /data/dontpanic 0750 root log

# Collect apanic data, free resources and re-arm trigger
copy /proc/apanic_console /data/dontpanic/apanic_console
chown root log /data/dontpanic/apanic_console
chmod 0640 /data/dontpanic/apanic_console

copy /proc/apanic_threads /data/dontpanic/apanic_threads
chown root log /data/dontpanic/apanic_threads
chmod 0640 /data/dontpanic/apanic_threads

write /proc/apanic_console 1

# create basic filesystem structure
mkdir /data/misc 01771 system misc
mkdir /data/misc/bluetoothd 0770 bluetooth bluetooth
mkdir /data/misc/bluetooth 0770 system system
mkdir /data/misc/keystore 0700 keystore keystore
mkdir /data/misc/keychain 0771 system system
mkdir /data/misc/vpn 0770 system vpn
mkdir /data/misc/systemkeys 0700 system system
# give system access to wpa_supplicant.conf for backup and restore
mkdir /data/misc/wifi 0770 wifi wifi
chmod 0660 /data/misc/wifi/wpa_supplicant.conf
mkdir /data/local 0751 root root
mkdir /data/local/tmp 0771 shell shell
mkdir /data/data 0771 system system
mkdir /data/app-private 0771 system system
mkdir /data/app 0771 system system
mkdir /data/property 0700 root root
mkdir /data/radio 0770 radio radio
mkdir /dev/radio 0770 radio radio

# create dalvik-cache, so as to enforce our permissions
mkdir /data/dalvik-cache 0771 system system

# create resource-cache and double-check the perms
mkdir /data/resource-cache 0771 system system
chown system system /data/resource-cache
chmod 0771 /data/resource-cache

# create the lost+found directories, so as to enforce our permissions
mkdir /data/lost+found 0770 root root

# create directory for DRM plug-ins - give drm the read/write access to
# the following directory.
mkdir /data/drm 0770 drm drm

chown system system /sys/class/android_usb/android0/f_mass_storage/lun/file
chmod 0660 /sys/class/android_usb/android0/f_mass_storage/lun/file
chown system system /sys/class/android_usb/android0/f_rndis/ethaddr
chmod 0660 /sys/class/android_usb/android0/f_rndis/ethaddr

# HTC add: Smartcard Service on ICS
chmod 0660 /dev/assd
chown smartcard smartcard /dev/assd

# HTC add: 3LM setting on ICS
setprop ro.3lm.production 1

# HTC add: 3LM encryption on ICS
setprop ro.3lm.legacy_encryption 1
mkdir /data/secure 0755 system system
mkdir /data/secure/data 0755 system system
mount tmpfs tmpfs /data/secure/data mode=0755,gid=1000

# HTC add: for customization wizard folder
mkdir /data/data/cw 0770 root cw_access
mkdir /data/data/cwtemp 0770 root cw_access

chmod 0770 /data/data/cw
chmod 0770 /data/data/cwtemp

# HTC add: double check the perms of /data/data for already existed case
chown system system /data/data
chmod 0771 /data/data
chmod 0660 /data/data/com.android.providers.settings/databases/settings.db-wal
chmod 0660 /data/data/com.android.providers.settings/databases/settings.db-shm
chmod 0660 /data/data/com.android.providers.settings/databases/settings.db-journal

# HTC add: double check the perms of /data/data/recovery for already existed case
chown root recvy_access /data/data/recovery
chmod 0775 /data/data/recovery

chown system system /sys/class/graphics/fb0/ratelimit

# If there is no fs-post-data action in the init.<device>.rc file, you
# must uncomment this line, otherwise encrypted filesystems
# won't work.
# Set indication (checked by vold) that we have finished this action
setprop vold.post_fs_data_done 1

on boot
# basic network init
ifup lo
hostname localhost
domainname localdomain

# set RLIMIT_NICE to allow priorities from 19 to -20
setrlimit 13 40 40
setrlimit 8 268435456 268435456

# Memory management. Basic kernel parameters, and allow the high
# level system server to be able to adjust the kernel OOM driver
# paramters to match how it is managing things.
write /proc/sys/vm/overcommit_memory 1
write /proc/sys/vm/min_free_order_shift 4
write /proc/sys/vm/highmem_is_dirtyable 1
write /proc/sys/vm/min_free_kbytes 4096
chown root system /sys/module/lowmemorykiller/parameters/adj
chmod 0664 /sys/module/lowmemorykiller/parameters/adj
chown root system /sys/module/lowmemorykiller/parameters/minfree
chmod 0664 /sys/module/lowmemorykiller/parameters/minfree

# Tweak background writeout
write /proc/sys/vm/dirty_expire_centisecs 200
write /proc/sys/vm/dirty_background_bytes 1024000
write /proc/sys/vm/dirty_bytes 10240000

# Permissions for System Server and daemons.
chown radio system /sys/android_power/state
chown radio system /sys/android_power/request_state
chown radio system /sys/android_power/acquire_full_wake_lock
chown radio system /sys/android_power/acquire_partial_wake_lock
chown radio system /sys/android_power/release_wake_lock
chown radio system /sys/power/state
chown radio system /sys/power/wake_lock
chown radio system /sys/power/wake_unlock
chmod 0444 /sys/android_camera/fps_mode
chmod 0660 /sys/android_camera2/htcwc
chown media system /sys/android_camera2/htcwc
chown media system /sys/android_camera/cam3Dmode
chown radio system /sys/camera_led_status/led_ril_status
chown system system /sys/camera_led_status/led_wimax_status
chown system system /sys/camera_led_status/led_hotspot_status
chown media system /sys/android_camera/cam_mode
chmod 0660 /sys/power/state
chmod 0660 /sys/power/wake_lock
chmod 0660 /sys/power/wake_unlock
chown system system /sys/class/timed_output/vibrator/enable
chown system system /sys/class/leds/keyboard-backlight/brightness
chown system system /sys/class/leds/lcd-backlight/brightness
chown system system /sys/class/leds/button-backlight/brightness
chown system system /sys/class/leds/jogball-backlight/brightness
chown system system /sys/class/leds/red/brightness
chown system system /sys/class/leds/green/brightness
chown system system /sys/class/leds/blue/brightness
chown system system /sys/class/leds/red/device/grpfreq
chown system system /sys/class/leds/red/device/grppwm
chown system system /sys/class/leds/red/device/blink
chown system system /sys/class/leds/red/brightness
chown system system /sys/class/leds/green/brightness
chown system system /sys/class/leds/blue/brightness
chown system system /sys/class/leds/red/device/grpfreq
chown system system /sys/class/leds/red/device/grppwm
chown system system /sys/class/leds/red/device/blink
chown system system /sys/class/timed_output/vibrator/enable
chown system system /sys/module/sco/parameters/disable_esco
chown system system /sys/kernel/ipv4/tcp_wmem_min
chown system system /sys/kernel/ipv4/tcp_wmem_def
chown system system /sys/kernel/ipv4/tcp_wmem_max
chown system system /sys/kernel/ipv4/tcp_rmem_min
chown system system /sys/kernel/ipv4/tcp_rmem_def
chown system system /sys/kernel/ipv4/tcp_rmem_max
chown root radio /proc/cmdline
# HTC SSD Peripheral UI - BEGIN
chown system system /sys/class/leds/red/brightness
chown system system /sys/class/leds/red/blink
chown system system /sys/class/leds/red/off_timer
chown system system /sys/class/leds/green/brightness
chown system system /sys/class/leds/green/blink
chown system system /sys/class/leds/green/off_timer
chown system system /sys/class/leds/blue/brightness
chown system system /sys/class/leds/blue/blink
chown system system /sys/class/leds/blue/off_timer
chown system system /sys/class/leds/amber/brightness
chown system system /sys/class/leds/amber/blink
chown system system /sys/class/leds/amber/off_timer
chown system system /sys/class/leds/button-backlight-portrait/brightness
chown system system /sys/class/leds/button-backlight-landscape/brightness
chown system system /sys/class/leds/amber-portrait/brightness
chown system system /sys/class/leds/green-portrait/brightness
chown system system /sys/class/leds/blue-portrait/brightness
chown system system /sys/class/leds/amber-landscape/brightness
chown system system /sys/class/leds/green-landscape/brightness
chown system system /sys/class/leds/blue-landscape/brightness
chown system system /sys/class/leds/sharekey/brightness
chown system system /sys/class/leds/sharekey/breath_times
chown system system /sys/class/leds/sharekey/breath_max_brightness
chown system system /sys/class/leds/charming-led/brightness
chown system system /sys/class/leds/charming-led/blink
chown system system /sys/class/leds/charming-led/off_timer
chown system system /sys/class/leds/flashlight/brightness
chown system system /sys/class/leds/caps/brightness
chown system system /sys/class/leds/func/brightness
chown media media /sys/class/leds/green-camera/brightness
chown system system /sys/devices/virtual/htc_accessory/fm/flag
chown system system /sys/devices/virtual/htc_accessory/tty/flag
chown system system /sys/class/switch/dock/dmb_wakeup
# HTC SSD Peripheral UI - END

# HTC SSD Peripheral Touch - START
chown system system /sys/android_touch/unlock
# HTC SSD Peripheral UI -END

# HTC SSD USB
chown system system /sys/class/android_usb/f_modem/on
chown system system /sys/class/android_usb/f_diag/on
chown system system /sys/class/android_usb/f_rmnet/on

#set diag permissions
chown radio radio /dev/diag
chown radio radio /dev/diag_mdm
chown radio radio /dev/htcdiag
chown radio radio /dev/diag_arm9
chown radio radio /dev/btdiag
chmod 0660 /dev/diag
chmod 0660 /dev/diag_mdm
chmod 0660 /dev/htcdiag
chmod 0660 /dev/diag_arm9
chmod 0660 /dev/btdiag

# Define TCP buffer sizes for various networks
# ReadMin, ReadInitial, ReadMax, WriteMin, WriteInitial, WriteMax,
setprop net.tcp.buffersize.default 4096,87380,110208,4096,16384,110208
setprop net.tcp.buffersize.wifi 524288,1048576,2097152,262144,524288,1048576
# setprop net.tcp.buffersize.hsdpa 4094,87380,393216,4096,16384,110208
# setprop net.tcp.buffersize.umts 4094,87380,393216,4096,16384,110208
# setprop net.tcp.buffersize.edge 4093,26280,393216,4096,16384,35040
# setprop net.tcp.buffersize.gprs 4092,8760,393216,4096,8760,11680
# setprop net.tcp.buffersize.lte 4096,221184,3461120,4096,221184,3461120
# setprop net.tcp.buffersize.evdo_b 4094,87380,262144,4096,16384,262144
# setprop net.tcp.buffersize.wimax 4096,221184,524288,4096,16384,110208
setprop net.tcp.buffersize.hsdpa 4094,87380,704512,4096,16384,110208
setprop net.tcp.buffersize.umts 4094,87380,704512,4096,16384,110208
setprop net.tcp.buffersize.edge 4093,26280,704512,4096,16384,35040
setprop net.tcp.buffersize.gprs 4092,8760,704512,4096,8760,11680
setprop net.tcp.buffersize.lte 4096,221184,3461120,4096,221184,3461120
setprop net.tcp.buffersize.evdo_b 4094,87380,262144,4096,16384,262144
setprop net.tcp.buffersize.wimax 4096,221184,524288,4096,16384,110208

# Assign TCP buffer thresholds to be ceiling value of technology maximums
# Increased technology maximums should be reflected here.
write /proc/sys/net/core/rmem_max 262144
write /proc/sys/net/core/wmem_max 262144

# Set this property so surfaceflinger is not started by system_init
setprop system_init.startsurfaceflinger 0

# Set error receiver
setprop ro.error.receiver.htc.apps com.htc.feedback

class_start core
class_start main

on nonencrypted
class_start late_start

on charger
class_start charger

on property:vold.decrypt=trigger_reset_main
class_reset main

on property:vold.decrypt=trigger_load_persist_props
load_persist_props

on property:vold.decrypt=trigger_post_fs_data
trigger post-fs-data

on property:vold.decrypt=trigger_restart_min_framework
class_start main

on property:vold.decrypt=trigger_restart_framework
class_start main
class_start late_start

on property:vold.decrypt=trigger_shutdown_framework
class_reset late_start
class_reset main

## Daemon processes to be run by init.
##
service ueventd /sbin/ueventd
class core
critical

service console /system/bin/sh
class core
console
disabled
user shell
group log

on property:ro.debuggable=1
start console

# adbd is controlled via property triggers in init.<platform>.usb.rc
service adbd /sbin/adbd
class core
disabled

# adbd on at boot in emulator
on property:ro.kernel.qemu=1
start adbd

# This property trigger has added to imitiate the previous behavior of "adb root".
# The adb gadget driver used to reset the USB bus when the adbd daemon exited,
# and the host side adb relied on this behavior to force it to reconnect with the
# new adbd instance after init relaunches it. So now we force the USB bus to reset
# here when adbd sets the service.adb.root property to 1. We also restart adbd here
# rather than waiting for init to notice its death and restarting it so the timing
# of USB resetting and adb restarting more closely matches the previous behavior.
on property:service.adb.root=1
write /sys/class/android_usb/android0/enable 0
restart adbd
write /sys/class/android_usb/android0/enable 1

service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm

service vold /system/bin/vold
class core
socket vold stream 0660 root mount
ioprio be 2

service netd /system/bin/netd
class main
socket netd stream 0660 root system
socket dnsproxyd stream 0660 root inet

service debuggerd /system/bin/debuggerd
class main

service ril-daemon /system/bin/rild
class core
socket rild stream 660 root radio
socket rild-debug stream 660 radio system
socket rild-htc stream 660 radio system
socket aepls001 stream 660 radio system
user root
group radio cache inet misc audio sdcard_rw log

service surfaceflinger /system/bin/surfaceflinger
class main
user system
group graphics
onrestart restart zygote

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd

service drm /system/bin/drmserver
class main
user drm
group system inet drmrpc

service media /system/bin/mediaserver
class main
user media
group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc cw_access oma_drm_group
ioprio rt 4

service fusermount /system/bin/fusermount -u /data/htcfs
disabled
oneshot

service htcfs /system/bin/htcfs /data/htcfs -f -o allow_other
onrestart restart fusermount

service bootanim /system/bin/bootanimation
class main
user graphics
group system audio graphics cw_access
disabled
oneshot

service dbus /system/bin/dbus-daemon --system --nofork
class main
socket dbus stream 660 bluetooth bluetooth
user bluetooth
group bluetooth net_bt_admin

service bluetoothd /system/bin/bluetoothd -n
class main
socket bluetooth stream 660 bluetooth bluetooth
socket dbus_bluetooth stream 660 bluetooth bluetooth
# init.rc does not yet support applying capabilities, so run as root and
# let bluetoothd drop uid to bluetooth with the right linux capabilities
group bluetooth net_bt_admin misc
disabled
oneshot

service installd /system/bin/installd
class main
socket installd stream 600 system system

service flash_recovery /system/etc/install-recovery.sh
class main
oneshot

service racoon /system/bin/racoon
class main
socket racoon stream 600 system system
# IKE uses UDP port 500. Racoon will setuid to vpn after binding the port.
group vpn net_admin inet
disabled
oneshot

service mtpd /system/bin/mtpd
class main
socket mtpd stream 600 system system
user vpn
group vpn net_admin inet net_raw
disabled
oneshot

service keystore /system/bin/keystore /data/misc/keystore
class main
user keystore
group keystore
socket keystore stream 666

service dumpstate /system/bin/dumpstate -s
class main
socket dumpstate stream 0660 shell log
disabled
oneshot

service ipd /system/bin/ipd
socket ipd stream 660 root radio

on property:dev.bootcomplete=1
start bootcomplete

service bootcomplete /system/bin/bootcomplete
user root
group root
disabled
oneshot

service shutdown /system/bin/shutdown
user root
group root
disabled
oneshot

service charging /system/bin/charging
user root
group root
disabled
oneshot

# HTC add: 3LM service default launched on ICS
service tund /system/bin/tund
socket tund stream 0660 vpn system
user vpn
group vpn net_admin net_raw
ioprio be 2

service post-boot /system/bin/sh /system/etc/init.post_boot.sh
user root
oneshot