Android系统编译之后的打包阶段,会将所有编译出来的有需要的执行文件,库文件以及各种配置文件等打包到各个镜像文件中。有时候我们需要看一下镜像文件中都打包了什么东西,那就可以通过一些方法将其挂载到一个目录,然后进行查看。
一、所用到的工具1.1 simg2img简述:将sparse格式的image文件转化为raw格式的image文件。 编译android源码默认会生成。
路径:out/host/linux-x86/bin/simg2img
如果没有请用如下的指令编出
source build/envsetup.sh lunch miodm_topaz_native-userdebug export OUT_DIR=out && nj simg2img
1.2 lpunpack**简述:**这个工具可以将system.img,product.img,vendor.img等文件从super.img解析出来。
路径:out/host/linux-x86/bin/lpunpack
如果没有请用如 ...
一、前言在面对UEFI阶段代码移植以及开机故障问题,需要对开机启动流程有一定的了解
二、芯片的冷启动Cold boot flow: 冷启动
可以看出,在设备上电后,先跑的是 APPS PBL,接着运行XBL SEC、XBL Loader,通过Loader引出XBL CORE APPSBL,最后进入HLOS
备注:
下面补充点arm架构的知识点,以便可以看懂上图
2.1 异常级别
异常级别
运行的软件
EL0
Application
EL1
Linux kernel- os
EL2
Hypervisor(可理解为上面跑多个虚拟OS)
EL3
Secure Monitor(ARM Trusted Firmware)
ELx(x<4),x越大等级越高,执行特权越高
执行在EL0,称为非特权执行
EL2没有Secure state,只有Non-secure state
EL3 只有Secure state,支持EL0/EL1的Secure 和Non-secure之间的切换
EL0 & EL1 必须要实现,EL2/EL3则是可选实 ...
AArch64执行状态提供了32个在任何时间任何特权级下都可访问的64位的通用寄存器。
每个寄存器都有64位宽,它们通常被称为寄存器X0-X30。
每个AArch64 64位通用寄存器(X0-X30)也具有32位(W0-W30)形式。
32位W寄存器取自相应的64位X寄存器的低32位。也就是说,W0映射到X0的低32位,W1映射到X1的低32位。
从W寄存器读取时,忽略相应X寄存器高32位,并保持其它不变。写入W寄存器时,将X寄存器的高32位设置为零。也就是说,将0xFFFFFFFF写入W0会将X0设置为0x00000000FFFFFFFF。
一、AArch64 特殊寄存器除了31个核心寄存器外,还有几个特殊的寄存器。
注意:没有被称为X31或W31的寄存器。许多指令被编码,例如:31代表零寄存器,ZR(WZR/XZR)。还有一组受限制的指令,其中对一个或多个参数进行编码,使数字31表示堆栈指针(SP)。
当访问零寄存器时,所有写操作都被忽略,所有读操作返回0。请注意,64位形式的SP寄存器不使用X前缀。
在ARMv8体系结构中,当CPU运行在AArch64状态时, ...
参考文档:Armv8-A Instruction Set Architecture.pdf
一、前言Armv8-A 中的指令集 Armv8-A 支持三种指令集:A32、T32 和 A64。
在AArch64执行状态下执行时使用A64指令集。它是一个固定长度的32位指令集。名称中的 “64”指的是 AArch64 执行状态对该指令的使用。它不是指内存中指令的大小。
A32 和 T32 指令集也分别称为“ARM”和“Thumb”。这些指令集在 AArch32 执行状态下执行时使用。在本指南中,我们不介绍 A32 和 T32 指令集。
每个版本的 Arm 架构都有自己的 Arm 架构参考手册(Arm ARM),可以在 Arm 开发者网站上找到。每个Arm ARM都提供了每条指令的详细说明,包括:
编码——指令在内存中的表示。
参数 - 指令的输入。
伪代码 - 指令的作用,以 Arm 伪代码语言表示。
限制 - 当指令不能使用时,或者它可以触发的异常。
A64 的指令描述也以 XML 和 HTML 形式提供。如果您需要经常参考说明,则 XML 和 HTML 格式
非常有用。 XM ...
01、认识一下Git!—简介Git是当前最先进、最主流的 分布式版本控制系统,免费、开源!核心能力就是版本控制。再具体一点,就是面向代码文件的版本控制,代码的任何修改历史都会被记录管理起来,意味着可以恢复到到以前的任意时刻状态。支持跨区域多人协作编辑,是团队项目开发的必备基础,所以Git也就成了程序员的必备技能。
🟢主要特点:
开源免费,使用广泛。
强大的文档(代码)的历史版本管理,直接记录完整快照(完整内容,而非差异),支持回滚、对比。
分布式多人协作的的代码协同开发,几乎所有操作都是本地执行的,支持代码合并、代码同步。
简单易用的分支管理,支持高效的创建分支、合并分支。
Git是Linux之父被迫开发的,为了解决Linux混乱的代码管理而开发的。Linux和Git之父 李纳斯·托沃兹(Linus Benedic Torvalds),来自1969年的芬兰。
02、Git是干什么的?—基础概念先了解下Git的基本概念,及基本框架、工作流程。
2.1、Git概念汇总
概念名称
描述
工作区(Workspace)
就是在电脑里能看到的代码库目录,是我们搬砖的地方,新 ...
缺页异常也叫缺页中断,页错误,是操作系统虚拟内存管理重要的一种机制,属于处理器的同步异常;
访问虚拟内存的时候,虚拟地址和物理地址没有建立映射关系,或者有访问权限错误发生时,会触发缺页异常;
内核必须处理此异常,而且对于进程来说时透明的。
一、缺页异常实现过程缺页异常,属于同步异常,触发时,CPU 会自动跳转到异常向量表;异常向量表入口地址在 arch/arm64/kernel/entry.S
1.1 相关源码文件异常入口:arch/arm64/kernel/entry.Sarm64 架构处理:arch/arm64/mm/fault.c通用代码:mm/memory.c
总体调用过程:
123456789101112131415vectors ///arch/arm64/kernel/entry.S 架构相关->el1_sync->el1_sync_handler->el1_abort->do_mem_abort ///arch/arm64/mm/f ...
一、kmalloc 函数1234567891011121314151617181920static __always_inline void *kmalloc(size_t size, gfp_t flags){if (__builtin_constant_p(size)) {#ifndef CONFIG_SLOB unsigned int index;#endif if (size > KMALLOC_MAX_CACHE_SIZE) return kmalloc_large(size, flags);#ifndef CONFIG_SLOB index = kmalloc_index(size); /// 查找使用的哪个 slab 缓冲区 if (!index) return ZERO_SIZE_PTR; return kmem_cache_alloc_trace( /// 从 slab 分配内存 kmall ...
一、补充点背景知识:
根据不同架构处理器,对内存的访问分为两种方式;a.x86 架构,将外设和普通内存分开,通过专门的 I / O 指令 (IN/OUT) 来访问外设的寄存器,称为“I/ O 地址空间”或“I/ O 端口空间”;
RISC 的 CPU,比如 ARM/PowerPC 等,采用统一编制,即将所有 I / O 外设的内存空间看作普通内存的一部分;
一般外设 I / O 的物理地址是已知的,但是开启 MMU 后,只能通过虚拟地址访问,因此需要将外设地址映射到虚拟地址;
二、ioremap 映射函数常用映射函数有
123#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))#define ioremap_np(add ...
进程是独立的资源空间,每个进程都有自己独立的页表;
用户进程创建页表发生在三个时刻:
创建进程 fork 时;
缺页异常时;
进程切换时;
一、创建进程 fork核心函数
123__do_fork() -->copy_process -->dup_mm()
1.1 dum_mm 函数123456789101112131415161718static struct mm_struct *dup_mm(struct task_struct *tsk, struct mm_struct *oldmm){ struct mm_struct *mm; int err; mm = allocate_mm(); if (!mm) goto fail_nomem; memcpy(mm, oldmm, sizeof(*mm)); if (!mm_init(mm, tsk, mm->user_ns)) /// 分配私有的 pgd 页面 goto fail_nomem; ...
Linux 初始化过程,会依次建立如下页表映射:
恒等映射:页表基地址 idmap_pg_dir;
粗粒度内核镜像映射:页表基地址 init_pg_dir;
fixmap 映射:页表基地址为 init_pg_dir, 待 paging_init 之后为 swapper_pg_end;
细粒度内核镜像映射:页表基地址为 swapper_pg_dir;
线性映射:页表基地址为 swapper_pg_dir;
用户空间页表映射:页表基地址 task->mm->pgd;
上篇解析 “fixmap 映射” , 这里来解析主内核页表的创建, 包括 “细粒度内核镜像映射“ 和 “线性映射“;
创建完固定映射后,会初始化物理页面分配器, 即初始化伙伴系统;有了物理页面分配器,内核主页表就可以建立动态映射页表:
1234567/// 整理 memblock 的内存区域arm64_memblock_init();/// 至此,物理内存通过 memblock 模块添加入了系统,但此时只有 dtb,Image 所在的两端物理内存可以访问;// 其他区域的物理内存,还没建立映射,可以通过 me ...