OS puts emphases on how to provide interfaces to user's APPs

for using hardware device

in the convenient and efficient way.

Everything has its own logic of running and must be done step by step,no shortcut. 

Take a look at Android OS Framework

Now, how to make the above OS run and every component of OS work to provide the service for user APP. Take a look at the process of startup as following picture

Step1: Startup from power on, Linux start up

  • System boot:bootloader  @bootable/bootloader/*
    • Comera+Power--->fastboot,
    • Home+Power--->load recovery.img
    • Power--->load boot.img
  • bootloader loads linux kernel
  • linux kernel initialize: @kernel/*

Step2: Android startup

  • kernel loads init-process: @ system/core/init/*
  • read config file: @system/rootdir/init.rc to start android service and start other commands and service(adbd for adb service, vold for SD mount)
  • Start native service, and other services such as ServiceManager,Zygote,media service.
  • Init read init process to start ril-daemon, media, bootsound, bootanim, servicemanager......
 init:@System/Core/Init
Init.c: parse_config_file(Init.rc) @parse_config_file(Init.marvel.rc)
解析脚本文件:Init.rc和Init.xxxx.rc(硬件平台相关)
Init.rc是Android自己规定的初始化脚本(Android Init Language, System/Core/Init/readme.txt)
该脚本包含四个类型的声明: Actions, Commands, Services, Options.
1.2 服务启动机制,我们来看看Init是这样解析.rc文件开启服务的。
()打开.rc文件,解析文件内容 @system/core/init/init.c
将service信息放置到service_list中。@system/core/init/parser.c
()restart_service() @system/core/init/init.c
service_start
execve(…).建立service进程。 export PATH /sbin:/system/sbin:/system/bin
export LD_LIBRARY_PATH /system/lib
mkdir /dev
mkdir /proc
mkdir /sys
mount tmpfs tmpfs /dev
mkdir /dev/pts
mkdir /dev/socket
mount devpts devpts /dev/pts
mount proc proc /proc
mount sysfs sysfs /sys
write /proc/cpu/alignment
ifup lo
hostname localhost
domainname localhost
mount yaffs2 mtd@system /system
mount yaffs2 mtd@userdata /data
import /system/etc/init.conf
class_start default
service adbd /sbin/adbd
user adb
group adb
service usbd /system/bin/usbd -r
user usbd
group usbd
socket usbd
service zygote /system/bin/app_process -Xzygote /system/bin --zygote
socket zygote
service runtime /system/bin/runtime
user system
group system
on device-added-/dev/compass
start akmd
on device-removed-/dev/compass
stop akmd
service akmd /sbin/akmd
disabled
user akmd
group akmd
Zygote // @system\core\rootdir\init.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media

Step3: Zygote Startup

  • In init.rc: service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
 /**
* Main entry of app process.
*
* Starts the interpreted runtime, then starts up the application.
*
*/ #define LOG_TAG "appproc" #include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <utils/Log.h>
#include <cutils/process_name.h>
#include <cutils/memory.h>
#include <android_runtime/AndroidRuntime.h> #include <stdio.h>
#include <unistd.h> namespace android { void app_usage()
{
fprintf(stderr,
"Usage: app_process [java-options] cmd-dir start-class-name [options]\n");
} class AppRuntime : public AndroidRuntime
{
public:
AppRuntime()
: mParentDir(NULL)
, mClassName(NULL)
, mClass(NULL)
, mArgC(0)
, mArgV(NULL)
{
} #if 0
// this appears to be unused
const char* getParentDir() const
{
return mParentDir;
}
#endif const char* getClassName() const
{
return mClassName;
} virtual void onVmCreated(JNIEnv* env)
{
if (mClassName == NULL) {
return; // Zygote. Nothing to do here.
} /**
* This is a little awkward because the JNI FindClass call uses the
* class loader associated with the native method we're executing in.
* If called in onStarted (from RuntimeInit.finishInit because we're
* launching "am", for example), FindClass would see that we're calling
* from a boot class' native method, and so wouldn't look for the class
* we're trying to look up in CLASSPATH. Unfortunately it needs to,
* because the "am" classes are not boot classes.
*
* The easiest fix is to call FindClass here, early on before we start
* executing boot class Java code and thereby deny ourselves access to
* non-boot classes.
*/
char* slashClassName = toSlashClassName(mClassName);
mClass = env->FindClass(slashClassName);
if (mClass == NULL) {
LOGE("ERROR: could not find class '%s'\n", mClassName);
}
free(slashClassName); mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
} virtual void onStarted()
{
sp<ProcessState> proc = ProcessState::self();
LOGV("App process: starting thread pool.\n");
proc->startThreadPool(); AndroidRuntime* ar = AndroidRuntime::getRuntime();
ar->callMain(mClassName, mClass, mArgC, mArgV); IPCThreadState::self()->stopProcess();
} virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
LOGV("App process: starting thread pool.\n");
proc->startThreadPool();
} virtual void onExit(int code)
{
if (mClassName == NULL) {
// if zygote
IPCThreadState::self()->stopProcess();
} AndroidRuntime::onExit(code);
} const char* mParentDir;
const char* mClassName;
jclass mClass;
int mArgC;
const char* const* mArgV;
}; } using namespace android; /**
* sets argv0 to as much of newArgv0 as will fit
*/
static void setArgv0(const char *argv0, const char *newArgv0)
{
strlcpy(const_cast<char *>(argv0), newArgv0, strlen(argv0));
} int main(int argc, const 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); // 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 = true;
niceName = "zygote";
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName = arg + 12;
} else {
className = arg;
break;
}
} if (niceName && *niceName) {
setArgv0(argv0, niceName);
set_process_name(niceName);
} runtime.mParentDir = parentDir; if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer ? "start-system-server" : "");
} else if (className) {
// 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_main

 // @system\core\rootdir\init.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
  • Zygote start up from main(…) of app_process   //@frameworks/base/cmds/app_main.cpp。
  • Create Java Runtime:  runtime.start("com.android.internal.os.ZygoteInit.java", startSystemServer); //@AndroidRuntime.cpp
  • Make Zygote run:com.android.internal.os.ZygoteInit:main()  //@com.android.internal.os.ZygoteInit
  • registerZygoteSocket();
  • startSystemServer();com.android.internal.os.ZygoteInit:startSystemServer() //@com.android.internal.os.ZygoteInit.
  • Now the Zygote service framework is built, and accept the requet from ActivityManagerService via Socket to fork APP.
  • Zygote.forkSystemServer(@dalvik.system.Zygote.java) is mapped to the process of linux with pid.
 public static void main(String argv[])
{
try {
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
registerZygoteSocket();
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();
// Do an initial gc to clean up after startup
gc();
// 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();
} else if (!argv[1].equals("")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
Log.i(TAG, "Accepting command socket connections");
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
runSelectLoopMode();
}
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
 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;
}
 //@dalvik.system.Zygote.java
public static int forkSystemServer(int uid, int gid, int[] gids,int debugFlags, int[][] rlimits,long permittedCapabilities, long effectiveCapabilities)
{
preFork();
//call native method to fork a process of system server which is mappged to linux process
int pid = nativeForkSystemServer(uid, gid, gids, debugFlags, rlimits,
permittedCapabilities,
effectiveCapabilities);
postFork();
return pid;
}

Step3:SystemServer Startup

  • Zygote fork a process of SystemServer: forkSystemServer() //@dalvik.system.Zygote.java
  • Zygote.nativeForkSystemServer() //@dalvik/vm/native/dalvik_system_Zygote.c
  • SystemServer is created and running.
  • com.android.server.SystemServer:init1(): The native method start all system native service.
  • com.android.server.SystemServer:init2(): Create a ServerThread to add just created native service by init1() to service list and finally loop.

com.android.server.SystemServer:main()//@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);
}
}, 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);
System.loadLibrary("android_servers");//load android_servers.so
init1(args);
}
/***
* This method is called from Zygote to initialize the system. This will cause the native
* services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
* up into init2() to start the Android services.
*/
native public static void init1(String[] args); public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
 //@com.android.server.SystemService
