AOSP 8.0 系统启动之一内核启动

news2024/9/22 5:28:31

目录

 

一、前言

二、涉及源码​​​​​​​

三、源码分析​​​​​​​


一、前言

Android本质上就是一个基于Linux内核的操作系统,与Ubuntu Linux、Fedora Linux类似,我们要讲Android,必定先要了解一些Linux内核的知识。

Linux内核的东西特别多,相关的知识体系许多也不太理解,由于本文主要讲解Android系统启动流程,所以这里主要讲一些内核启动相关的知识。

Linux内核启动主要涉及3个特殊的进程,idle进程(PID = 0), init进程(PID = 1)和kthreadd进程(PID = 2),这三个进程是内核的基础。

  • idle进程是Linux系统第一个进程,是init进程和kthreadd进程的父进程
  • init进程是Linux系统第一个用户进程,是Android系统应用程序的始祖,我们的app都是直接或间接以它为父进程
  • kthreadd进程是Linux系统内核管家,所有的内核线程都是直接或间接以它为父进程

二、涉及源码

init/main.c
kernel/fork.c
kernel/kthread.c
include/linux/kthread.h
kernel/pid.c

三、源码分析

//内核启动的第一行代码
asmlinkage void __init start_kernel(void){
    ......
    rest_init(); //启动内核的剩余部分
}

static noinline void __init_refok rest_init(void)
{
    int pid;
    kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); //创建init进程,此时pid = 1,且init创建之后会调用kernel_init这个函数指针(重点分析)
    pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); //创建kthreadd进;此时pid = 2
    complete(&kthreadd_done); // complete和wait_for_completion是配套的同步机制,跟java的notify和wait差不多,之前kernel_init函数调用了wait_for_completion(&kthreadd_done),这里调用complete就是通知kernel_init进程kthreadd进程已创建完成,可以继续执行

    init_idle_bootup_task(current); // 0号进程进入idle模式;,不会在进程(线程)列表中出现
}

init进程启动分为前后两部分,前一部分是在内核启动的,主要是完成创建和内核初始化工作,内容都是跟Linux内核相关的; 后一部分是在用户空间启动的,主要完成Android系统的初始化工作。

//	1号kernel_init进程完成linux的各项配置(包括启动AP)后,就会在/sbin,/etc,/bin寻找init程序来运行。
//	该init程序会替换kernel_init进程(注意:并不是创建一个新的进程来运行init程序,而是一次变身,使用sys_execve函数改变核心进程的正文段,
//  将核心进程kernel_init转换成用户进程init),
//	此时处于内核态的1号kernel_init进程将会转换为用户空间内的1号进程init。
static int __ref kernel_init(void *unused)
{
    kernel_init_freeable(); //会给ramdisk_execute_command赋值为“/init”
	......
 	if (ramdisk_execute_command) { //ramdisk_execute_command值为/init
		if (!run_init_process(ramdisk_execute_command))
			return 0;
		pr_err("Failed to execute %s\n", ramdisk_execute_command);
	}
	.....

	panic("No init found.  Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.");
}
static noinline void __init kernel_init_freeable(void)
{
    .....
    if (!ramdisk_execute_command)
		ramdisk_execute_command = "/init"
    //根文件系统中是否存在init文件
  	if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
		ramdisk_execute_command = NULL;
		prepare_namespace();
	}
}

static int run_init_process(const char *init_filename)
{
	argv_init[0] = init_filename; 
    // 会将proc/cmdline的内容作为参数,传递给init 进程
    // do_execve 核心的工作就是把文件映射到进程的空间,对于ELF可执行文件会被默认映射0x8048000。
    // 需要动态链接的可执行文件先加载链接器ld​(load _ elf _ interp 动态链接库动态链接文件),动态链接器的起点。如果它是一个静态链接,可直接将文件地址入口进行赋值。
	return do_execve(init_filename,(const char __user *const __user *)argv_init, (const char __user *const __user *)envp_init);
}

目前还在内核空间中,主要是加载init可执行文件,并执行 。

kernel_init主要工作是完成一些init的初始化操作,然后去系统根目录下依次找ramdisk_execute_command和execute_command设置的应用程序,如果这两个目录都找不到,就依次去根目录下找 /sbin/init,/etc/init,/bin/init,/bin/sh 这四个应用程序进行启动,只要这些应用程序有一个启动了,其他就不启动了

ramdisk_execute_command和execute_command的值是通过bootloader传递过来的参数设置的,ramdisk_execute_command通过"rdinit"参数赋值,execute_command通过"init"参数赋值

ramdisk_execute_command如果没有被赋值,kernel_init_freeable函数会赋一个初始值"/init"

四、开启启动参数

节点proc/cmdline,是系统开机的引导参数

