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

news/2024/9/23 4:34:19/

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.ppmy.cn/news/1435011.html

相关文章

五、e2studio VS STM32CubeIDE之汉化

目录 一、概述/目的 二、stm32cubeide汉化 2.1 在线下载安装汉化插件 2.2 直接安装汉化包(推荐) 三、e2studio STM32CubeIDE中英文切换 五、e2studio VS STM32CubeIDE之汉化 一、概述/目的 介绍stm32cubeide汉化方案和汉化包 e2studio自带汉化包,在安装过程中…

OpenHarmony鸿蒙南向开发案例:【智能猫眼(基于3518开发板)】

样例简介 本Demo是基于Hi3518开发板,使用开源OpenHarmony开发的RTSP协议流媒体应用。达到将Hi3518开发板中摄像头获取的数据通过RTSP协议传输到手机并显示 。 rtsp实现可参考文档:openharmony_1.0.1实现RTSPServer 运行效果 样例原理 如上图所示&…

XiaodiSec day033 Learn Note 小迪安全学习笔记

XiaodiSec day033 Learn Note 小迪安全学习笔记 记录得比较凌乱,不尽详细 day33 文件上传 中间件上传,学了也不一定遇得到,但是要学 文件上传漏洞有几个情况会导致,有后端验证,第三方富文本编辑器导致 编辑器被目…

【运维】docker-compose部署redis

部署Redis使用docker-compose是一种简便且流行的方式。以下是基本的docker-compose.yml文件示例,用于部署单节点Redis服务 方案一 直接使用docker安装单机版 创建.env环境文件并配置管理密码 echo REDIS_PWDredis123456 > .env创建docker-compose.yml环境文件…

详细分析mysqlslap的基本知识 | 压力测试(附Demo)

目录 前言1. 基本知识2. 参数解读2.1 auto-generate-sql2.2 only-print2.3 iterations2.4 并发处理参数 前言 对数据库进行压力测试,对此补充这方面的详细知识点 1. 基本知识 mysqlslap 是 MySQL 自带的用于模拟数据库负载的压力测试工具 可以模拟多个客户端并发…

[C++][算法基础]判定质数(试除法)

给定 n 个正整数 ai,判定每个数是否是质数。 输入格式 第一行包含整数 n。 接下来 n 行,每行包含一个正整数 ai。 输出格式 共 n 行,其中第 i 行输出第 i 个正整数 ai 是否为质数,是则输出 Yes,否则输出 No。 数…

MATLAB 获取时间戳

说明 首先使用tic函数开始计时,然后使用toc函数获取从开始计时到当前的秒数,即时间戳。 最后,将时间戳赋值给变量timestamp,可以在后续使用。 需要注意的是,tic函数和toc函数必须成对使用。也就是说,每个…

学习周报:文献阅读+Fluent案例+水力学理论学习

目录 摘要 Abstract 文献阅读:基于物理信息神经网络的压力场重建比较评价 文献摘要 提出问题 研究方案 使用的PINN框架 所需方程 实验设置 实验一:采用二维Taylor衰减涡的理论解来验证不同方法之间的压力重建性能 实验结果展示 实验二&#x…