class ServerThread extends Thread
{
......
@Override
public void run()
{
...............................
Looper.prepare();
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
BinderInternal.disableBackgroundScheduling(true);
android.os.Process.setCanSelfBackground(false);
// Check whether we failed to shut down last time we tried.
{
....................
}
String factoryTestStr = SystemProperties.get("ro.factorytest");
int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
: Integer.parseInt(factoryTestStr);
.......//declare all native service object.
// Critical services...add all service into list of service manager
try {
Slog.i(TAG, "Entropy Service");
ServiceManager.addService("entropy", new EntropyService());
power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);
context = ActivityManagerService.main(factoryTest);
ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));
AttributeCache.init(context);
........................
alarm = new AlarmManagerService(context);
ServiceManager.addService(Context.ALARM_SERVICE, alarm);
Watchdog.getInstance().init(context, battery, power, alarm,ActivityManagerService.self());
Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, power,factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,!firstBoot);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ActivityManagerService.self().setWindowManager(wm);
....................... } catch (RuntimeException e) {
}
.............................
// Bring up services needed for UI.
if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL)
{
try {
Slog.i(TAG, "Input Method Service");
imm = new InputMethodManagerService(context);
ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
} catch (Throwable e) {
reportWtf("starting Input Manager Service", e);
}
.......................
} try {
wm.displayReady();
} catch (Throwable e) {
reportWtf("making display ready", e);
} try {
pm.performBootDexOpt();
} catch (Throwable e) {
reportWtf("performing boot dexopt", e);
} try {
ActivityManagerNative.getDefault().showBootMessage(context.getResources().getText(
com.android.internal.R.string.android_upgrading_starting_apps),
false);
} catch (RemoteException e) {
}
if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
try {
Slog.i(TAG, "Device Policy");
devicePolicy = new DevicePolicyManagerService(context);
ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
} catch (Throwable e) {
reportWtf("starting DevicePolicyService", e);
}
....................
try {
Slog.i(TAG, "Wi-Fi Service");
wifi = new WifiService(context);
ServiceManager.addService(Context.WIFI_SERVICE, wifi);
} catch (Throwable e) {
reportWtf("starting Wi-Fi Service", e);
}
....................
try {
Slog.i(TAG, "NetworkTimeUpdateService");
networkTimeUpdater = new NetworkTimeUpdateService(context);
} catch (Throwable e) {
reportWtf("starting NetworkTimeUpdate service", e);
}
}
// Before things start rolling, be sure we have decided whether
// we are in safe mode.
final boolean safeMode = wm.detectSafeMode();
if (safeMode) {
ActivityManagerService.self().enterSafeMode();
// Post the safe mode state in the Zygote class
Zygote.systemInSafeMode = true;
// Disable the JIT for the system_server process
VMRuntime.getRuntime().disableJitCompilation();
} else {
// Enable the JIT for the system_server process
VMRuntime.getRuntime().startJitCompilation();
}
// It is now time to start up the app processes...
if (devicePolicy != null) {
try {
devicePolicy.systemReady();
} catch (Throwable e) {
reportWtf("making Device Policy Service ready", e);
}
}
if (notification != null) {
try {
notification.systemReady();
} catch (Throwable e) {
reportWtf("making Notification Service ready", e);
}
}
try {
wm.systemReady();
} catch (Throwable e) {
reportWtf("making Window Manager Service ready", e);
}
if (safeMode) {
ActivityManagerService.self().showSafeModeOverlay();
}
// Update the configuration for this context by hand, because we're going
// to start using it before the config change done in wm.systemReady() will
// propagate to it.
..................................
power.systemReady();
try {
pm.systemReady();
} catch (Throwable e) {
reportWtf("making Package Manager Service ready", e);
} // These are needed to propagate to the runnable below.
final Context contextF = context;
final BatteryService batteryF = battery;
.........................
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
ActivityManagerService.self().systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Making services ready");
startSystemUi(contextF);
try {
if (batteryF != null) batteryF.systemReady();
} catch (Throwable e) {
reportWtf("making Battery Service ready", e);
}
.....................
try {
if (textServiceManagerServiceF != null) textServiceManagerServiceF.systemReady();
} catch (Throwable e) {
reportWtf("making Text Services Manager Service ready", e);
}
}
}); // For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
Looper.loop();
Slog.d(TAG, "System ServerThread is exiting!");
}
static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
Slog.d(TAG, "Starting service: " + intent);
context.startService(intent);
}
}

