日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本篇文章主要介紹 Android 開發中的部分知識點,通過閱讀本篇文章,您將收獲以下內容:

一、啟動流程概述

二、Android啟動分析

三、init 進程啟動分析

四、init 啟動腳本分析

五、init 進程分析

六、init 腳本執行

七、init 進程守護

八、init rc 腳本啟動Zygote

九、啟動分析小結

一、 啟動流程概述

Android啟動流程跟 linux啟動類似,大致分為如下五個階段。

  • 1.開機上電,加載固化的ROM。
  • 2.加載BootLoader,拉起Android OS。
  • 3.加載Uboot,初始外設,引導Kernel啟動等。
  • 4.啟動Kernel,加載驅動,硬件。
  • 5.啟動Android,掛載分區,加載驅動、服務,init進程等。

Android系統啟動大致過程如下:

 

Android 9.0 init 啟動流程

 

 

Android 啟動過程

由于水平有限,無法深入了理解驅動層代碼,本文主要對 Android上層啟動流程進行分析。

二、Android啟動分析

Uboot啟動Kernel完成系統設置后,會首先在系統中尋找init.rc文件,并啟動init進程。

 

Android 9.0 init 啟動流程

 

 

Android 啟動分析

三、init 進程啟動分析

Init進程是Android啟動的第一個進程,進程號為1,是Android的系統啟動的核心進程,主要用來創建Zygote、屬性服務等。 init.cpp 中的main 函數,是init進程的入口函數,源碼主要存在systemcoreinit目錄下。

常見init.xxx.rc 進程如下:

 

Android 9.0 init 啟動流程

 

 

常見init.xxx.rc 進程

init 進程主要作用

 

Android 9.0 init 啟動流程

 

 

init 進程主要作用

/system/core/init 部分內容如下:

 

Android 9.0 init 啟動流程

 

 

/system/core/init 部分內容

main 函數主要做的事情

1.創建掛載啟動所需的文件系統(tmpfs、 devpts、 proc、 sysfs、 selinuxfs等)。

2.初始化并啟動屬性服務

3.解析init.rc 腳本配置文件,并啟動Zygote 進程。

init.cpp main 函數實現代碼如下:

int main(int argc, char** argv) {
 ... ...
 if (!strcmp(basename(argv[0]), "watchdogd")) {
 //啟動看門狗函數
 return watchdogd_main(argc, argv);
 }
 ... ...
 //啟動第一階段
 if (is_first_stage) {
 boot_clock::time_point start_time = boot_clock::now();
 // 清理 umask.
 umask(0);
 clearenv();
 setenv("PATH", _PATH_DEFPATH, 1);
 // 在RAM內存上獲取基本的文件系統,剩余的被 rc 文件所用
 mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
 mkdir("/dev/pts", 0755);
 mkdir("/dev/socket", 0755);
 mount("devpts", "/dev/pts", "devpts", 0, NULL);
 #define MAKE_STR(x) __STRING(x)
 mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
 // 非特權應用不能使用 Android 命令行
 chmod("/proc/cmdline", 0440);
 gid_t groups[] = { AID_READPROC };
 setgroups(arraysize(groups), groups);
 mount("sysfs", "/sys", "sysfs", 0, NULL);
 mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
 mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
 if constexpr (WORLD_WRITABLE_KMSG) {
 mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11));
 }
 mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
 mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
 // Mount staging areas for devices managed by vold
 // See storage config details at http://source.android.com/devices/storage/
 mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
 "mode=0755,uid=0,gid=1000");
 //創建可供讀寫的 vendor目錄
 mkdir("/mnt/vendor", 0755);
 // 在/dev目錄下掛載好 tmpfs 以及 kmsg 
 // 這樣就可以初始化 /kernel Log 系統,供用戶打印log
 InitKernelLogging(argv);
 LOG(INFO) << "init first stage started!";
 if (!DoFirstStageMount()) {
 LOG(FATAL) << "Failed to mount required partitions early ...";
 }
 SetInitAvbVersionInRecovery();
 // Enable seccomp if global boot option was passed (otherwise it is enabled in zygote).
 global_seccomp();
 // 優先加載selinux log系統, 緊接著初始化selinux
 SelinuxSetupKernelLogging();
 SelinuxInitialize();
 // 添加 selinux 是否啟動成功的log
 if (selinux_android_restorecon("/init", 0) == -1) {
 PLOG(FATAL) << "restorecon failed of /init failed";
 }
 setenv("INIT_SECOND_STAGE", "true", 1);
 static constexpr uint32_t kNanosecondsPerMillisecond = 1e6;
 uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond;
 setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1);
 char* path = argv[0];
 char* args[] = { path, nullptr };
 execv(path, args);
 // execv() only returns if an error hAppened, in which case we
 // panic and never fall through this conditional.
 PLOG(FATAL) << "execv("" << path << "") failed";
 }
 //啟動第二階段
 InitKernelLogging(argv);
 LOG(INFO) << "init second stage started!";
 // Set up a session keyring that all processes will have access to. It
 // will hold things like FBE encryption keys. No process should override
 // its session keyring.
 keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1);
 // Indicate that booting is in progress to background fw loaders, etc.
 close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
 //初始化屬性
 property_init();
 // If arguments are passed both on the command line and in DT,
 // properties set in DT always have priority over the command-line ones.
 process_kernel_dt();
 process_kernel_cmdline();
 // Propagate the kernel variables to internal variables
 // used by init as well as the current required properties.
 export_kernel_boot_props();
 // Make the time that init started available for bootstat to log.
 property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));
 property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK"));
 // Set libavb version for Framework-only OTA match in Treble build.
 const char* avb_version = getenv("INIT_AVB_VERSION");
 if (avb_version) property_set("ro.boot.avb_version", avb_version);
 // 清空設置的環境變量
 unsetenv("INIT_SECOND_STAGE");
 unsetenv("INIT_STARTED_AT");
 unsetenv("INIT_SELINUX_TOOK");
 unsetenv("INIT_AVB_VERSION");
 // 設置第二階段的selinux
 SelinuxSetupKernelLogging();
 SelabelInitialize();
 SelinuxRestoreContext();
 //創建 epoll 句柄
 epoll_fd = epoll_create1(EPOLL_CLOEXEC);
 if (epoll_fd == -1) {
 PLOG(FATAL) << "epoll_create1 failed";
 }
 //設置 子進程處理函數
 sigchld_handler_init();
 if (!IsRebootCapable()) {
 // If init does not have the CAP_SYS_BOOT capability, it is running in a container.
 // In that case, receiving SIGTERM will cause the system to shut down.
 InstallSigtermHandler();
 }
 LoadRscRoProps();
 property_load_boot_defaults();
 export_oem_lock_status();
 //啟動屬性服務
 start_property_service();
 //為USB存儲設置udc Contorller, sys/class/udc
 set_usb_controller();
 const BuiltinFunctionMap function_map;
 Action::set_function_map(&function_map);
 subcontexts = InitializeSubcontexts();
 ActionManager& am = ActionManager::GetInstance();
 ServiceList& sm = ServiceList::GetInstance();
 LoadBootScripts(am, sm);
 // Turning this on and letting the INFO logging be discarded adds 0.2s to
 // Nexus 9 boot time, so it's disabled by default.
 if (false) DumpState();
 am.QueueEventTrigger("early-init");
 // Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
 am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
 // ... so that we can start queuing up actions that require stuff from /dev.
 am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
 am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
 am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
 am.QueueBuiltinAction(keychord_init_action, "keychord_init");
 am.QueueBuiltinAction(console_init_action, "console_init");
 // Trigger all the boot actions to get us started.
 am.QueueEventTrigger("init");
 // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
 // wasn't ready immediately after wait_for_coldboot_done
 am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
 // Don't mount filesystems or start core system services in charger mode.
 std::string bootmode = GetProperty("ro.bootmode", "");
 if (bootmode == "charger") {
 am.QueueEventTrigger("charger");
 } else {
 am.QueueEventTrigger("late-init");
 }
 // Run all property triggers based on current state of the properties.
 am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
 while (true) {
 // By default, sleep until something happens.
 int epoll_timeout_ms = -1;
 if (do_shutdown && !shutting_down) {
 do_shutdown = false;
 if (HandlePowerctlMessage(shutdown_command)) {
 shutting_down = true;
 }
 }
 if (!(waiting_for_prop || Service::is_exec_service_running())) {
 am.ExecuteOneCommand();
 }
 if (!(waiting_for_prop || Service::is_exec_service_running())) {
 if (!shutting_down) {
 auto next_process_restart_time = RestartProcesses();
 // If there's a process that needs restarting, wake up in time for that.
 if (next_process_restart_time) {
 epoll_timeout_ms = std::chrono::ceil<std::chrono::milliseconds>(
 *next_process_restart_time - boot_clock::now())
 .count();
 if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
 }
 }
 // If there's more work to do, wake up again immediately.
 if (am.HasMoreCommands()) epoll_timeout_ms = 0;
 }
 epoll_event ev;
 int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms));
 if (nr == -1) {
 PLOG(ERROR) << "epoll_wait failed";
 } else if (nr == 1) {
 ((void (*)()) ev.data.ptr)();
 }
 }
 return 0;
}

