虚拟地址空间全景图 从 0x00000000U 至 0xFFFFFFFFU ,外设和主存采用统一编址方式 @note_pic 鸿蒙源码分析系列篇: http://weharmonyos.com | https://my.oschina.net/weharmony +----------------------------+ 0xFFFFFFFFU | IO设备未缓存 | | PERIPH_PMM_SIZE | +----------------------------+ 外围设备未缓存基地址 PERIPH_UNCACHED_BASE | IO设备缓存 | | PERIPH_PMM_SIZE | +----------------------------+ 外围设备缓存基地址 PERIPH_CACHED_BASE | 包括 IO设备 | | PERIPH_PMM_SIZE | +----------------------------+ 外围设备基地址 PERIPH_DEVICE_BASE | Vmalloc 空间 | | 内核栈 内核堆 |内核动态分配空间 | 128M | | 映射区 | +----------------------------+ 内核动态分配开始地址 VMALLOC_START | DDR_MEM_SIZE | | Uncached段 | +----------------------------+ 未缓存虚拟空间基地址 UNCACHED_VMM_BASE = KERNEL_VMM_BASE + KERNEL_VMM_SIZE | 内核虚拟空间 | | mmu table 临时页表 |临时页表的作用详见开机阶段汇编代码注释 | .bss |Block Started by Symbol : 未初始化的全局变量,内核映射页表所在区 g_firstPageTable,这个表在内核启动后更新 | .data 可读写数据区 | | .rodata 只读数据区 | | .text 代码区 | | vectors 中断向量表 | +----------------------------+ 内核空间开始地址 KERNEL_ASPACE_BASE = KERNEL_VMM_BASE | 16M预留区 | +----------------------------+ 用户空间栈顶 USER_ASPACE_TOP_MAX = USER_ASPACE_BASE + USER_ASPACE_SIZE | | | 用户空间 | | USER_ASPACE_SIZE | | 用户栈区(stack) | | 映射区(map) | | 堆区 (heap) | | .bss | | .data .text | +----------------------------+ 用户空间开始地址 USER_ASPACE_BASE | 16M预留区 | +----------------------------+ 0x00000000U 以下定义 可见于 ..\vendor\hi3516dv300\config\board\include\board.h 在liteos_a中, KERNEL_VADDR_BASE 是一个很常用的地址, 可以叫内核的运行起始地址 内核的运行地址就是内核设计者希望内核运行时在内存中的位置,这个地址在内核源码中有地方可以配置, 并且链接脚本里也会用到这个地址,编译代码时所用到的跟地址相关的值都是以内核运行基址为基础进行计算的。 在liteos_a中,内核运行基址是在各个板子的board.h中配置的 #ifdef LOSCFG_KERNEL_MMU #ifdef LOSCFG_TEE_ENABLE #define KERNEL_VADDR_BASE 0x41000000 #else #define KERNEL_VADDR_BASE 0x40000000 #endif #else #define KERNEL_VADDR_BASE DDR_MEM_ADDR #endif #define KERNEL_VADDR_SIZE DDR_MEM_SIZE #define SYS_MEM_BASE DDR_MEM_ADDR #define SYS_MEM_END (SYS_MEM_BASE + SYS_MEM_SIZE_DEFAULT) #define EXC_INTERACT_MEM_SIZE 0x100000 内核空间范围: 0x40000000 ~ 0xFFFFFFFF 用户空间氛围: 0x00000000 ~ 0x3FFFFFFF cached地址和uncached地址的区别是 对cached地址的访问是委托给CPU进行的,也就是说你的操作到底是提交给真正的外设或内存,还是转到CPU缓存, 是由CPU决定的。CPU有一套缓存策略来决定什么时候从缓存中读取数据,什么时候同步缓存。 对unchached地址的访问是告诉CPU忽略缓存,访问操作直接反映到外设或内存上。 对于IO设备一定要用uncached地址访问,是因为你的IO输出操作肯定是希望立即反映到IO设备上,不希望让CPU缓存你的操作; 另一方面,IO设备的状态是独立于CPU的,也就是说IO口状态的改变CPU是不知道,这样就导致缓存和外设的内容不一致, 你从IO设备读取数据时,肯定是希望直接读取IO设备的当前状态,而不是CPU缓存的过期值。
在文件 los_vm_zone.h 中定义.