Step4:Home luncher Startup

http://blog.csdn.net/maxleng/article/details/5508372

http://wenku.baidu.com/view/fc7729375a8102d276a22f13.html

http://wenku.baidu.com/view/42ebf459be23482fb4da4c33.html

http://www.cnblogs.com/linucos/archive/2012/05/22/2513760.html

Android's Process & Thread

Android OS Startup的更多相关文章

  1. android.os.NetworkOnMainThreadException异常

    在android4.0以前,访问网络的代码可以写在UI主线程,但是在android4.0以上就不能在ui主线程中访问网络了,会出现android.os.NetworkOnMainThreadExcep ...

  2. Xamarin Android.Views.WindowManagerBadTokenException: Unable to add window -- token android.os.BinderProxy

    Android.Views.WindowManagerBadTokenException: Unable to add window -- token android.os.BinderProxy@ ...

  3. Android.os.NetworkOnMainThreadException

    出现Android.os.NetworkOnMainThreadException错误提示的原因原因:不允许在主线程中进行网络访问解决办法:将网络访问的操作单独放到一个线程中

  4. android aidl 进程间通信需要注意的地方(android.os.TransactionTooLargeException)

    转自:http://blog.sina.com.cn/s/blog_4e1e357d0102wau9.html 1.bus工程实现通过service实现aidl实体类 2.actor工程通过发起bin ...

  5. android-解决 Android N 上 报错:android.os.FileUriExposedException

    解决 Android N 上 安装Apk时报错:android.os.FileUriExposedException: file:///storage/emulated/0/Download/appN ...

  6. Android内核开发:系统启动速度优化-Android OS启动优化(转)

    Android系统的启动优化主要分为三大部分: (1) Bootloader优化 (2) Linux Kernel的剪裁与优化 (3) Android OS部分的剪裁与优化 本文重点关注Android ...

  7. android.os.BadParcelableException: ClassNotFoundException when unmarshalling:解决办法

    例如在用AlarmManager的时候 AlarmManager alarmMgr = (AlarmManager) mContext .getSystemService(Context.ALARM_ ...

  8. 主线程中一定不能放耗时操作,必须要开子线程,比如下载文件,不然会不让你拿到输入流--报错显示android.os.NetworkOnMainThreadException

    1.必须要开子线程来操作耗时操作,android.os.NetworkOnMainThreadException new Thread(new Runnable() { @Override publi ...

  9. android.os.NetworkOnMainThreadException解决

    很早就知道Android4.0以后,要把耗时的网络操作放在多线程中,处理方法有: 1) setContentView(R.layout.activity_main)下面加上如下代码 if (andro ...

随机推荐

  1. 《图解HTTP》阅读笔记-第五章-web服务器

      第五章.与HTTP协助的web服务器单台虚拟主机实现多个域名可以用单台物理主机运行多台虚拟主机,这些虚拟主机的IP相同,而虚拟主机有可以寄存多个不同主机名和域名的web网站,所以要保证发送HTTP ...

  2. P1402 酒店之王 最大流

    \(\color{#0066ff}{ 题目描述 }\) XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自己所爱的菜,但是该 ...

  3. Tarjan缩点+LCA【洛谷P2416】 泡芙

    P2416 泡芙 题目描述 火星猫经过一番努力终于到达了冥王星.他发现冥王星有 N 座城市,M 条无向边.火星猫准备出发去找冥王兔,他听说有若干泡芙掉落在一些边上,他准备采集一些去送给冥王兔.但是火星 ...

  4. linux文件系统相关概念

    struct task_struct { ......................... struct mm_struct*mm;//内存描述符的指针 struct files_struct *f ...

  5. P3167 [CQOI2014]通配符匹配 题解

    题目 题目大意 给出一个字符串,其中包含两种通配符 ‘?’和 ‘*’ ,‘?’可以代替一个字符,‘*’可以代替一个字符串(长度可以为0) 然后给出几个字符转,判断能否用给出的字符串表示出来 样例解释 ...

  6. codeforces 620D Professor GukiZ and Two Arrays

    #include <bits/stdc++.h> using namespace std; + ; const long long inf = 1e18; int n, m; long l ...

  7. FileLoadException: 未能加载文件或程序集"aliyun-net-sdk-cf, Version=1.0.0.0,

    清理缓存解决 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files C:\Windows\Microsoft. ...

  8. 报错:The valid characters are defined in RFC 7230 and RFC 3986

    访问 spring boot controller时,报错:The valid characters are defined in RFC 7230 and RFC 3986 1.特殊符号 @Spri ...

  9. disruptor 问题排查

    需求:收到银行异步通知,要在2秒内将结果返回银行,同时还要根据银行返回的交易状态更新数据库订单状态和其他业务. 采用disruptor,其实最好使用独立MQ产品.本次用的是disruptor,遇到了一 ...

  10. C++文件读写函数之——fopen、fread和fwrite、fgetc和fputc、fgets和fputs、ftellf和fseek、rewind

    由于最近经常使用到c语言中的读写文件,所以在此总结以下,方便以后查找. 在c中,文件操作都是由库函数来实现的,主要是分为读和写两种操作,以下详细讲解以下所有有关文件操作的邯郸乎的用法: //C++写入 ...