【Android】Android中的系统镜像由什么组成?
文章目录
- 总览
- Boot Loader 的加锁与解锁
- Boot 镜像
- 内核
- RAM disk
- ARM 中的设备树 (Device Tree)
- /System 和/Data 分区镜像
- 参考
总览
各种Android设备都只能刷专门为相应型号的设备定制的镜像。
厂商会提供一套系统镜像把它作为“出厂默认”的 Android 系统刷在设备上。
一个完整的系统镜像是由以下几个文件组成的,刷机时它们会被写入各自对应的分区中。
- Boot Loader:
其中含有在启动阶段由应用处理器 (application processor)执行的代码。这些代码一般是用来寻找和加载 boot 镜像的,但同时也被用来进行固件升级和让系统启动到recovery模式下。大多数 Boot Loader 还会实现一个小小的USB栈(USB stack),通过它,用户在电脑上就可以控制启动和升级过程,通常是通过 fastboot。Boot Loader会被刷到“aboot”分区里去。 - boot镜像:
它一般是由内核和 RAM disk 组成的,作用是加载系统。假设启动正常,RAM disk 会被 Android 用作 root 文件系统,其中的/init.rc
及相关文件规定了系统余下的其他部分该如何被加载。boot 镜像会被刷到“boot”分区里去。 - recovery镜像:
这个镜像同样是由内核和(另一个)RAM disk 组成的,一般用来在正常启动失败或者通过 OTA 升级时,把系统加载到“recovery 模式”。这个镜像会被刷到“recovery”分区上。 - /system 分区镜像:
这里存放的是一个完整的 Android 系统,其中除了谷歌提供的二进制可执行文件和框架(framework) 之外,还有厂商或运营商提供的类似的东西。 - /data 分区镜像:
这里存放的是“默认出厂设置”的数据文件,它们是/system 分区中程序正常运行所必需的文件。当手机需要重置到“出厂状态”时,也只需把这个分区镜像刷写到/data 分区,覆盖掉原来的数据即可。
Boot Loader 的加锁与解锁
Android 设备上的 Boot Loader 一般都会被加锁。也就是说,如果数字签名验证没有通过,手机/平板电脑会拒绝刷机或用更新的镜像启动。厂商会在 ROM 中提供他们的公钥,该密钥被用来建立一条贯穿启动过程始终的信任链。这样,所有的启动组件(从rpm到 sbl再到Android Boot Loader)就都可以被验证 (是否来自厂商或有无遭到修改)了。对这些组件的逆向分析表明,其中都有一个X.509v3 的证书,以及验证密钥时所必需的 OpenSSL 相关代码。
被解锁之后(如果可能的话), Boot Loader 就能完全控制/data 分区中的信息。所以解锁 BootLoader 会从根本上危及手机的安全性,因为攻击者拿到手机之后,就能给手机刷一个能绕过用户的开机密码或者锁屏图案的恶意更新包,或者把/data 分区中的数据复制出来,把里面的所有个人信息全部偷走。
如果 BootLoader 不能解锁,那么至少从理论上说,只要不被 root,手机就是安全的。不过在实践中,Android 也并不是不存在能够 root 它的漏洞。事实上,任何一个 3.13 及以后版本的Linux内核漏洞利用代码都有可能被用来 root Android 系统。著名的“TowelRoot”(这个漏洞利用代码是由 GeoHot 公开的)会影响到目前市场上销售的所有 Android 设备,而这还只是好几个般被称为“一键 root”(相当于 iOS 中的越狱程序)的漏洞利用程序中的一个。
Boot 镜像
Android 的 Boot 镜像中存储的是操作系统的核心组件,包括内核和 RAM disk。此外,Boot镜像(它是由Android 源码树中的 mkbootimg 创建的)的组成部分还有一个很小的头部、内核命令行、一个 Hash以及一个可选的(在实践中并不使用的)二级启动加载器。
所有这些组件都是闪存页边界(通常为2KB)对齐的。Boot 镜像可以用它的文件签名“ANDROID!”予以识别,这和上文中我们可以用Boot Loader 的文件签名“BOOTLDR!”识别 Boot Loader 的原理是一样的。
内核
与大多数操作系统的内核不同,Linux 的内核大多是经过压缩的。内核镜像文件格式(也被称为 zImage 格式)规定,其中必须含有用来把内核镜像中其他经过压缩的部分解压到内存中去的自解压代码。由于不同压缩算法各有所长,所以可选的压缩算法也有好几个,具体使用哪种算法是在 build 内核的过程时 (make config)决定的,如图:
内核总是会先运行自解压代码,这也就意味着,我们得先搜索一下文件,找到压缩算法的签名。传统上,大多数ARM 内核使用的都是 zmage,尽管严格意义上说并不一定要这样做。
内核是 Android 系统中与体系结构最为紧密相关的部分。尽管其他的一些组件也需要关心处理器的类型 (系统中使用的到底是 ARM、Intel 还是 MIPS 处理器),但是内核还要关心主板类型和芯片组的型号。因为事实上,移动设备的处理器是个单晶片系统(SoC,System-on-Chip,它由一组芯片构成),其中还含有其他芯片,内核也必须为这些芯片提供专用的驱动。这些驱动是源码树的一部分,谷歌为不同的芯片组提供了不同的内核设备树 (device tree)。
RAM disk
Boot或recovery 镜像的另一个组件就是“initialRAM disk”,它通常也被简称为initrd。RAMdisk 提供了最初的文件系统,在操作系统启动时,它被用作根文件系统(/)。它会和内核一起被 BootLoader 预加载到 RAM (也就是内存,所以得名 RAM disk)中去,所以是可以直接访问而不需要经过任何特殊的驱动的。
这并不是一个 Linux 特性,我们知道,在其他一些 UNIX 系统中也使用它,其中最著名的当属iOS 了,尽管 iOS 中是把它和
kernel cache 并排放在ipsw 系统镜像里的。
传统上,initramfs 是用来提供内核操作时所需的相关设备的驱动程序的。在它的帮助下,Linux 发行版本才能提供一个通用的、相对紧凑的内核,并在最开始安装的过程中,把所需的驱动打包放进一个单独的文件中。
为了解开“先有鸡还是先有蛋”,即加载驱动先要能访问存储器,而要能访问存储器又先要有存储器的驱动这个死结,一些关键的必备驱动会被打包放在 intramfs 中。这样,内核就能直接在 RAM中访问到它们了。initramfs 中还含有一个启动程序/init,内核会把它作为系统中的第一个进程(PID=1)运行起来,用于完成一些需要在用户模式 (user mode) 下执行的初始启动操作,比如加载模块。
当RAM disk 的操作完成之后,Linux 通常都会丢弃掉它,以便使用磁盘上的文件系统,用一个通常被称为“pivoting root”的进程。
但在Android 中,initramfs 却还是会被保留在内存中用来提供根文件系统(/)。由于其中的文件会被经常访问,而且 RAM disk 本身所占的内存空间也非常的小,所以这样做还是很有用的。此外,这么做也使得修改根文件系统的难度变得更大了一些,因为 Boot 镜像是有数字签名保护的。
Linux支持两种文件格式的RAM disk–initrd (ext4文件系统镜像)和initramfs (CPIO文件)。后者更为常用,不过常常也会被称为 imitrd。CPIO 文档是一种只需占用很少内存空间的简单格式。为了进一步节省空间,该文档还会经过 gzip 压缩(内核是支持 zlib 的,因为内核要用它把自己解压出来)。
根据相关规定,内核在被压缩之后会和 RAM disk 一起放在一个单独的分区中。这背后有一个非常重要的设计思想,就是把两个东西打包在一起,只要用一个数字签名,就能同时保护这两个东西。
即,只要应用一次防篡改措施,就能保护两者都不会被篡改。内核当然是系统的关键组件,但 RAM disk 也是非常重要的,其中的/init 及其对应的/init.rc 文件控制着系统的启动过程。/init 会以 root 权限启动,负责启动所有其他的系统组件,只要修改一下/init.rc 文件就能获取设备的 root 访问权限,但只要搞不定数字签名,这一切就是水中花,井中月。
ARM 中的设备树 (Device Tree)
大多数ARM内核需要靠设备树 (device tree)文件向内核提供硬件设备定义的相关信息这个文件提供了设备相互连接的层次关系,使得内核能够据此启动相应的设备。
设备树文件一般会被附加在内核镜像的尾部,但有时也会为它专门分配一个分区。
设备树是一个二进制的 blob 文件,可以通过它的文件签名 0xd0dfeed 予以识别。
“Blob” 一词通常用来指代二进制大型对象(Binary Large Object),是一种存储二进制数据的数据类型。在计算机领域中,“blob” 可以表示任意类型的二进制数据,如图像、音频、视频等。这个术语通常用于描述数据库中存储的非结构化数据。
另外,在编程和计算机科学中,“blob” 也可能指代内存中的一块连续的二进制数据块,通常用来存储临时数据或需要以原始形式处理的数据。
/System 和/Data 分区镜像
因为厂商可以提供自己专门开发的分区刷写工具,所以,用哪种镜像文件格式存储它们完全可以由厂商自己说了算。不过由于大多数厂商使用的还都是 fastboot,所以他们很可能也就沿用了谷歌在自己的镜像上使用的 simg(sparseimage)格式。能处理这种文件格式的实用程序可以在AOSP的system/core/libsparse
目录下找到。
参考
《最强Android书:架构大剖析》
相关文章:

【Android】Android中的系统镜像由什么组成?
文章目录 总览Boot Loader 的加锁与解锁Boot 镜像内核RAM diskARM 中的设备树 (Device Tree) /System 和/Data 分区镜像参考 总览 各种Android设备都只能刷专门为相应型号的设备定制的镜像。 厂商会提供一套系统镜像把它作为“出厂默认”的 Android 系统刷在设备上。 一个完…...

仿真机器人-深度学习CV和激光雷达感知(项目2)day7【ROS关键组件】
文章目录 前言Launch 文件了解 XML 文件Launch 文件作用Launch 文件常用标签实例--作业1的 Launch 文件TF Tree介绍发布坐标变换--海龟例程获取坐标变换--海龟自动跟随例程rqt_工作箱前言 💫你好,我是辰chen,本文旨在准备考研复试或就业 💫本文内容是我为复试准备的第二个…...

解锁一些SQL注入的姿势
昨天课堂上布置了要去看一些sql注入的案例,以下是我的心得: 1.新方法 打了sqli的前十关,我发现一般都是联合查询,但是有没有不是联合查询的方法呢…...

Qt 拖拽事件示例
一、引子 拖拽这个动作,在桌面应用程序中是非常实用和具有很友好的交互体验的。我们常见的譬如有,将文件拖拽到某个窗口打开,或者拖拽文件到指定位置上传;在绘图软件中,选中某个模板、并拖拽到画布上,画布上变回绘制该模板的图像… 诸如此类,数不胜数。 那么,在Qt中我…...

