linux内核初始化成功后是如何过渡到android初始化的

Android用的linux内核,以完成OS该有的功能,例如,文件系统,网络,内存管理,进程调度,驱动等 ,向下管理硬件资源向上提供系统调用。另一些Android特有驱动也放在内核之中。
当linux内核启动完成后,便进行Android的初始化工作。

内核端

内核是在main.c中进行初始化,从kernel_init开始

static int __init kernel_init(void * unused)
{lock_kernel();/** init can run on any cpu.*/set_cpus_allowed_ptr(current, CPU_MASK_ALL_PTR);/** Tell the world that we're going to be the grim* reaper of innocent orphaned children.** We don't want people to have to make incorrect* assumptions about where in the task array this* can be found.*/init_pid_ns.child_reaper = current;cad_pid = task_pid(current);smp_prepare_cpus(setup_max_cpus);do_pre_smp_initcalls();start_boot_trace();smp_init();sched_init_smp();cpuset_init_smp();do_basic_setup();/** check if there is an early userspace init.  If yes, let it do all* the work*/if (!ramdisk_execute_command)ramdisk_execute_command = "/init";if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {ramdisk_execute_command = NULL;prepare_namespace();}/** Ok, we have completed the initial bootup, and* we're essentially up and running. Get rid of the* initmem segments and start the user-mode stuff..*/init_post();return 0;
}

在main.c 函数init_post()开始执行Android相关代码

	if (ramdisk_execute_command) {run_init_process(ramdisk_execute_command);printk(KERN_WARNING "Failed to execute %s\n",ramdisk_execute_command);}/** We try each of these until one succeeds.** The Bourne shell can be used instead of init if we are* trying to recover a really broken machine.*/if (execute_command) {run_init_process(execute_command);printk(KERN_WARNING "Failed to execute %s.  Attempting ""defaults...\n", execute_command);}run_init_process("/sbin/init");run_init_process("/etc/init");run_init_process("/bin/init");run_init_process("/bin/sh");

run_init_process便是加载执行文件。可以看到有六处出现了这个函数,但是执行的是第一个,
也就是run_init_process(ramdisk_execute_command), 变量ramdisk_execute_command在kernel_init执行时被赋值为’/init’, 也就是说,将会执行根文件目录下的init进程,而这个进程正是Android的初始化进程.

Android端

在根目录下可以看到init是个软链接,真正的init文件在/system/bin下面
在这里插入图片描述
进入目录,真身就在里面

在这里插入图片描述
加载执行后,就是大家耳熟能详的init进程了,开始进入Android的世界。

int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)__asan_set_error_report_callback(AsanReportCallback);
#endifif (!strcmp(basename(argv[0]), "ueventd")) {return ueventd_main(argc, argv);}if (argc > 1) {if (!strcmp(argv[1], "subcontext")) {android::base::InitLogging(argv, &android::base::KernelLogger);const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();return SubcontextMain(argc, argv, &function_map);}if (!strcmp(argv[1], "selinux_setup")) {return SetupSelinux(argv);}if (!strcmp(argv[1], "second_stage")) {return SecondStageMain(argc, argv);}}return FirstStageMain(argc, argv);
}

init可执行文件的命名

在源码/system/core/init目录下查看mk和bp文件,在文件Android.mk中

LOCAL_MODULE := init_first_stage
LOCAL_MODULE_STEM := init

在文件Android.bp中

cc_binary {name: "init_second_stage",recovery_available: true,stem: "init",defaults: ["init_defaults"],static_libs: ["libinit"],required: ["e2fsdroid","init.rc","mke2fs","sload_f2fs","make_f2fs","ueventd.rc",],srcs: ["main.cpp"],symlinks: ["ueventd"],target: {recovery: {cflags: ["-DRECOVERY"],exclude_shared_libs: ["libbinder","libutils",],},},
}

在Android 11源码中,mk文件和bp文件还是共存的,但mk在编译时会被转换成bp文件。在初始化的过程中,与Android密切相关的又分为两个阶段,但无论在第一阶段,还是第二阶段,其stem都是init。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/636720.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

时序分析基础(6)——input delay时序分析

1 简介 FPGA对于外部的时钟以及数据的延时信息是不知道的,在低速时钟且时钟发射沿在数据正中心的时候,一般可以不做约束来直接使用。但是到了高速时钟或者双沿采样或者发射沿和数据对齐的情况下,这时候就需要告诉VIVADO外部的时钟与数据情况来…

