1,ddr 内存
- DDR 物理基址:
0x00000000 - DDR 容量:
0x08000000,即 128MiB - DDR 物理范围:
0x00000000--0x07FFFFFF - LiteOS 镜像加载/运行地址:
0x00000000 - 若为 MIPS KSEG0 链接,则虚拟地址 = 物理地址 +
0x80000000- 物理
0x00000000↔ KSEG0 虚拟0x80000000 - 物理
0x00320000↔ KSEG0 虚拟0x80320000
- 物理
- 系统启动栈:64KiB
- 系统堆:从
0x00320000到0x07EFFFFF - 顶部保留:1MiB
- 任务栈:默认从系统堆动态分配;也可用静态数组放在
.bss/.data
2. 128MiB DDR 总体物理分布示例
| 物理地址范围 | 大小 | 用途 | 地址来处/查看方式 |
|---|---|---|---|
0x00000000--0x00000FFF |
4KiB | 异常/中断向量表、启动头 | 启动文件、链接脚本 .vectors、liteos.map |
0x00001000--0x000FFFFF |
约 1020KiB | LiteOS .text 代码段 |
链接脚本 .text、_stext/_etext、liteos.map |
0x00100000--0x0017FFFF |
512KiB | .rodata 只读数据、常量、字符串 |
链接脚本 .rodata、readelf -S |
0x00180000--0x001FFFFF |
512KiB | .data 已初始化全局变量/静态变量 |
链接脚本 .data、_sdata/_edata、nm |
0x00200000--0x002FFFFF |
1MiB | .bss 未初始化/零初始化全局变量、静态变量 |
链接脚本 .bss、__bss_start/__bss_end |
0x00300000--0x0030FFFF |
64KiB | 系统启动栈 | 链接脚本 __stack_top/__stack_end、OS_SYS_STACK_SIZE、启动汇编设置 SP |
0x00310000--0x0031FFFF |
64KiB | 保留区:异常栈、启动参数、日志缓冲等 | 板级配置、链接脚本保留段 |
0x00320000--0x07EFFFFF |
约 123.875MiB | LiteOS 系统堆 | 链接脚本 __heap_start/__heap_end、OS_SYS_MEM_ADDR/OS_SYS_MEM_SIZE、LOS_MemInit |
0x07F00000--0x07FFFFFF |
1MiB | 顶部保留:调试、共享内存、异常保存、未来扩展 | 板级保留配置、链接脚本 |
镜像区总计约 3MiB:0x00000000--0x002FFFFF。
系统堆大小:0x07F00000 - 0x00320000 = 0x07BE0000 = 123.875MiB。
3. LiteOS 代码段、运行地址、加载地址
| 项目 | 物理地址示例 | 虚拟地址示例,MIPS KSEG0 | 说明 |
|---|---|---|---|
| LiteOS 加载地址 | 0x00000000 |
0x80000000 |
BootROM/U-Boot 将镜像拷贝到 DDR 的目标地址 |
| LiteOS 运行地址 | 0x00000000 |
0x80000000 |
链接脚本 ORIGIN(RAM) 决定 |
.text 运行地址 |
0x00001000--0x000FFFFF |
0x80001000--0x800FFFFF |
代码段,来源链接脚本 .text |
.text 加载地址 |
通常同运行地址 | --- | 若从 Flash 启动,LMA 在 Flash,启动代码拷贝到 DDR 后运行 |
.rodata 运行地址 |
0x00100000--0x0017FFFF |
0x80100000--0x8017FFFF |
常量、字符串 |
.data 运行地址 |
0x00180000--0x001FFFFF |
0x80180000--0x801FFFFF |
已初始化全局/静态变量 |
.bss 运行地址 |
0x00200000--0x002FFFFF |
0x80200000--0x802FFFFF |
未初始化/零初始化全局/静态变量,不占镜像文件空间 |
MIPS KSEG0 换算:
物理地址 = KSEG0 虚拟地址 - 0x80000000
KSEG0 虚拟地址 = 物理地址 + 0x80000000
例如:
.text 物理 0x00001000 -> KSEG0 虚拟 0x80001000
.bss 物理 0x00200000 -> KSEG0 虚拟 0x80200000
堆 物理 0x00320000 -> KSEG0 虚拟 0x80320000
4. 堆、栈、静态数据、全局变量详细分布
4.1 系统堆
| 项目 | 物理地址 | 说明 |
|---|---|---|
| 系统堆起始 | 0x00320000 |
来自链接脚本 __heap_start 或 OS_SYS_MEM_ADDR |
| 系统堆结束 | 0x07EFFFFF |
来自链接脚本 __heap_end 或 OS_SYS_MEM_ADDR + OS_SYS_MEM_SIZE |
| 堆大小 | 约 123.875MiB |
0x07F00000 - 0x00320000 |
| 初始化函数 | --- | 启动时调用 LOS_MemInit() 初始化该内存池 |
| 动态分配 API | --- | LOS_MemAlloc()、LOS_MemFree()、LOS_MemRealloc() 等 |
系统堆中会存放:
- 任务栈,若由内核动态分配
malloc/LOS_MemAlloc动态内存- 消息队列、信号量、事件控制块等内核对象,若从堆分配
- 动态加载模块、缓存、日志缓冲等
4.2 系统启动栈
| 项目 | 物理地址 | 说明 |
|---|---|---|
| 栈底 | 0x00300000 |
栈区低地址 |
| 栈顶 | 0x00310000 |
初始 SP 通常设为栈顶 |
| 栈大小 | 64KiB |
由 OS_SYS_STACK_SIZE 或链接脚本决定 |
| 增长方向 | 向低地址增长 | ARM/MIPS 常见 ABI |
即:
初始 SP = 0x00310000
栈向下增长到 0x00300000 附近
4.3 任务栈
LiteOS 任务栈有两种方式:
-
动态从系统堆分配
由
LOS_TaskCreate()的uwStackSize指定大小,内核从系统堆分配。此时任务栈物理地址不固定,取决于分配顺序和堆碎片。
-
用户静态数组提供
例如:
static UINT8 g_taskStack[0x2000];该数组位于
.bss或.data,物理地址固定,查liteos.map或nm即可。
动态任务栈示例,仅作地址演示:
| 任务 | 物理地址示例 | 大小 | 初始 SP 示例 |
|---|---|---|---|
| Task A 栈 | 0x00320000--0x00321FFF |
8KiB | 0x00322000 |
| Task B 栈 | 0x00322000--0x00323FFF |
8KiB | 0x00324000 |
| Task C 栈 | 0x00324000--0x00327FFF |
16KiB | 0x00328000 |
注意:这些地址只是"假设从堆起始顺序分配"的示例。实际运行时必须通过:
LOS_TaskInfoGet(taskId, &taskInfo);
或调试器查看任务控制块中的栈指针/栈大小。字段名随 LiteOS 版本略有差异,通常可看到 uwStackSize、uwStackPointer、uwTopOfStack 等信息。
4.4 静态数据、全局变量、常量
| 内容 | 所在段 | 物理地址示例 | 查看方式 |
|---|---|---|---|
常量、字符串、const 全局变量 |
.rodata |
0x00100000--0x0017FFFF |
readelf -S、objdump -h、liteos.map |
| 已初始化全局变量 | .data |
0x00180000--0x001FFFFF |
nm -n liteos.elf、liteos.map |
| 已初始化静态变量 | .data |
同上 | nm、map |
| 未初始化/零初始化全局变量 | .bss |
0x00200000--0x002FFFFF |
__bss_start/__bss_end、nm |
| 未初始化/零初始化静态变量 | .bss |
同上 | nm、map |
函数内 static 变量 |
.data 或 .bss |
由符号地址决定 | nm、map |
| 函数局部变量 | 任务栈 | 运行时 SP 附近 | 调试器看 SP、栈回溯 |
malloc/LOS_MemAlloc 分配的数据 |
系统堆 | 动态 | LOS_MemAlloc 返回值、调试器 |
示例:
g_initialized 在 .data,假设物理地址 0x00181234
g_zero 在 .bss,假设物理地址 0x00201234
g_const 在 .rodata,假设物理地址 0x00101234
查法:
nm -n liteos.elf | grep g_initialized
nm -n liteos.elf | grep g_zero
nm -n liteos.elf | grep g_const
若符号虚拟地址为 0x80181234,MIPS KSEG0 下物理地址为:
0x80181234 - 0x80000000 = 0x00181234
5. LiteOS 地址来处与查看方法
LiteOS 没有 Linux 的 /proc/iomem。要看 LiteOS 的代码段、堆、栈、全局变量物理地址,主要看以下内容。
5.1 链接脚本
常见文件名:
liteos.ld
link.lds
gcc.ld
targets/<board>/link.lds
重点看:
MEMORY
{
RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 0x08000000
}
SECTIONS
{
.text : { ... }
.rodata : { ... }
.data : { ... }
.bss : { ... }
__bss_start = .;
__bss_end = .;
__heap_start = .;
__heap_end = .;
__stack_top = .;
__stack_end = .;
}
这些符号决定:
.text/.rodata/.data/.bss物理地址__heap_start/__heap_end系统堆范围__stack_top/__stack_end系统栈范围
5.2 liteos.map
编译后查看:
cat liteos.map
重点搜索:
_stext
_etext
_sdata
_edata
__bss_start
__bss_end
__heap_start
__heap_end
__stack_top
__stack_end
5.3 ELF 文件
readelf -S liteos.elf
objdump -h liteos.elf
nm -n liteos.elf
size liteos.elf
readelf -S:看各段地址、大小objdump -h:看 VMA/LMAnm -n:看全局变量、静态变量、链接符号地址size:看 text/data/bss 总大小
5.4 配置文件
查看:
los_config.h
target_config.h
menuconfig 配置
重点宏,名称随版本/板级适配层可能不同:
OS_SYS_MEM_ADDR
OS_SYS_MEM_SIZE
OS_SYS_STACK_SIZE
OS_TSK_DEFAULT_STACK_SIZE
LOSCFG_SYS_HEAP_ADDR
LOSCFG_SYS_HEAP_SIZE
系统堆常见初始化形式:
LOS_MemInit((VOID *)__heap_start, __heap_end - __heap_start);
或:
LOS_MemInit((VOID *)OS_SYS_MEM_ADDR, OS_SYS_MEM_SIZE);
5.5 运行时查看
调试器/JTAG/GDB:
p/x &g_initialized
p/x &g_zero
p/x $sp
p/x __heap_start
p/x __heap_end
p/x __stack_top
p/x __stack_end
info symbol 0x00181234
LiteOS shell 常见命令,具体以版本为准:
free
task
mem
stack
可查看系统堆使用、任务栈使用、内存池信息。任务栈运行时地址可通过 LOS_TaskInfoGet() 获取。
6. 地址来处汇总表
| 地址/区域 | 物理地址示例 | 来处与查看方式 |
|---|---|---|
| DDR 基址/容量 | 0x00000000--0x07FFFFFF |
板级 DDR_MEM_BASE/DDR_MEM_SIZE、链接脚本 MEMORY、los_config.h |
| LiteOS 加载地址 | 0x00000000 |
BootROM/U-Boot 加载配置、链接脚本 ORIGIN(RAM) |
| LiteOS 运行地址 | 0x00000000 |
链接脚本 ORIGIN(RAM)、启动入口 |
| 向量表/启动头 | 0x00000000--0x00000FFF |
启动文件、链接脚本 .vectors |
.text |
0x00001000--0x000FFFFF |
链接脚本 .text、_stext/_etext、liteos.map |
.rodata |
0x00100000--0x0017FFFF |
链接脚本 .rodata、readelf -S |
.data 已初始化全局/静态 |
0x00180000--0x001FFFFF |
链接脚本 .data、_sdata/_edata、nm |
.bss 未初始化全局/静态 |
0x00200000--0x002FFFFF |
链接脚本 .bss、__bss_start/__bss_end |
| 系统启动栈 | 0x00300000--0x0030FFFF |
__stack_top/__stack_end、OS_SYS_STACK_SIZE、启动汇编设置 SP |
| 保留区 | 0x00310000--0x0031FFFF |
板级保留、链接脚本保留段 |
| 系统堆 | 0x00320000--0x07EFFFFF |
__heap_start/__heap_end、OS_SYS_MEM_ADDR/OS_SYS_MEM_SIZE、LOS_MemInit |
| 顶部保留 | 0x07F00000--0x07FFFFFF |
板级保留配置、链接脚本 |
| 动态任务栈 | 示例 0x00320000--0x00321FFF |
LOS_TaskCreate 的 uwStackSize、OS_TSK_DEFAULT_STACK_SIZE、LOS_TaskInfoGet |
| 静态任务栈数组 | 在 .bss/.data 内 |
nm、liteos.map |
| 全局变量/静态变量 | .data/.bss 内 |
nm -n liteos.elf、liteos.map |
| 常量/字符串 | .rodata 内 |
readelf -S、objdump -h、map |
| 函数局部变量 | 任务栈内 | 运行时 SP、栈回溯、调试器 |
7. 结论
对于 128MiB DDR、LiteOS 5.0.3.8 的示例布局:
- DDR 物理范围:
0x00000000--0x07FFFFFF - LiteOS 加载/运行物理地址:
0x00000000 .text:0x00001000--0x000FFFFF.rodata:0x00100000--0x0017FFFF.data已初始化全局/静态变量:0x00180000--0x001FFFFF.bss未初始化/零初始化全局/静态变量:0x00200000--0x002FFFFF- 系统启动栈:
0x00300000--0x0030FFFF,初始 SP 约0x00310000 - 保留区:
0x00310000--0x0031FFFF - 系统堆:
0x00320000--0x07EFFFFF,约123.875MiB - 顶部保留:
0x07F00000--0x07FFFFFF
需要特别注意:
- 堆和动态任务栈没有唯一固定物理地址,取决于链接脚本、堆起始地址、分配顺序和任务创建顺序。
- 静态任务栈、全局变量、静态变量有固定物理地址 ,查
liteos.map、nm、readelf即可。 - LiteOS 没有 Linux
/proc/iomem,应看 链接脚本、liteos.map、liteos.elf、los_config.h、调试器和 LiteOS shell。 - 若你的 DDR 基址是
0x80000000,则上表所有物理地址加0x80000000;若为 MIPS KSEG0 链接,则虚拟地址 = 物理地址 +0x80000000。实际以板级链接脚本和los_config.h为准。