Linux:命名管道及其实现原理
文章目录 命名管道指令级命名管道代码级命名管道 本篇要引入的内容是命名管道 命名管道 前面的总结中已经搞定了匿名管道,但是匿名管道有一个很严重的问题,它只允许具有血缘关系的进程进行通信,那如果是两个不相关的进程进行通信࿰…...

实习记录——第五天
今天我的心情不是很美丽,昨天晚上没怎么睡好,因为我一直在想离不离开实验室?该怎么说的事情?但是又觉得这个项目还没有完全结束,冒昧提这个事情是不是不好?最终也没得出一个结论,晚上睡得也不踏…...

Kotlin 教程(环境搭建)
Kotlin IntelliJ IDEA环境搭建 IntelliJ IDEA 免费的社区版下载地址:Download IntelliJ IDEA – The Leading Java and Kotlin IDE 下载安装后,我们就可以使用该工具来创建项目,创建过程需要选择 SDK, Kotlin 与 JDK 1.6 一起使…...

04.领域驱动设计:了解聚合和聚合根,怎样设计聚合-学习总结
目录 1、概述 2、聚合 3、聚合根 4、怎么设计聚合 4.1 聚合的构建过程主要步骤 第 1 步:采用事件风暴。 第 2 步:选出聚合根。 第 3 步:找出与聚合根关联的所有紧密依赖的实体和值对象。 第 4 步:画出对象的引用和依赖模型…...

