内存布局
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)