基于MTK 平臺 init.cpp 源碼分析

 

Android 9.0 init 啟動流程

 

 

基于MTK 平臺 init.cpp 主要作用

四、 init 啟動腳本分析

init.rc 路徑 一般在system/core/rootdir下,init腳本是有Android 初始化語言編寫。

Android Init Language 語句類型:

  • 1.Action
  • 2.Command
  • 3.Service
  • 4.Option
  • 5.Import

 

Android 9.0 init 啟動流程

 

 

init 進程分析

Android 9.0 init 啟動流程

 

 

init.rc on

Android 9.0 init 啟動流程

 

 

init.rc services

Android 9.0 init 啟動流程

 

 

init.rc import

五、init 進程分析

 

Android 9.0 init 啟動流程

 

 

init 進程分析

Android 9.0 init 啟動流程

 

 

init 解析腳本分析

Android 9.0 init 啟動流程

 

 

init 事件列表

Android 9.0 init 啟動流程

 

 

init 事件結構

六 、init 腳本執行

 

Android 9.0 init 啟動流程

 

 

init 進程解析和執行

Android 9.0 init 啟動流程

 

 

整理事件列表

Android 9.0 init 啟動流程

 

 

init 構建事件

Android 9.0 init 啟動流程

 

 

Service 事件分類

Android 9.0 init 啟動流程

 

 

init 進程執行命令和啟動服務

七、init 進程守護

init進程處理消息事件

  1. 根據Shell或者系統中消息設置系統prop
  •  
  1. 守護系統服務,如果服務退出,重啟退出的服務。

 

Android 9.0 init 啟動流程

 

 

init守護進程

Android 9.0 init 啟動流程

 

 

init 處理 prop 消息分析

Android 9.0 init 啟動流程

 

 

init 守護服務分析

八、init rc 腳本啟動Zygote

Zygote 的 classname 為main.

init.rc文件配置代碼如下:

... ... 
on nonencrypted
 class_start main
 class_start late_start
on property:sys.init_log_level=*
 loglevel ${sys.init_log_level}
... ...

九、啟動分析小結

 

Android 9.0 init 啟動流程

 

 

啟動分析小結

分享到:
標簽:Android
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定