前端css中border-radius的简单使用

前端css中border-radius的使用 一、前言二、border-radius语法三、border-radius的模型例子1.源码12.源码1效果截图 四、border-radius的动画效果(动态交互)1.源码22.源码2显示效果 五、结语六、定位日期 一、前言 在CSS中,我们常用border-r…

LE Audio —— Boardcast 与 Unicast 对比

蓝牙低功耗音频(Bluetooth LE Audio,简称:LE Audio)自 2020 年 1月 发布,到 2022 年 7 月完成全套规范的定义。 LE Audio是新一代蓝牙音频技术标准,采用了全新的音频架构,充分利用低功耗蓝牙无…

二维码门楼牌管理应用平台建设:网格化管理的新篇章

文章目录 前言一、二维码门楼牌管理应用平台的建设背景二、二维码门楼牌管理应用平台的功能特点三、二维码门楼牌管理应用平台的实际应用四、二维码门楼牌管理应用平台的前景展望 前言 随着信息技术的飞速发展,二维码门楼牌管理应用平台的建设已成为城市网格化管理…

【Java基础】25.包(package)

文章目录 前言一、包的作用二、创建包三、import 关键字四、package 的目录结构五、设置 CLASSPATH 系统变量 前言 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。 一、包的作用 把功能相似或相关的类或接口组织在同一个包中&#xff…

STM32 HAL库 利用CH376进行USB文件读写

STM32 其实可以进行读取USB文件,但仅限于F4以上芯片才可以进行SUB文件读写,但在项目开发中,往往用不到此芯片,那么只能通过外挂的USB芯片进行USB文件读写,本文则是采用STM32F103的SPI与CH376进行通信,通过CH376操作指令进行操作。 1、CH376介绍 CH376芯片 是沁恒的一款文…

Modelsim自动化仿真脚本(TCL)——简单实例

目录 1. Modelsim与TCL脚本的关系 2.实验文件 2.1设计文件 2.2仿真测试文件 2.3. 脚本文件 3. 实验步骤 3.1. 创建文件夹 3.2. 指定路径 3.3. 创建工程 3.4. 运行命令 3.4. 实验效果 1. Modelsim与TCL脚本的关系 TCL(Tool Command Language)是…

Vue.js------Vue组件基础

能够理解Vue组件概念和作用能够掌握封装创建组件能力能够使用组件之间通信能够完成todo案例 一.Vue组件创建和使用 1.折叠面板-实现多个 创建一个文件夹demo 具体步骤请参考vue.js---vue基础 ⚫ 解决方案: 采用vue提供的单.vue文件-组件方式来封装一套然后复用 在component…

C++:面向对象大坑:菱形继承

菱形继承 1.单继承1.概念 2.多继承2.1概念2.2菱形继承1.概念2.问题3.样例理解二义性数据冗余对于内存模型抽象化 2.3菱形虚拟继承(解决菱形继承的问题)1.概念2.样例理解对于内存模型抽象化 2.4总结 3.问题总结1.C有多继承,为什么?…

xpath为元素路径定位

selenium4 pytest支持更多的包 和unittest对比 yaml数据驱动 allure报告 日志 数据库 通过jenkins发送消息 下载chromedriver Chrome for Testing availability https://googlechromelabs.github.io/chrome-for-testing/ 把chromedriver放到python文件夹里面 浏览…

【编译原理】03语法分析

1,语法分析的若干问题 1.1 语法分析器的作用 编译器前端的重要组成部分: (1) 根据词法分析器提供的记号流,为语法正确的输入构造分析树(或语法树)。 (2) 检查输入中的语法(可能包括词法)错误,并调用出错处理器进…

在Gtiee搭建仓库传代码/多人开发/个人代码备份---git同步---TortoiseGit+TortoiseSVN

文章目录 前言1.安装必要软件2. Gitee建立新仓库git同步2.1 Gitee建立新仓库2.2 Gitee仓库基本配置2.3 Git方式进行同步 3. TortoiseGitTortoiseSVN常用开发方式3.1 秘钥相关3.2 TortoiseGit拉取代码TortoiseGit提交代码 4. 其他功能探索总结 前言 正常企业的大型项目都会使用…