节点proc/kmsg 内核日志中,有设备启动的引导参数打印
Kernel command line: earlycon androidboot.selinux=permissive uart_dma keep_dbgclk_on clk_ignore_unused initrd=0xd0000000,38711808 rw crash_page=0x8f040000 initrd=/recoveryrc boot_reason=0x2000 ota_status=0x1001

1、在linux kernel中解析cmdline参数

(以init,rdinit为例)vim kernel/linux/init/main.c (即kernel_init函数所在的文件)

如代码所示__setup是一个宏,如果cmdline中有这个参数,则会执行对应的后面的函数。
下面这两个函数,会将cmdline中解析到的“init=”、“rdinit=”后面的字串写入到execute_command和ramdisk_execute_command全局变量中.
然后在kernel的代码中,就可以使用这两个变量了.

static int __init init_setup(char *str)
{
	unsigned int i;

	execute_command = str;
	/*
	 * In case LILO is going to boot us with default command line,
	 * it prepends "auto" before the whole cmdline which makes
	 * the shell think it should execute a script with such name.
	 * So we ignore all arguments entered _before_ init=... [MJ]
	 */
	for (i = 1; i < MAX_INIT_ARGS; i++)
		argv_init[i] = NULL;
	return 1;
}
__setup("init=", init_setup);

static int __init rdinit_setup(char *str)
{
	unsigned int i;

	ramdisk_execute_command = str;
	/* See "auto" comment in init_setup */
	for (i = 1; i < MAX_INIT_ARGS; i++)
		argv_init[i] = NULL;
	return 1;
}
__setup("rdinit=", rdinit_setup);

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode - 630 课程表Ⅲ

目录 题目来源 题目描述 示例 提示 题目解析 算法源码 题目来源 630. 课程表 III - 力扣&#xff08;LeetCode&#xff09; 题目描述 这里有 n 门不同的在线课程&#xff0c;按从 1 到 n 编号。给你一个数组 courses &#xff0c;其中 courses[i] [durationi, lastDay…

被面试官问住了,MySQL两阶段提交是什么鬼?

前言 MySQL通过两阶段提交的机制&#xff0c;保证了redo log和bin log的逻辑一致性&#xff0c;进而保证了数据的不丢失以及主从库的数据一致。 而说起两阶段提交&#xff0c;就不得不先介绍一下redo log和bin log。 redo log redo log即重做日志&#xff0c;是InnoDB引擎特…

捷报频传 | 中睿天下再获“2022信创产业实干者企业”荣誉称号

近日&#xff0c;国内信创专业媒体“信创产业”正式公布“2022信创产业实干者”申报结果&#xff0c;同期发布信创产业实干者全景图。作为以“实战对抗”为特点的能力价值型网络安全厂商&#xff0c;中睿天下凭借自主研发实力、信创生态兼容性等综合实力&#xff0c;再次入选信…

stm32使用TB6600驱动器控制42BYGH型步进电机

stm32使用TB6600驱动器控制42BYGH型步进电机 stm32使用TB6600驱动器控制42BYGH型步进电机 文章目录stm32使用TB6600驱动器控制42BYGH型步进电机前言一、使用的设备说明介绍24V开关电源TB6600驱动器产品特点技术规格拨码开关设定42BYGH 步进电机接线方法控制步进电机的正反转控…

深度学习与排序模型发展

8.3 深度学习与排序模型发展 学习目标 目标 了解深度学习排序模型的发展应用 无 8.3.1 模型发展 CTR/CVR预估经历了从传统机器学习模型到深度学习模型的过渡。下面先简单介绍下传统机器学习模型&#xff08;GBDT、LR、到深度模型及应用&#xff0c;然后再详细介绍在深度学习…

基于遗传算法的配电网重构研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Android MVVM 开发新姿势 一

Android MVVM 开发新姿势 一 1. 前言 网上有不少关于Android架构的讨论&#xff0c;如MVC&#xff0c; MVP&#xff0c;MVVM&#xff0c;最近还有MVI&#xff0c;emmm…不得不感慨时代变化太快。MVVM出来也有一段很长的时间了&#xff0c;接触时间不长&#xff0c;写一篇文章…

快速入门pandas进行数据挖掘数据分析[多维度排序、数据筛选、分组计算、透视表](一)

1. 快速入门python&#xff0c;python基本语法 Python使用缩进(tab或者空格)来组织代码&#xff0c;而不是像其 他语言比如R、C、Java和Perl那样用大括号。考虑使用for循 环来实现排序算法: for x in list_values:if x < 10:small.append(x)else:bigger.append(x)标量类型 …

uni-app中vant-Weapp组件库的使用

