内存布局

From 3dbrew
Jump to navigation Jump to search

ARM11物理内存区域[edit]

地址 大小 说明
0x0 0x10000 Bootrom (超私密代码数据 @ 0x8000)
0x10000 0x10000 Bootrom备份
0x10000000 ? IO内存
0x17E00000 0x2000 MPCore私有内存区域
0x18000000 0x600000 VRAM
0x1FF00000 0x80000 DSP内存
0x1FF80000 0x80000 AXI WRAM
0x20000000 0x8000000 FCRAM

硬件内存映射[edit]

ARM11详细物理内存映射[edit]

18000000 - 18600000: VRAM

1FF80000 - 1FFAB000: Kernel code
1FFAB000 - 1FFF0000: SlabHeap [临时装载启动进程]
1FFF0000 - 1FFF1000: ?
1FFF1000 - 1FFF2000: ?
1FFF2000 - 1FFF3000: ?
1FFF3000 - 1FFF4000: ?
1FFF4000 - 1FFF5000: 异常向量表
1FFF5000 - 1FFF5800: Unused?
1FFF5800 - 1FFF5C00: 虚拟地址(VA)FF4xx000对应的256入口L2 MMU表
1FFF5C00 - 1FFF6000: 虚拟地址(VA)FF5xx000对应的256入口L2 MMU表
1FFF6000 - 1FFF6400: 虚拟地址(VA)FF6xx000对应的256入口L2 MMU表
1FFF6400 - 1FFF6800: 虚拟地址(VA)FF7xx000对应的256入口L2 MMU表
1FFF6800 - 1FFF6C00: 虚拟地址(VA)FF8xx000对应的256入口L2 MMU表
1FFF6C00 - 1FFF7000: 虚拟地址(VA)FF9xx000对应的256入口L2 MMU表
1FFF7000 - 1FFF7400: 虚拟地址(VA)FFAxx000对应的256入口L2 MMU表
1FFF7400 - 1FFF7800: 虚拟地址(VA)FFBxx000对应的256入口L2 MMU表
1FFF7800 - 1FFF7C00: 是MMU表但是好像没使用?
1FFF7C00 - 1FFF8000: 虚拟地址(VA)FFFxx000对应的256入口L2 MMU表
1FFF8000 - 1FFFC000: 虚拟地址(VA)xxx00000对应的4096入口L1 MMU表(CPU 0 or 1)
1FFFC000 - 20000000: 虚拟地址(VA)xxx00000对应的4096入口L1 MMU表(CPU 1 or 0)
20000000 - 28000000: 主内存

ARM11详细虚拟内存映射[edit]

E8000000 - E8600000: 映射到VRAM (18000000 - 18600000)

EFF00000 - F0000000: 映射到内部内存(1FF00000 - 20000000)
F0000000 - F8000000: 映射到主内存

FF401000 - FF402000: 映射到 ? (27FC7000 - 27FC8000)

FF403000 - FF404000: 映射到 ? (27FC2000 - 27FC3000)

FF405000 - FF406000: 映射到 ? (27FBB000 - 27FBC000)

FF407000 - FF408000: 映射到 ? (27FB3000 - 27FB4000)

FF409000 - FF40A000: 映射到 ? (27F8E000 - 27F8F000)

FFF00000 - FFF45000: 映射到SlabHeap 

FFF60000 - FFF8B000: 映射到内核代码

FFFCC000 - FFFCD000: 映射到IO I2C second bus (10144000 - 10145000)

FFFCE000 - FFFCF000: 映射到IO PDC (10400000 - 10401000)

FFFD0000 - FFFD1000: 映射到IO PDN (10141000 - 10142000)

FFFD2000 - FFFD3000: 映射到IO PXI (10163000 - 10164000)

FFFD4000 - FFFD5000: 映射到IO PAD (10146000 - 10147000)

FFFD6000 - FFFD7000: 映射到IO LCD (10202000 - 10203000)

FFFD8000 - FFFD9000: 映射到IO ? (10140000 - 10141000)

FFFDA000 - FFFDB000: 映射到IO XDMA (10200000 - 10201000)

FFFDC000 - FFFE0000: 映射到 ? (1FFF8000 - 1FFFC000)

FFFE1000 - FFFE2000: 映射到 ? (1FFF0000 - 1FFF1000)

FFFE3000 - FFFE4000: 映射到 ? (1FFF2000 - 1FFF3000)

FFFE5000 - FFFE9000: 映射到虚拟内存(VA)xxx00000的L1 MMU表

FFFEA000 - FFFEB000: 映射到 ? (1FFF1000 - 1FFF2000)

FFFEC000 - FFFED000: 映射到 ? (1FFF3000 - 1FFF4000)

FFFEE000 - FFFF0000: 映射到IO中断 (17E00000 - 17E02000)

