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);
#endif

    if (!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。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java关键字和API

1 this和super关键字 1.this和super的意义 this:当前对象 在构造器和非静态代码块中,表示正在new的对象 在实例方法中,表示调用当前方法的对象 super:引用父类声明的成员 无论是this和super都是和对象有关的。 2.this和sup…

详解数据结构之-「数组篇」

详解数据结构之-「数组篇」 太久没有写算法了,最近在回顾数据结构和算法,准备把这块重新捡起来,给自己立一个flag,每周花时间练习算法,写一篇总结。 数组 数组数据结构(英语:array data stru…

Mysql学习2

目录 一.数据库: 1.创建数据库: 2.查看数据库: 3.备份恢复数据库: 二.表 1.创建表指令: 2.MySQL常用数据类型: 3.删除与修改表(重点): 4.数据库CRUD语句&#xf…

网络 (TCP/IP 四层协议中常见网络协议)

应用层 DNS (Domain Name System) 域名系统. DNS 是一整套从域名映射到 IP的系统 NAT 技术 解决 IP 地址不够用的问题. 可以实现私有 IP 和全局 IP 的相互转换 NAPT 技术 使用 IP Port 唯一确定局域网中的主机 传输层 TCP 协议 (Transmission Control Protocol 传输控制协议…

C++:范围-based for 循环

范围-based for 循环是 C11 引入的一种循环语法,它简化了遍历容器和数组等序列的操作,使代码更加清晰和简洁。它通常用于遍历容器类(如数组、向量、列表等)中的元素,或者以范围的形式遍历初始化列表。 范围-based for …

AI大模型探索之路-实战篇1:基于OpenAI智能翻译助手实战落地

文章目录 前言一、需求规格描述二、系统架构设计三、技术实施方案四、核心功能说明五、开源技术选型六、代码实现细节1.图形用户界面(GUI)的开发2.大型模型调用的模块化封装3.文档解析翻译结果处理 总结 前言 在全球化的浪潮中,语言翻译需求…

HarmonyOS NEXT 使用Canvas实现模拟时钟案例

介绍 本示例介绍利用 Canvas 和定时器实现模拟时钟场景,该案例多用于用户需要显示自定义模拟时钟的场景。 效果图预览 使用说明 无需任何操作,进入本案例页面后,所见即模拟时钟的展示。 使用说明 无需任何操作,进入本案例页…

20240330-2-XGBoost面试题

XGBoost面试题 1. RF和GBDT的区别 相同点: 都是由多棵树组成,最终的结果都是由多棵树一起决定。 不同点: 集成学习: R F RF RF属于 B a g g i n g Bagging Bagging思想,而 G B D T GBDT GBDT是 B o o s t i n g Bo…

【数据结构2-线性表】

数据结构2-线性表 1 线性表-数组2 线性表-单链式结构2.1 前插顺序单链表2.2 后插顺序单链表2.3 循环单链表2.4 双向链表 总结 线性表、栈、队列、串和数组都属于线性结构。 线性结构的基本特点是除第一个元素无直接前驱,最后一个元素无直接后继之外,其他…

Django中间件的源码解析流程(上)——中间件载入的前置

目录 1. ​前言​ 2. 请求的入口 3. 中间件加载的入口 4. 源码中的闭包实现 5. 最后 1. 前言 哈喽,大家好,我是小K,今天咋们分享的内容是:在学会Django中间件之后, 我们继续深入底层源码。 在执行中间件时请求到来总是从前往后…

第三方应用类---Phpmyadmin 后台 Getshell 操作

免责声明:本节仅做技术交流学习. 目录 什么是Phpmyadmin? getshell前提条件: 详细步骤: 1-搜集到开放phpmyadmin的web,然后访问进去 2-执行SQL命令查看是否开启了读写权限 3-开启了读写权限-->继续 没有开读写权限--->鸡鸡 4-有读写权限之后,执行SQL语句导出文件…

【Python】函数进阶(纯干货版)

目录 函数的多返回值 多个参数的传递 缺省参数 不定长参数 位置不定长参数传参举例 关键字不定长参数举例 函数作为参数传递 匿名函数 函数的多返回值 在Python中允许一个函数带回多个返回值,写法是一个return 返回值1,返回值2 在接收的时候同样…

快速入门Spring Data JPA

Spring Data JPA是Spring Data框架的一小部分,它能够让开发者能够更加简单的对数据库进行增删改查。 由于Spring Data JPA可以自动生成SQL代码所以一般情况下,简单的增删查改就可以交给Spring Data JPA来完成,而复杂的动态SQL等用MyBatis来完…

软考 系统架构设计师系列知识点之大数据设计理论与实践(14)

接前一篇文章:软考 系统架构设计师系列知识点之大数据设计理论与实践(13) 所属章节: 第19章. 大数据架构设计理论与实践 第4节 Kappa架构 19.4.3 Kappa架构的实现 下面以Apache Kafka为例来讲述整个全新架构的过程。 部署Apach…

解线性方程组——直接解法:LU分解、PLU分解(类似列主元消去法) | 北太天元

L: lower triangular 下三角 U: upper triangular 上三角 LU 分解,顾名思义,为 把一个 矩阵 分成 一个下三角矩阵 乘上一个上三角矩阵的形式。 Example 为什么可以这样 几个基本的初等行变换,可以自己验算一下,等式的左边与右边…

Linux管道共享内存

前言 进程虽然是独立运行的个体,但它们之间有时候需要协作才能完成一项工作,比如有两个进程需要同步数据,进程 A 把数据准备好后,想把数据发往进程 B,进程 B 必须被提前通知有数据即将到来,或者进程 A 想发…

腾讯EdgeOne产品测评体验—金字塔般的网络安全守护神

作为一名对网络安全和性能优化充满热情的用户,我决定体验腾讯云下一代 CDN 服务 - EdgeOne。这款引以为傲的全方位服务如数来到,从域名解析、动静态智能加速到四层加速及DDoS/CC/Web/Bot 防护,一应俱全。随着时代风云变幻,日均数千…

kubernetes1.28版本的二进制安装

前言 二进制部署 Kubernetes(K8s)集群相对于其他部署方式(如基于发行版的包管理器、容器化部署工具等)具有一些优势,主要包括: 灵活性:二进制部署方式更加灵活,您可以根据自己的需…

冯喜运:4.21黄金市场失去正常反应?下周黄金原油解析

【黄金消息面解析 】:周五(4月19日),伊朗媒体似乎淡化了以色列袭击的影响,表明地缘政治风险降低,导致避险资产需求放缓,金价回吐涨幅。本周现货黄金价格上涨超2%。美国黄金期货收盘上涨0.7%,至2413.8美元。…

基于SpringBoot的“火车订票管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“火车订票管理系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 前台首页功能界面图 登录、用…