liteos 内存分布

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 任务栈有两种方式:

  1. 动态从系统堆分配

    由 LOS_TaskCreate() 的 uwStackSize 指定大小,内核从系统堆分配。

    此时任务栈物理地址不固定,取决于分配顺序和堆碎片。

  2. 用户静态数组提供

    例如:

    复制代码
    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/LMA
  • nm -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

需要特别注意:

  1. 堆和动态任务栈没有唯一固定物理地址,取决于链接脚本、堆起始地址、分配顺序和任务创建顺序。
  2. 静态任务栈、全局变量、静态变量有固定物理地址 ,查 liteos.map、nm、readelf 即可。
  3. LiteOS 没有 Linux /proc/iomem,应看 链接脚本、liteos.map、liteos.elf、los_config.h、调试器和 LiteOS shell。
  4. 若你的 DDR 基址是 0x80000000,则上表所有物理地址加 0x80000000;若为 MIPS KSEG0 链接,则虚拟地址 = 物理地址 + 0x80000000。实际以板级链接脚本和 los_config.h 为准。
相关推荐
u0109053591 天前
(永久免费)树莓派 / 香橙派等开发板,安装神卓互联巴比达内网穿透安装教程(Linux ARM 版 V9.4.1)
linux·运维·arm开发
打工仔折腾 AI1 天前
后端部署避坑:吃透IPv4地址、网络接口与CIDR前缀的实际应用
arm开发·人工智能·后端·python·性能优化
工控存储研习2 天前
嵌入式设备启动时间优化:从上电到应用就绪,每一毫秒怎么抠
arm开发
a5986522 天前
云手机怎么选?ARM服务器原生架构和X86模拟器差别很大
服务器·arm开发·智能手机
李某学编程3 天前
基于ARM的微机原理学习笔记(一)
arm开发·笔记·学习
XMAIPC_Robot3 天前
基于 i.MX95 平台在新一代工业控制器中的应用 — 工业车载平板、半导体设备主控方案解析
arm开发·人工智能·机器学习·fpga开发·rk3588+fpga·i.mx95
女神下凡3 天前
芯参谋(71):全桥电机驱动电路设计指南
arm开发·stm32·单片机·嵌入式硬件·硬件工程·设计规范·1024程序员节
szxinmai主板定制专家3 天前
基于 AM62x + Artix-7 的低功耗 ARM+FPGA 平台在轨道交通车门控制中的应用
arm开发·人工智能·fpga开发·zynq·am62x
幻智星科技3 天前
我砍掉了FPGA里的ARM核项目反而提前交付了
arm开发·网络协议·fpga开发·硬件架构