cmake-find_package链接第三方库
文章目录 基本调用形式和模块模式使用方式 之前我们是使用了绝对路径来链接OpenCV第三方库,但是现在很多库一般会自己写一些cmake文件提供给用户,用户可以直接使用其中的内置变量即可。使用的命令就是find_package。 基本调用形式和模块模式 find_packa…...

obsidian阅读pdf和文献——与zotero连用
参考: 【基于Obsidian的pdf阅读、标注,构建笔记思维导图,实现笔记标签化、碎片化,便于检索和跳转】 工作流:如何在Obsidian中阅读PDF - Eleven的文章 - 知乎 https://zhuanlan.zhihu.com/p/409627700 操作步骤 基于O…...

走方格(动态规划)
解题思路: 找边界,即行为1,列为1。 拆分问题,拆分成一次走一步,只能向右或者向下走。 解题代码: public static void main(String[] args) {int [][]arrnew int[31][31];Scanner scnew Scanner(Sys…...

基于DataKit迁移MySQL到openGauss
📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…...

API网关-Apinto压缩包方式自动化安装配置教程
文章目录 前言一、Apinto安装教程1. 复制脚本2. 增加执行权限3. 执行脚本4. Apinto命令4.1 启动Apinto4.2 停止Apinto4.3 重启Apinto4.4 查看Apinto版本信息4.5 加入Apinto集群4.6 离开Apinto集群4.7 查看Apinto节点信息 5. 卸载Apinto 二、Apserver(Apinto Dashboard V3)安装教…...

内网穿透natapp使用教程(Linux)
我的使用场景:在家访问学校服务器,由于不在一个局域网,所以需要使用内网穿透,我使用的是natapp。需要在有局域网的时候做好以下步骤。 (natapp官网:https://natapp.cn/) 1. 下载客户端 &#x…...

php函数 二
一 字符串包含 1.1 str_starts_with(string $haystack, string $needle) php8版本中新函数。 检查字符串是否以指定子串开头,区分大小写。返回布尔值。 $haystack待判断的字符串,$needle需要查询的内容。 function test1() {$str "Qwe asd zx…...

IDC机房交换机核心技术与应用指南
IDC机房交换机核心技术与应用指南 在这个快速发展的数字时代,数据中心作为信息技术的心脏,不仅承载着海量数据的处理、存储和传输,更是支撑着全球企业运营和互联网服务的关键基础设施。在众多构成数据中心的组件中,IDC机房交换…...

Compose | UI组件(五) | Button 按钮组件
文章目录 前言Button 是什么?Button的创建Button显示水平方向的UI IconButton是什么?IconButton是创建 FloatingActionButton是什么?FloatingActionButton创建 ExtendedFloatingActionButton是什么? 总结 前言 随着移动端的技术不…...

【leetcode刷刷】235. 二叉搜索树的最近公共祖先 、701.二叉搜索树中的插入操作 、450.删除二叉搜索树中的节点
235. 二叉搜索树的最近公共祖先 class Solution:def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:# 递归if not root: return if root.val p.val: return pif root.val q.val: return qleft Noneright Noneif root.val > p.…...

YoloV8改进策略:BackBone改进|DCNv4最新实践|高效涨点|多种改进教程|完整论文翻译
摘要 涨点效果:在我自己的数据集上,mAP50 由0.986涨到了0.993,mAP50-95由0.737涨到0.77,涨点明显! DCNv4是可变形卷积的第四版,速度和v3相比有了大幅度的提升,但是环境搭建有一定的难度,对新手不太友好。如果在使用过程遇到编译的问题,请严格按照我写的环境配置。 …...

高中数学常识
一、大小关系 |x| > |sinx| 理由: 很明显,在圆内,弧长x>垂线sinx 3x、2x 、 1 2 \frac{1}{2} 21x 理由: log 1 2 _\frac{1}{2} 21x、log 2 _2 2x、 log 3 _3 3x 二、(xy)? 的求法 利用二项式定理 三、平…...

docker之部署青龙面板
青龙面板是一个用于管理和监控 Linux 服务器的工具,具有定时运行脚本任务的功能。在实际情况下也可以用于一些定期自动签到等任务脚本的运行。 本次记录下简单的安装与使用,请提前安装好docker,参考之前的文章。 一、安装部署 1、拉取镜像 # …...

Type-C平板接口协议芯片介绍,实现单C口充放电功能
在现代平板电脑中,Type-C接口已经成为了一个非常常见的接口类型。相比于传统的USB接口,Type-C接口具有更小的体积、更快的传输速度和更方便的插拔体验。但是,在使用Type-C接口的平板电脑上,如何实现单C口充电、放电和USB2.0数据传…...

系统架构演变
1.1系统架构的演变 2008年以后,国内互联网行业飞速发展,我们对软件系统的需求已经不再是过去”能用就行”这种很low的档次了,像抢红包、双十一这样的活动不断逼迫我们去突破软件系统的性能上限,传统的IT企业”能用就行”的开发思…...

Oracle PL/SQL Programming 第2章:Creating and Running PL/SQL Code 读书笔记
总的目录和进度,请参见开始读 Oracle PL/SQL Programming 第6版 暂不考虑系统设计或单元测试之类的任务,所有 PL/SQL 程序员必须熟悉的基本操作任务包括: 浏览数据库创建和编辑 PL/SQL 源代码编译 PL/SQL 源代码,并更正编译器注…...

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Swiper容器组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Swiper容器组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Swiper容器组件 滑块视图容器,提供子组件滑动轮播显示的能力。…...

『建议收藏』OpenAI官方出的Prompt提示词教程中文版来了!
一些结论 六大策略: 写清晰的指令 提供参考文本 将复杂任务分解为更简单的子任务 给模型时间“思考” 使用外部工具 系统性测试变化 提高结果质量的六大策略 写清晰的指令 这些模型无法读懂你的想法。如果输出过长,要求简短回复;如果输出过于简单…...

牛刀小试 - C++ 推箱子小游戏
参考文档 C笔记:推箱子小游戏 copy函数 memcpy()函数用法(可复制数组) 使用memcpy踩出来的坑,值得注意 完整代码 /********************************************************************* 程序名:推箱子小游戏 说明&#x…...

手机视频压缩怎么压缩?一键瘦身~
现在手机已经成为我们日常生活中必不可少的工具,而在手机的应用领域中,文件的传输和存储是一个非常重要的问题。很多用户都会遇到这样一个问题,那就是在手机上存储的文件太多太大,导致手机存储空间不足,那么怎么在手机…...

目标主力能源:华为智能光伏的时代指南针
让新能源成为人类主要的能源来源,是实现“双碳目标”的核心方案。而光伏能源则是目前新能源体系中的主要选择之一。以光伏为核心构建新型电力系统,让光伏能源成为主力能源值得关注和期待。 过去几年,光伏能源极速发展。但如何百尺竿头更进一步…...

每日一题 力扣2846 边权重均等查询
2846. 边权重均等查询 题目描述: 现有一棵由 n 个节点组成的无向树,节点按从 0 到 n - 1 编号。给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] [ui, vi, wi] 表示树中存在一条位于节点 ui 和节点 vi 之间、权重…...