先创建一个基础的uni-app目录从github下载vant包&#xff0c;zip格式的https://github.com/youzan/vant-weapp/releases项目根目录下创建wxcomponents文件夹把我们下好的文件vant-weapp里面只留下dist其余的可以全部删掉&#xff0c;然后把vant-weapp放到 wxcomponents里面App.…

在CentOS-6.9配置apache服务(2)---虚拟目录配置

文章目录一 需求二 系统环境三 基于Alias普通别名3.1 配置个人主页3.2 编写虚拟目录配置文件3.3 测试四 基于ScriptAlias脚本别名4.1 编写主配置文件4.2 创建测试主页4.3 测试一 需求 基于用户个人主页的身份验证&#xff0c;在浏览器输入 10.0.0.100/~a 可以得到用户a的个人网…

Linux:CPU频率调节模式以及降频方法简介

概述 cpufreq的核心功能&#xff0c;是通过调整CPU的电压和频率&#xff0c;来兼顾系统的性能和功耗。在不需要高性能时&#xff0c;降低电压和频率&#xff0c;以降低功耗&#xff1b;在需要高性能时&#xff0c;提高电压和频率&#xff0c;以提高性能。 cpufreq 是一个动态调…

拉伯证券|机构看好中国经济 人民币资产吸引力持续增强

2023年人民币汇率以及A股强势开局。1月以来人民币对美元中心价已累计增值超3%&#xff0c;接连3个月增值。到1月末&#xff0c;北向资金累计净买入额达1311.46亿元&#xff0c;刷新了沪深股通单月净买入新高。 在“真金白银”加仓布局人民币财物的一起&#xff0c;外资组织也纷…

CSS实现9宫格布局的4种方法:flex、float、grid、table布局

一、实现效果及html代码 1、实现效果 2、html代码 <body><div class"container"><div style"background-color: red">1</div><div style"background-color: blue">2</div><div style"background-…

十二、树结构的实际应用—赫夫曼树

1、赫夫曼树 1.1 基本介绍 给定 n 个权值作为 n 个叶子节点&#xff0c;构造一棵二叉树&#xff0c;若该树的带权路径长度&#xff08;wpl&#xff09;达到最小&#xff0c;称这样的二叉树为最优二叉树&#xff0c;也称哈夫曼树&#xff08;Huffman Tree&#xff09;&#xf…

Java工厂模式

定义&#xff1a;将创建对象的权利交给工厂类实现&#xff0c;解耦对象使用者和对象创建过程。 工厂模式有三种&#xff1a; 1、简单工厂模式 2、工厂方法模式 3、抽象工厂模式 使用工厂模式作用&#xff1a; 1、客户类和对象之间的耦合关系转移到了工厂方法和对象之间 …

pl/sql篇之變量的定義

簡述本篇文章主要介紹pl/sql的變量的簡單數據類型&#xff0c;複雜數據類型定義和調用方法&#xff0c;希望能對讀者有些許作用數據類型介紹變量的定義和調用在pl/sql中&#xff0c;定義的變量在聲明之後&#xff0c;可以直接在後續的sql調用&#xff0c;使用上非常方便簡單數據…

图解 MySQL MVCC 实现原理

文章目录MVCC 产生背景InnoDB 引擎表的隐藏列Undo 回滚版本链一致性视图MVCC 实现原理举例说明 MVCC 实现过程MVCC 产生背景 最早的数据库系统,只有读读之间可以并发,读写,写读,写写之间都要阻塞。而 MVCC (Muti Version Concurrency Control) , 是一种多版本并发控制机制。在…

Pandas+Pyecharts | 全国吃穿住行消费排行榜,最‘抠门’的地区居然是北京!!!

文章目录&#x1f3f3;️‍&#x1f308; 1. 导入模块&#x1f3f3;️‍&#x1f308; 2. Pandas数据处理2.1 读取数据2.2 计算各项占比&#x1f3f3;️‍&#x1f308; 3. Pyecharts数据可视化3.1 全国各地区人均收入、消费支出排行榜3.2 全国各地区人均可支配收入地图3.3 全国…

HCIA之ARP协议

ARP协议1、原理2、ARP工作过程3、ARP分类1、原理 根据已知的地址来获取与其对应的另一种地址 2、ARP工作过程 目标MAC全F&#xff0c;对于交换机&#xff0c;会洪泛&#xff1b;对于所有主机&#xff0c;都会以为是找自己的。 发送者PC1&#xff1a;发出广播帧&#xff0c;源I…

大型CRM客户管理系统带小程序、H5 java源码(spring boot 后台 前端vue)

功能介绍 1、系统管理&#xff1a;员工管理、角色管理、菜单管理、部门管理、岗位管理、字典管理、参数设置、日志管理 2、系统监控&#xff1a;在线用户、定时任务、数据监控、服务监控 3、系统工具&#xff1a;表单构建、代码生成、系统接口 4、平台配置&#xff1a;配置…