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

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

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

本篇文章主要介紹 Android 開發(fā)中的部分知識點(diǎn),通過閱讀本篇文章,您將收獲以下內(nèi)容:

一、啟動流程概述

二、Android啟動分析

三、init 進(jìn)程啟動分析

四、init 啟動腳本分析

五、init 進(jìn)程分析

六、init 腳本執(zhí)行

七、init 進(jìn)程守護(hù)

八、init rc 腳本啟動Zygote

九、啟動分析小結(jié)

一、 啟動流程概述

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

  • 1.開機(jī)上電,加載固化的ROM。
  • 2.加載BootLoader,拉起Android OS。
  • 3.加載Uboot,初始外設(shè),引導(dǎo)Kernel啟動等。
  • 4.啟動Kernel,加載驅(qū)動,硬件。
  • 5.啟動Android,掛載分區(qū),加載驅(qū)動、服務(wù),init進(jìn)程等。

Android系統(tǒng)啟動大致過程如下:

 

Android 9.0 init 啟動流程

 

 

Android 啟動過程

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

二、Android啟動分析

Uboot啟動Kernel完成系統(tǒng)設(shè)置后,會首先在系統(tǒng)中尋找init.rc文件,并啟動init進(jìn)程。

 

Android 9.0 init 啟動流程

 

 

Android 啟動分析

三、init 進(jìn)程啟動分析

Init進(jìn)程是Android啟動的第一個(gè)進(jìn)程,進(jìn)程號為1,是Android的系統(tǒng)啟動的核心進(jìn)程,主要用來創(chuàng)建Zygote、屬性服務(wù)等。 init.cpp 中的main 函數(shù),是init進(jìn)程的入口函數(shù),源碼主要存在systemcoreinit目錄下。

常見init.xxx.rc 進(jìn)程如下:

 

Android 9.0 init 啟動流程

 

 

常見init.xxx.rc 進(jìn)程

init 進(jìn)程主要作用

 

Android 9.0 init 啟動流程

 

 

init 進(jìn)程主要作用

/system/core/init 部分內(nèi)容如下:

 

Android 9.0 init 啟動流程

 

 

/system/core/init 部分內(nèi)容

main 函數(shù)主要做的事情

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

2.初始化并啟動屬性服務(wù)

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

init.cpp main 函數(shù)實(shí)現(xiàn)代碼如下:

int main(int argc, char** argv) {
 ... ...
 if (!strcmp(basename(argv[0]), "watchdogd")) {
 //啟動看門狗函數(shù)
 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內(nèi)存上獲取基本的文件系統(tǒng),剩余的被 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));
 // 非特權(quán)應(yīng)用不能使用 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");
 //創(chuàng)建可供讀寫的 vendor目錄
 mkdir("/mnt/vendor", 0755);
 // 在/dev目錄下掛載好 tmpfs 以及 kmsg 
 // 這樣就可以初始化 /kernel Log 系統(tǒng),供用戶打印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();
 // 優(yōu)先加載selinux log系統(tǒng), 緊接著初始化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);
 // 清空設(shè)置的環(huán)境變量
 unsetenv("INIT_SECOND_STAGE");
 unsetenv("INIT_STARTED_AT");
 unsetenv("INIT_SELINUX_TOOK");
 unsetenv("INIT_AVB_VERSION");
 // 設(shè)置第二階段的selinux
 SelinuxSetupKernelLogging();
 SelabelInitialize();
 SelinuxRestoreContext();
 //創(chuàng)建 epoll 句柄
 epoll_fd = epoll_create1(EPOLL_CLOEXEC);
 if (epoll_fd == -1) {
 PLOG(FATAL) << "epoll_create1 failed";
 }
 //設(shè)置 子進(jìn)程處理函數(shù)
 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();
 //啟動屬性服務(wù)
 start_property_service();
 //為USB存儲設(shè)置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 進(jìn)程分析

Android 9.0 init 啟動流程

 

 

init.rc on

Android 9.0 init 啟動流程

 

 

init.rc services

Android 9.0 init 啟動流程

 

 

init.rc import

五、init 進(jìn)程分析

 

Android 9.0 init 啟動流程

 

 

init 進(jìn)程分析

Android 9.0 init 啟動流程

 

 

init 解析腳本分析

Android 9.0 init 啟動流程

 

 

init 事件列表

Android 9.0 init 啟動流程

 

 

init 事件結(jié)構(gòu)

六 、init 腳本執(zhí)行

 

Android 9.0 init 啟動流程

 

 

init 進(jìn)程解析和執(zhí)行

Android 9.0 init 啟動流程

 

 

整理事件列表

Android 9.0 init 啟動流程

 

 

init 構(gòu)建事件

Android 9.0 init 啟動流程

 

 

Service 事件分類

Android 9.0 init 啟動流程

 

 

init 進(jìn)程執(zhí)行命令和啟動服務(wù)

七、init 進(jìn)程守護(hù)

init進(jìn)程處理消息事件

  1. 根據(jù)Shell或者系統(tǒng)中消息設(shè)置系統(tǒng)prop
  •  
  1. 守護(hù)系統(tǒng)服務(wù),如果服務(wù)退出,重啟退出的服務(wù)。

 

Android 9.0 init 啟動流程

 

 

init守護(hù)進(jìn)程

Android 9.0 init 啟動流程

 

 

init 處理 prop 消息分析

Android 9.0 init 啟動流程

 

 

init 守護(hù)服務(wù)分析

八、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}
... ...

九、啟動分析小結(jié)

 

Android 9.0 init 啟動流程

 

 

啟動分析小結(jié)

分享到:
標(biāo)簽:Android
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

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

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定