FFFF0000 - FFFF1000: 映射到异常向量表

FFFF2000 - FFFF6000: 映射到虚拟内存(VA)xxx00000的L1 MMU表

FFFF7000 - FFFF8000: 映射到 ? (1FFF1000 - 1FFF2000)

FFFF9000 - FFFFA000: 映射到 ? (1FFF3000 - 1FFF4000)

FFFFB000 - FFFFE000: 映射到L2 MMU表(1FFF5000 - 1FFF8000)

ARM11用户空间内存区域[edit]

虚拟基地址 物理基地址 分区最大大小 描述
0x00100000 / 0x14000000 0x03F00000 ExeFS:/.code会装载到这里,可执行文件必须在exheader "special memory"标志清零前加载到0x00100000区域。 只有当标志清零后才会有0x03F00000字节大小的限制。当exheader "special memory"置数时,可执行文件一般会加载到0x14000000,其实这个地址可以任意。
0x08000000 用于应用程序的FCRAM和GSP的堆大小 0x08000000 内存控制映射的堆
0x10000000-栈大小 .bss物理地址- 总栈页面 从进程exheader获得的栈大小 主线程的栈,被ARM11内核初始化。exheader中的栈大小一般是0x4000,而栈底常是0x0FFFC000。其他线程的栈一般定位到进程的.data位置,不过可以随意。
0x10000000 0x04000000 共享内存
0x14000000 FCRAM+0 0x08000000 可以用内存控制映射,这是用于应用程序的GSP的堆。
0x1EC00000 0x10100000 0x01000000 IO寄存器,是每个进程都可以在CXI中指定访问的IO映射页面。(应用程序一般没有在此范围寄存器的访问权限)
0x1F000000 0x18000000 0x00600000 VRAM,用exheader指定访问权限。
0x1FF00000 0x1FF00000 0x00080000 DSP内存,用exheader指定访问权限。
0x1FF80000 0x1000 设置信息内存,任何进程都对这里有访问权限,但是需要在exheader "Shared page writing"标记指定页面的写权限。
0x1FF81000 0x1000 共享页面,访问方式和0x1FF80000相同。

所有的可执行页面都是只读的,数据页面则有不可许可执行的标记。一般的,ExeFS:/.code里面的.text只能映射到可执行内存。可执行文件的CROs可以被装载到内存,一旦装载完CRO的.text区域,内存页面的权限就被控制进程内存从RW-改到R-X。每个ExeFS:/.code区域的地址和大小都在exheader里面,对应各个区域的权限是:.text R-X, .rodata R--, .data RW-, and .bss RW-。装载过的.code会被ARM11内核根据exheader中指定的地址映射。栈的权限被ARM11内核初始化为RW-。堆的权限一般是RW-。

所有用户空间的内存都在特权模式下映射为RW权限。不过一般ARM11内核访问内存根据SVCs的指定,只用用户空间读写指令(或者检查内存可以先从用户空间写入)。

低于0x20000000的虚拟内存是进程独立的,进程不能直接访问其他进程的内存。从0x20000000开始的内存只有在特权模式下才能访问。当调用服务命令时,内核会映射目标进程的内存作为IO缓冲区,将进程接到的命令地址替换为这个映射内存。如果是一块输入缓冲,缓冲数据会复制到映射内存。如果是输出缓冲,在映射内存中存储的数据会复制到命令指定的目标缓冲区。

应用程序内存类型的内存物理地址会映射到FCRAM+0,总共为此内存类型分配的内存会存储到设置信息内存。低于应用程序内存类的应用程序的exefs:/.code 会映射到FCRAM + APPMEMALLOC - exefs:/.code大小,根据页面大小向上对齐。应用程序的.bss会映射到CODEADDR - .bss大小, 根据页面大小向下对齐。当应用程序的exefs:/.code,.bss和栈都被映射后,APPMEMALLOC会设置为APPMEMALLOC - (栈大小 + bss大小 + code大小),将栈大小,bss大小,code大小都对齐到页面大小。

系统内存细节[edit]

0xFFFF9004是指向当前KProcess示例的指针。

句柄[edit]

句柄0xFFFF8001是到当前KProcess的引用。

运行网络浏览器时候的VRAM映射[edit]

  • 0x1e6000-0x22C500 -- 上屏幕帧缓冲0(240x400x3)
  • 0x22C800-0x272D00 -- 上屏幕帧缓冲1(240x400x3)
  • 0x273000-0x2B9500 -- 上屏幕帧缓冲2(240x400x3)
  • 0x2B9800-0x2FFD00 -- 上屏幕帧缓冲3(240x400x3)
  • 0x48F000-0x4C7400 -- 下屏幕帧缓冲0(240x320x3)
  • 0x4C7800-0x4FF800 -- 下屏幕帧缓冲1(240x320x3)