对linux预留内存的理解
linux的预留(保留)内存一般是通过3中方式去实现的,分为两类,一种是通过在boot kernel的时候由boot kernel传递bootcmd参数来实现,其依赖与’mem’节点的设置。另一类是设备树的方式来定义预留内存,而设备树又是通过设置
/memreserve/
以及
reserved-memory
这两种属性来设置预留内存的。
1 memreserve
/memreserve/这种方式当前使用的比较少,在xilinx 6.10内核上可以看到有下面这些板卡在使用/memreserve/去定义和声明预留内存。
./arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi:33:/memreserve/ 0x81000000 0x00200000;
./arch/arm64/boot/dts/toshiba/tmpv7708.dtsi:14:/memreserve/ 0x81000000 0x00300000; /* cpu-release-addr */
./arch/arm64/boot/dts/realtek/rtd139x.dtsi:8:/memreserve/ 0x0000000000000000 0x000000000002f000;
./arch/arm64/boot/dts/realtek/rtd139x.dtsi:9:/memreserve/ 0x000000000002f000 0x00000000000d1000;
./arch/arm64/boot/dts/realtek/rtd129x.dtsi:8:/memreserve/ 0x0000000000000000 0x000000000001f000;
./arch/arm64/boot/dts/realtek/rtd129x.dtsi:9:/memreserve/ 0x000000000001f000 0x00000000000e1000;
./arch/arm64/boot/dts/realtek/rtd129x.dtsi:10:/memreserve/ 0x0000000001b00000 0x00000000004be000;
./arch/arm64/boot/dts/freescale/s32v234.dtsi:9:/memreserve/ 0x80000000 0x00010000;
./arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi:12:/memreserve/ 0x80000000 0x00010000;
./arch/arm64/boot/dts/arm/foundation-v8.dtsi:12:/memreserve/ 0x80000000 0x00010000;
./arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts:15:/memreserve/ 0x80000000 0x00010000;
./arch/arm64/boot/dts/arm/fvp-base-revc.dts:15:/memreserve/ 0x80000000 0x00010000;
2 reserved-memory
2.1 description
Reserved memory is specified as a node under the /reserved-memory node. The operating system shall exclude reserved memory from normal usage one can create child nodes describing particular reserved (excluded from normal use)
memory regions. Such memory regions are usually designed for the special usage by various device drivers.
Each child of the reserved-memory node specifies one or more regions of reserved memory. Each child node may either use a ‘reg’ property to specify a specific range of reserved memory, or a ‘size’ property with optional constraints to request a dynamically allocated block of memory.
Following the generic-names recommended practice, node names should reflect the purpose of the node (ie. “framebuffer” or “dma-pool”). Unit address (@
) should be appended to the name if the node is a static allocation.2.2 properties
2.2.1 size
description:
minItems: 1
maxItems: 2
Length based on parent's \#size-cells. Size in bytes of memory to
reserve.
2.2.2 alloc-ranges
description:
Address and Length pairs. Specifies regions of memory that are
acceptable to allocate from.
2.2.3 no-map
type: boolean
description: >
Indicates the operating system must not create a virtual mapping
of the region as part of its standard mapping of system memory,
nor permit speculative access to it under any circumstances other
than under the control of the device driver using the region.
2.2.4 reusable
type: boolean
description: >
The operating system can use the memory in this region with the
limitation that the device driver(s) owning the region need to be
able to reclaim it back. Typically that means that the operating
system can use that region to store volatile or cached data that
can be otherwise regenerated or migrated elsewhere.
2.3 examples
2.3.1 arch/arm64/boot/dts/mediatek/mt8195-demo.dts
- #address-cells = <2>; 表示当前的地址由两个uint32数据组成
- #size-cells = <2>;表示当前的大小是由两个uint32数据组成
- bl31_secmon_reserved: secmon@54600000 声明当前预留内存的用途以及起始地址
- reg = <0 0x54600000 0x0 0x30000>;
0 0x54600000
表示地址,而0x0 0x30000
表示的当前要保留的内存的大小 - no-map;表示当前的内存不能作虚拟映射
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
/* 192 KiB reserved for ARM Trusted Firmware (BL31) */
bl31_secmon_reserved: secmon@54600000 {
no-map;
reg = <0 0x54600000 0x0 0x30000>;
};
/* 12 MiB reserved for OP-TEE (BL32)
* +-----------------------+ 0x43e0_0000
* | SHMEM 2MiB |
* +-----------------------+ 0x43c0_0000
* | | TA_RAM 8MiB |
* + TZDRAM +--------------+ 0x4340_0000
* | | TEE_RAM 2MiB |
* +-----------------------+ 0x4320_0000
*/
optee_reserved: optee@43200000 {
no-map;
reg = <0 0x43200000 0 0x00c00000>;
};
};
2.3.2 arch/arm64/boot/dts/mediatek/mt8173.dtsi
- #address-cells = <2>; 表示当前的地址由两个uint32数据组成
- #size-cells = <2>;表示当前的大小是由两个uint32数据组成
- vpu_dma_reserved: vpu_dma_mem_region@b7000000 声明当前预留内存的用途以及起始地址
- reg = <0 0xb7000000 0 0x500000>;
0 0xb7000000
表示地址,而0 0x500000
表示的当前要保留的内存的大小 - no-map;表示当前的内存不能作虚拟映射
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
vpu_dma_reserved: vpu_dma_mem_region@b7000000 {
compatible = "shared-dma-pool";
reg = <0 0xb7000000 0 0x500000>;
alignment = <0x1000>;
no-map;
};
};
2.3.3 arch/arm64/boot/dts/qcom/msm8996.dtsi
- #address-cells = <2>; 表示当前的地址由两个uint32数据组成
- #size-cells = <2>; 表示当前的大小是由两个uint32数据组成
- hyp_mem: memory@85800000 声明当前预留内存的用途以及起始地址
- reg = <0x0 0x85800000 0x0 0x600000>;
0x0 0x85800000
表示地址,而0x0 0x600000
表示的当前要保留的内存的大小 - no-map; 表示当前的内存不能作虚拟映射
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
hyp_mem: memory@85800000 {
reg = <0x0 0x85800000 0x0 0x600000>;
no-map;
};
xbl_mem: memory@85e00000 {
reg = <0x0 0x85e00000 0x0 0x200000>;
no-map;
};
smem_mem: smem-mem@86000000 {
reg = <0x0 0x86000000 0x0 0x200000>;
no-map;
};
tz_mem: memory@86200000 {
reg = <0x0 0x86200000 0x0 0x2600000>;
no-map;
};
rmtfs_mem: rmtfs {
compatible = "qcom,rmtfs-mem";
size = <0x0 0x200000>;
alloc-ranges = <0x0 0xa0000000 0x0 0x2000000>;
no-map;
qcom,client-id = <1>;
qcom,vmid = <15>;
};
mpss_mem: mpss@88800000 {
reg = <0x0 0x88800000 0x0 0x6200000>;
no-map;
};
adsp_mem: adsp@8ea00000 {
reg = <0x0 0x8ea00000 0x0 0x1b00000>;
no-map;
};
slpi_mem: slpi@90500000 {
reg = <0x0 0x90500000 0x0 0xa00000>;
no-map;
};
gpu_mem: gpu@90f00000 {
compatible = "shared-dma-pool";
reg = <0x0 0x90f00000 0x0 0x100000>;
no-map;
};
venus_mem: venus@91000000 {
reg = <0x0 0x91000000 0x0 0x500000>;
no-map;
};
mba_mem: mba@91500000 {
reg = <0x0 0x91500000 0x0 0x200000>;
no-map;
};
};