optee内核中malloc函数的原理介绍
文章目录
- 1、链接文件和汇编文件的对比分析
- 2、malloc和calloc
- 3、optee中的内核栈
★★★ 友情链接 : 个人博客导读首页—点击此处 ★★★
1、链接文件和汇编文件的对比分析
可用查看optee的kern.ld.S文件,和下面的反汇编文件对比.
out/arm-plat-xxxx/core/tee.elf: file format elf64-littleaarch64
out/arm-plat-xxxx/core/tee.elf
architecture: aarch64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000000080020000Program Header:LOAD off 0x0000000000010000 vaddr 0x0000000080020000 paddr 0x0000000080020000 align 2**16filesz 0x0000000000051538 memsz 0x00000000003d0b80 flags rwxSTACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
private flags = 0:Sections:
Idx Name Size VMA LMA File off Algn0 .text 00042e00 0000000080020000 0000000080020000 00010000 2**11 ---------- 代码段CONTENTS, ALLOC, LOAD, READONLY, CODE1 .rodata 0000bd08 0000000080062e00 0000000080062e00 00052e00 2**3CONTENTS, ALLOC, LOAD, READONLY, DATA2 .data 00002538 000000008006f000 000000008006f000 0005f000 2**3CONTENTS, ALLOC, LOAD, DATA3 .bss 00019270 0000000080071540 0000000080071540 00061538 2**5ALLOC4 .heap1 00301850 000000008008a7b0 000000008008a7b0 00061538 2**0 ---------- 堆,malloc就使用的这里的内存ALLOC5 .nozi 00064b80 000000008038c000 000000008038c000 00061538 2**12 ----------non zero initialized, optee的内核栈在这里ALLOC6 .debug_info 000e1253 0000000000000000 0000000000000000 00061538 2**0CONTENTS, READONLY, DEBUGGING7 .debug_abbrev 00023d00 0000000000000000 0000000000000000 0014278b 2**0CONTENTS, READONLY, DEBUGGING8 .debug_loc 000c0b5d 0000000000000000 0000000000000000 0016648b 2**0CONTENTS, READONLY, DEBUGGING9 .debug_aranges 00008110 0000000000000000 0000000000000000 00226ff0 2**4CONTENTS, READONLY, DEBUGGING10 .debug_ranges 0000da30 0000000000000000 0000000000000000 0022f100 2**4CONTENTS, READONLY, DEBUGGING11 .debug_line 00028b2a 0000000000000000 0000000000000000 0023cb30 2**0CONTENTS, READONLY, DEBUGGING12 .debug_str 0001117d 0000000000000000 0000000000000000 0026565a 2**0CONTENTS, READONLY, DEBUGGING13 .debug_frame 00011998 0000000000000000 0000000000000000 002767d8 2**3CONTENTS, READONLY, DEBUGGING
2、malloc和calloc
(1)、malloc和calloc直接调用的mdbg_calloc函数
#define malloc(size) mdbg_malloc(__FILE__, __LINE__, (size))
#define calloc(nmemb, size) \mdbg_calloc(__FILE__, __LINE__, (nmemb), (size))
(2)、malloc_poolset是一个链表,指向内存池,mdbg_malloc从malloc_poolset链表中分配内存
void *mdbg_malloc(const char *fname, int lineno, size_t size)
{struct mdbg_hdr *hdr;uint32_t exceptions = malloc_lock();/** Check struct mdbg_hdr doesn't get bad alignment.* This is required by C standard: the buffer returned from* malloc() should be aligned with a fundamental alignment.* For ARM32, the required alignment is 8. For ARM64, it is 16.*/COMPILE_TIME_ASSERT((sizeof(struct mdbg_hdr) % (__alignof(uintptr_t) * 2)) == 0);hdr = raw_malloc(sizeof(struct mdbg_hdr),mdbg_get_ftr_size(size), size, &malloc_poolset);if (hdr) {mdbg_update_hdr(hdr, fname, lineno, size);hdr++;}malloc_unlock(exceptions);return hdr;
}
(3)、系统开机时,调用malloc_add_pool将堆地址加入到malloc_poolset链表(内存池)
void malloc_add_pool(void *buf, size_t len)
{void *p;size_t l;uint32_t exceptions;uintptr_t start = (uintptr_t)buf;uintptr_t end = start + len;const size_t min_len = ((sizeof(struct malloc_pool) + (SizeQuant - 1)) &(~(SizeQuant - 1))) +sizeof(struct bhead) * 2;start = ROUNDUP(start, SizeQuant);end = ROUNDDOWN(end, SizeQuant);assert(start < end);if ((end - start) < min_len) {DMSG("Skipping too small pool");return;}exceptions = malloc_lock();tag_asan_free((void *)start, end - start);bpool((void *)start, end - start, &malloc_poolset);l = malloc_pool_len + 1;p = realloc_unlocked(malloc_pool, sizeof(struct malloc_pool) * l);assert(p);malloc_pool = p;malloc_pool[malloc_pool_len].buf = (void *)start;malloc_pool[malloc_pool_len].len = end - start;
#ifdef BufStatsmstats.size += malloc_pool[malloc_pool_len].len;
#endifmalloc_pool_len = l;malloc_unlock(exceptions);
}
(4)、系统开机时,将__heap1_start和__heap2_start都加入了malloc_poolset链表(内存池)
static void init_runtime(unsigned long pageable_part)
{.....malloc_add_pool(__heap1_start, __heap1_end - __heap1_start);malloc_add_pool(__heap2_start, __heap2_end - __heap2_start);.....
}
(5)、__heap1_start是在kern.ld.S链接文件中定义的,在conf.mk中定义CFG_CORE_HEAP_SIZE = 3145728
__heap1_start = .;
#ifndef CFG_WITH_PAGER. += CFG_CORE_HEAP_SIZE;
#endif. = ALIGN(16 * 1024);__heap1_end = .;}
(5)、在创建user线程时,也将userspace的堆地址加入到了malloc_poolset链表(内存池)
static TEE_Result init_instance(void)
{trace_set_level(tahead_get_trace_level());__utee_gprof_init();malloc_add_pool(ta_heap, ta_heap_size);_TEE_MathAPI_Init();return TA_CreateEntryPoint();
}
3、optee中的内核栈
通过上述分析,我们知道malloc从堆中分配内存,且堆的大小是固定的,那么除去代码端、section段、堆之后,剩余的空间都是什么呢?
剩余的空间都是.nozi段,optee中的栈就定义在此段,包含stack_tmp、stack_abt、stack_thread栈
- DECLARE_STACK(stack_tmp, CFG_TEE_CORE_NB_CORE, STACK_TMP_SIZE,
static); //aarch32下给atf用的栈 - DECLARE_STACK(stack_abt, CFG_TEE_CORE_NB_CORE, STACK_ABT_SIZE,
static); //异常栈 - DECLARE_STACK(stack_thread, CFG_NUM_THREADS, STACK_THREAD_SIZE,
static); //optee内核栈
该栈定义在nozi_stack栈,而nozi_stack又在nozi段中
#define DECLARE_STACK(name, num_stacks, stack_size, linkage) \
linkage uint32_t name[num_stacks] \[ROUNDUP(stack_size + STACK_CANARY_SIZE, STACK_ALIGNMENT) / \sizeof(uint32_t)] \__attribute__((section(".nozi_stack"), \aligned(STACK_ALIGNMENT)))
.nozi (NOLOAD) : {__nozi_start = .;ASSERT(!(__nozi_start & (16 * 1024 - 1)), "align nozi to 16kB");KEEP(*(.nozi .nozi.*)). = ALIGN(16);__nozi_end = .;__nozi_stack_start = .;KEEP(*(.nozi_stack)). = ALIGN(8);__nozi_stack_end = .;}
optee内核中malloc函数的原理介绍相关推荐
- optee应用程序中malloc函数的原理介绍
文章目录 1.TA的反汇编文件 2.TA中的堆的定义 3.malloc ★★★ 友情链接 : 个人博客导读首页-点击此处 ★★★ TA(trust application)是optee种的应用程序,也 ...
- php new对象 调用函数,关于JS中new调用函数的原理介绍
这篇文章主要介绍了关于JS中new调用函数的原理介绍,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 JavaScript 中经常使用构造函数创建对象(通过 new 操作符调用一个函数) ...
- api中重载函数的原理_小心重载API方法
api中重载函数的原理 重载方法是API设计中的一个重要概念,尤其是当您的API是流利的API或DSL( 特定于域的语言 )时. 对于jOOQ就是这种情况,在这种情况下,您经常想使用与完全相同的方法名 ...
- linux 内核flush,armv8(aarch64)linux内核中flush_dcache_all函数详细分析
/* * __flush_dcache_all() * Flush the wholeD-cache. * Corrupted registers: x0-x7, x9-x11 */ ENTRY( ...
- 【转】malloc函数实现原理!
[转]malloc函数实现原理! https://blog.csdn.net/YEDITABA/article/details/53443792 重载new和delete来检测内存泄漏 posted ...
- Pandas中describe()函数的使用介绍
Pandas中describe()函数的使用介绍 一.describe()函数介绍 pandas 是基于numpy构建的含有更高级数据结构和工具的数据分析包,提供了高效地操作大型数据集所需的工具.pa ...
- 内核中dump_stack的实现原理(3) —— 内核函数printk的实现
参考内核文档: Documentation/printk-formats.txt 在内核中使用dump_stack的时候可以看到如下用法: static inline void print_ip_sy ...
- malloc函数实现原理!
任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至 ...
- 查看内核中每个函数花费的时间 initcall_debug
实现查看内核启动的时候每个函数花费的时间 在uboot的环境变量中 添加如下信息,就可以在内核启动的时候查看到每个函数花费的时间 添加: initcall_debug=1 Linux version ...
最新文章
- iOS Socket Client 通讯
- python正则表达式(三)
- 大数据中台之Kafka,到底好在哪里?
- StringUtils类中 isEmpty() 与 isBlank()的区别
- 用HttpReports快速搭建API分析平台
- Java 高级类(下) —— 内部类和匿名类
- 官宣!“一流大学”,异地落户!
- java cpu高_Java中的CPU占用高和内存占用高的问题排查
- 【数据结构与算法】数据结构与算法基本理论笔记
- leetcode - 343. 整数拆分
- 3个平台下的ffmpeg——ffmpeg编译
- 动态规划:任务调度问题(双塔问题)
- [转帖]2016年时的新闻:ASP.NET Core 1.0、ASP.NET MVC Core 1.0和Entity Framework Core 1.0
- 面试必掌握的Mysql的11个问题
- s3c6410 RTC driver——读取实时时间信息 LDD3 ELDD 学习笔记
- Android单机游戏保存进度,安卓游戏存档修改教程 | 手游网游页游攻略大全
- 思岚A1激光雷达的测试(windows)
- 订餐小项目-(适合公司内部使用)
- Codeforces Raif Round 1 (Div. 1 + Div. 2) 1428D Bouncing Boomerangs 贪心+构造
- 12星座都是什么性格?(python爬虫+jieba分词+词云)
热门文章
- 支付宝回应“崩了”:机房网络出现短暂抖动,已恢复正常
- 综合布线五大技巧与综合布线规范详解
- 数据中心基础架构 22 年演进
- python datetime格式转换_分别用Excel和python进行日期格式转换成时间戳格式
- docker mysql 无权限_Docker 中级篇
- ML之xgboost:绘制xgboost的二叉树graphviz的两种方法代码实现
- Dataset:(公交车、恐龙、大象、花朵、骏马)六类图片数据集(AutoKeras测试)的简介、下载、使用方法之详细攻略
- Py之mglearn:python库之mglearn简介、安装、使用方法之详细攻略
- Python之tkinter:动态演示调用python库的tkinter带你进入GUI世界(text.insert/link各种事件)
- Python之日志处理(logging模块)