第一步:开机,给电路进行供电。硬件电路按照一个确定的时序复位电路,并且cpu是最后一个被复位的硬件。
第二步:处理器执行处理器片上rom中的一小段程序,这段程序就是Bootloader程序。这段程序会根据处理器一些特定引脚的高低电平状态,选择从哪种物理接口加载用户程序,例如sd卡,usb口,并口flash,串口等
第三步:大多数ARM硬件系统,会从并口NAND Flash芯片的0x00000000地址装载用户程序。对于Android来说,这段程序还不是Android程序,而是uboot或者fastboot程序。作用是初始化硬件设备,并提供一些调试功能。
第四步:fastboot会检测用户是否按下了某些特别的按键,以便决定是否进入调试模式。否则就会从Flash中装载Linux内核,装载地址也是在编译fastboot是预先约定好的。
接下来就进入了Linux内核的启动
init程序解析init.rc来构建出系统运行的初始环境。
init.rc主要概念有四个
Action
on
Command
命令将在所属事件发生时,一个一个的执行
Service
service
其中name:表示此service的名称
pathname:表示此service文件所在的路径
argument:启动service时所带的参数
option:对此Service的约束选项
Option
对service的约束
其中Action在满足触发条件是会被触发执行命令,而Service总是会被解析执行。
Linux系统中,最重要的进程就是init进程,其他的进程都是init进程fork出来的。
而在Android系统中,所有的进程都是zygote进程fork出来的子进程。
android系统中,init进程解析init.rc文件,fork出了zygote进程。来具体看看
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
其中,class main 表示这个service是属于main这一个组的,当这个组中的进程会被同时启动停止,例如还属于这个组的有netd, dbus,surfaceflinger等
socket表示这个zygote进程需要一个名称为”zygote”的socket资源,这样,系统启动后,我们就可以在/dev/socket目录下看到有一个名为zygote的文件。
onrestart表示当当前进程被重启时,这些进程也会被重启。
根据init.rc的语法可以知道,它的具体启动代码是app_process, 启动的参数有zytote,start-system-server。
int main(int argc, const char* const argv[])
{
...
AppRuntime runtime;
...
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 (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;
}
}
这个函数主要流程:
AppRantime继承自AndroidRuntime,AppRantime的start具体实现在父类中AndroidRuntime中
void AndroidRuntime::start(const char* className, const char* options)
{
...
JNIEnv* env;
if (startVm(&mJavaVM, &env) != 0) {//调用startVm启动虚拟机
return;
}
onVmCreated(env);
...
if (startReg(env) < 0) {// 调用函数startReg注册JNI方法
LOGE("Unable to register all android natives\n");
return;
}
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) {
LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
//通过JNI调用Java断的com.android.internal.os.ZygoteInit类的main函数。
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
LOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
...
}
可以看到start主要做了三件事情
再来看看ZygoteInit类的main函数
//其中有这么几行代码
if (argv[1].equals("start-system-server")) {
startSystemServer();
}
可以看到根据传入的参数调用了startSystemServer()
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(//调用forkSystemServer来fork一个子进程
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;
}
可以看到startSystemServer方法主要就是fork一个zygote的子进程,其中forkSystemServer是通过jni调用native代码,然后native调用系统接口来实现fork进程的
然后当fork出子进程之后调用handleSystemServerProcess来启动各种系统服务。
handleSystemServerProcess会将parsedArgs作为参数传递给RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs)
方法。zygoteInit方法又会调用zygoteInitNative()
方法,而zygoteInitNative方法是一个native方法,接下来SystemServer中的main方法会被执行
public class SystemServer{
...
native public static void init1(String[] args);
public static void main(String[] args) {
...
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");
init1(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();
}
}
init1是一个native方法,主要用于完成native实现的各种Service的启动,例如SufaceFlinger,AudioFinger等
init1最后会主动回调Java层中的init2方法。
init2方法创建了一个ServerThread线程。然后启动这个线程。
ServerThread继承自Thread
public void run() {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
SystemClock.uptimeMillis());
Looper.prepare();
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
BinderInternal.disableBackgroundScheduling(true);
android.os.Process.setCanSelfBackground(false);
...
LightsService lights = null;
PowerManagerService power = null;
BatteryService battery = null;
AlarmManagerService alarm = null;
NetworkManagementService networkManagement = null;
NetworkStatsService networkStats = null;
NetworkPolicyManagerService networkPolicy = null;
ConnectivityService connectivity = null;
WifiP2pService wifiP2p = null;
WifiService wifi = null;
IPackageManager pm = null;
Context context = null;
WindowManagerService wm = null;
BluetoothService bluetooth = null;
BluetoothA2dpService bluetoothA2dp = null;
DockObserver dock = null;
UsbService usb = null;
UiModeManagerService uiMode = null;
RecognitionManagerService recognition = null;
ThrottleService throttle = null;
NetworkTimeUpdateService networkTimeUpdater = null;
// Critical services...
try {
Slog.i(TAG, "Entropy Service");
ServiceManager.addService("entropy", new EntropyService());
Slog.i(TAG, "Power Manager");
power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);
Slog.i(TAG, "Activity Manager");
context = ActivityManagerService.main(factoryTest);
Slog.i(TAG, "Telephony Registry");
ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));
AttributeCache.init(context);
Slog.i(TAG, "Package Manager");
// Only run "core" apps if we're encrypting the device.
String cryptState = SystemProperties.get("vold.decrypt");
boolean onlyCore = false;
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
onlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
onlyCore = true;
}
pm = PackageManagerService.main(context,
factoryTest != SystemServer.FACTORY_TEST_OFF,
onlyCore);
boolean firstBoot = false;
try {
firstBoot = pm.isFirstBoot();
} catch (RemoteException e) {
}
ActivityManagerService.setSystemProcess();
mContentResolver = context.getContentResolver();
// The AccountManager must come before the ContentService
try {
Slog.i(TAG, "Account Manager");
ServiceManager.addService(Context.ACCOUNT_SERVICE,
new AccountManagerService(context));
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Account Manager", e);
}
Slog.i(TAG, "Content Manager");
ContentService.main(context,
factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);
Slog.i(TAG, "System Content Providers");
ActivityManagerService.installSystemProviders();
Slog.i(TAG, "Lights Service");
lights = new LightsService(context);
Slog.i(TAG, "Battery Service");
battery = new BatteryService(context, lights);
ServiceManager.addService("battery", battery);
Slog.i(TAG, "Vibrator Service");
ServiceManager.addService("vibrator", new VibratorService(context));
// only initialize the power service after we have started the
// lights service, content providers and the battery service.
power.init(context, lights, ActivityManagerService.self(), battery);
Slog.i(TAG, "Alarm Manager");
alarm = new AlarmManagerService(context);
ServiceManager.addService(Context.ALARM_SERVICE, alarm);
Slog.i(TAG, "Init Watchdog");
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);
// Skip Bluetooth if we have an emulator kernel
// TODO: Use a more reliable check to see if this product should
// support Bluetooth - see bug 988521
if (SystemProperties.get("ro.kernel.qemu").equals("1")) {
Slog.i(TAG, "No Bluetooh Service (emulator)");
} else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
Slog.i(TAG, "No Bluetooth Service (factory test)");
} else {
Slog.i(TAG, "Bluetooth Service");
bluetooth = new BluetoothService(context);
ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, bluetooth);
bluetooth.initAfterRegistration();
bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);
ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
bluetoothA2dp);
bluetooth.initAfterA2dpRegistration();
int airplaneModeOn = Settings.System.getInt(mContentResolver,
Settings.System.AIRPLANE_MODE_ON, 0);
int bluetoothOn = Settings.Secure.getInt(mContentResolver,
Settings.Secure.BLUETOOTH_ON, 0);
if (airplaneModeOn == 0 && bluetoothOn != 0) {
bluetooth.enable();
}
}
} catch (RuntimeException e) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting core service", e);
}
...
// These are needed to propagate to the runnable below.
final Context contextF = context;
final BatteryService batteryF = battery;
final NetworkManagementService networkManagementF = networkManagement;
final NetworkStatsService networkStatsF = networkStats;
final NetworkPolicyManagerService networkPolicyF = networkPolicy;
final ConnectivityService connectivityF = connectivity;
final DockObserver dockF = dock;
final UsbService usbF = usb;
final ThrottleService throttleF = throttle;
final UiModeManagerService uiModeF = uiMode;
final AppWidgetService appWidgetF = appWidget;
final WallpaperManagerService wallpaperF = wallpaper;
final InputMethodManagerService immF = imm;
final RecognitionManagerService recognitionF = recognition;
final LocationManagerService locationF = location;
final CountryDetectorService countryDetectorF = countryDetector;
final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
final TextServicesManagerService textServiceManagerServiceF = tsms;
final StatusBarManagerService statusBarF = statusBar;
...
Looper.loop();
Slog.d(TAG, "System ServerThread is exiting!");
}
等到AMS被启动,就可以启动Launcher桌面应用了。