Android 5.1 乙太網服務啟動過程
1.SystemServer簡介
Android系統中的好多功能能夠執行起來,在程式碼層面好多都是以服務的方式實現的。而幾乎所有的服務都是在SystemServer中建立的。SystemServer作為Android系統的一個核心程序,它是在zygote程序中孕育出來的。
那麼zygote程序是怎麼來的呢?再次我稍作解釋。
我們知道,Android系統是以Linux為核心的,在Linux系統中,所有的程序無一例外的都是由init程序直接或者間接建立的,也就是說所有的程序都是init程序的後代(這個和我們現在所講的,中國人都是炎黃子孫一個道理,炎黃相當於是init程序,我們這些人都是其子孫程序)。那麼zygote程序也不例外,它就是在系統啟動過程中由init程序建立的。
import /init.${ro.zygote}.rc service servicemanager /system/bin/servicemanager class core user system group system critical onrestart restart healthd onrestart restart zygote onrestart restart media onrestart restart surfaceflinger onrestart restart drm service surfaceflinger /system/bin/surfaceflinger class core user system group graphics drmrpc onrestart restart zygote
在rootdir中還有4個和zygote相關的指令碼:init.zygote32.rc、init.zygote32_64.rc、init.zygote64.rc、init.zygote64_32.rc,這個是為了區分64位和32才這麼做的。
我們可以看一下init.zygote32.rc中的內容:
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
那麼SystemServer又是怎樣建立的呢?答案是:在ZygoteInit中建立的,看下邊的程式碼。
public class ZygoteInit {
private static final String TAG = "Zygote";
public static void main(String argv[]) {
try {
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
registerZygoteSocket(socketName);
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();
// Disable tracing so that forked processes do not inherit stale tracing tags from
// Zygote.
Trace.setTracingEnabled(false);
if (startSystemServer) {
startSystemServer(abiList, socketName);/*啟動SystemServer的地方*/
}
Log.i(TAG, "Accepting command socket connections");
runSelectLoop(abiList);
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
我們在來看看startSystemServer方法的程式碼實現:
/*
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer(String abiList, String socketName)
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(/*這裡fork了SystemServer*/
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) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
handleSystemServerProcess(parsedArgs);
}
return true;
}
2.乙太網服務的啟動
乙太網在Android中能夠執行,也是作為一個系統級服務來執行的,那麼自然我們能聯想到它是在SystemServer中啟動的。程式碼路徑如下:
frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {
private static final String TAG = "SystemServer";
.......................
private static final String ETHERNET_SERVICE_CLASS =
"com.android.server.ethernet.EthernetService";
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Start services.
/* SystemServer中啟動服務的三個方法 */
try {
startBootstrapServices();
startCoreServices();
startOtherServices(); /* 這個方法裡啟動了乙太網服務程序 */
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
}
}
private void startOtherServices() {
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)) {
mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
}
}
至此,Android乙太網服務程序就算啟動起來了
乙太網服務啟動後,乙太網卡對應的埠又是怎樣up起來的呢?又是怎樣分配到地址的呢?我的另一篇博文《Android5.1系統啟動過程中啟動有線網絡卡併為其分配靜態IP地址》http://blog.csdn.net/moyu123456789/article/details/50002099中有比較明確的解釋。