This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] AM62A7: How do I update the AM62A memory map?

Part Number: AM62A7

Q: The default memory map for AM62A does not work for my application. How do I modify the RAM / DDR memory map to suit my module size and application?

  • I see this question fairly often for developers working towards their production application. Let me start with the fundamentals of this task

    The memory map of this device may require modification for a few reasons:
    1. Fit all runtime memory into a smaller DDR module, e.g. 2 GB
    2. The application requires a lot of memory because it has large AI models, large images, many processing elements, and so on.
    The regions of the memory map can be optimized for your application. Let's go into this topic

    What is the memory map in this context?

    The AM62A memory map defines how DDR memory is partitioned and allocated across multiple cores and hardware accelerators in the system. It encompasses:
    • Shared memory regions for inter-processor communication (IPC) and data exchange
    • Hardware accelerator heaps for ISP, MSC, LDC (VPAC); C7 NPU
    • Firmware code and data sections for remote cores the same remote cores
    • TIOVX framework memory for cross-SOC meta data, logging and traces in the TI's OpenVX implementation
    The memory map ensures that each processor and hardware component has dedic`ated, non-overlapping memory regions with proper alignment and cache settings that matches the data access patterns. We will primarily focus on Linux as the high-level OS for this FAQ.

    Generally, only the sections for shared memory and accelerator heaps should be modified. These consistent of the upper range of the first 1GB of memory. As a result, it is simple to convert the default 4 GB from the SDK and EVM into a 1 GB map by only changing Linux device tree. If shared memory or core heaps are not enough (e.g. for multiple large AI models or complex vision pipelines on larger resolutions), then changing the shared region and heaps may be required.
     

    Where Does the Memory Map Take Effect?

    The memory map configuration affects multiple components across the system:

    DM R5F Core Firmware
    • Bootloader (tiboot3.bin): Located in BOOT partition, boots the device and includes the remote core firmware that will run after the bootloader finishes
    • Remote core firmware: Defines code, data, and heap sections for the R5F processor used in TIOVX (and by extension, GStreamer) applications
    • IPC buffers: Manages communication between A53 and remote cores
    • Shared buffers: Accesses DDR_SHARED_MEM for input/output frames
    C7x NPU Firmware
    • TIDL inference firmware: Located in `/usr/lib/firmware/`, requires sections for code, data for normal core operation. This will setup other regions used by TIOVX and TI Deep Learning
    • Local heaps: DDR_C7X_1_LOCAL_HEAP for model weights and metadata
    • Scratch memory: DDR_C7X_1_SCRATCH for intermediate tensors during inference
    • Shared buffers: Accesses DDR_SHARED_MEM for input/output tensors
    Libraries in HLOS (A53 Linux)
    • libtivision_apps.so: Vision applications library in `/usr/lib/`, and contains configuration of the various shared DDR regions for used TIOVX. This library provides TIOVX to Linux
    Device Tree (DTS/DTSO)
    • Memory carveouts: Reserved memory regions defined in device tree for Linux
    • CMA regions: Contiguous Memory Allocator pools, primarily for VPU / video codec. This is not dependent on TIOVX or remote-core memory regions discussed in this FAQ
    • Firmware loading: Memory addresses for loading remote core firmware

    Memory Map Regions and Usage

    Current Memory Map (SDK 10.x and prior)

    The below does not include code/data for remote core firmwares or fundamental IPC regions. 

    Region Name Start Address Size Usage
    APP_LOG_MEM 0xA1000000 256.00 KB Memory for remote core logging
    TIOVX_OBJ_DESC_MEM 0xA1040000 15.75 MB Memory for TI OpenVX shared memory. MUST be non-cached or cache-coherent
    APP_FILEIO_MEM 0xA2000000 4.00 MB Memory for remote core file operations
    TIOVX_LOG_RT_MEM 0xA2400000 12.00 MB Memory for TI OpenVX shared memory for Run-time logging. MUST be non-cached or cache-coherent
    DDR_SHARED_MEM 0xA3000000 176.00 MB Memory for shared memory buffers in DDR
    DDR_MCU_R5F_LOCAL_HEAP 0xAE000000 16.00 MB DDR for MCU R5F for local heap
    DDR_DM_R5F_LOCAL_HEAP 0xAF000000 16.00 MB DDR for DM R5F for local heap
    DDR_C7X_1_LOCAL_HEAP_NON_CACHEABLE 0xB0000000 16.00 MB DDR for c7x_1 for non cacheable local heap
    DDR_C7X_1_SCRATCH_NON_CACHEABLE 0xB1000000 16.00 MB DDR for c7x_1 for non cacheable scratch Memory
    DDR_C7X_1_LOCAL_HEAP 0xB2000000 112.00 MB DDR for c7x_1 for local heap
    DDR_C7X_1_SCRATCH 0xB9000000 112.00 MB DDR for c7x_1 for Scratch Memory
    The end of these regions ends at 0xC000 0000 , which is 1 GB from the DDR start (0x8000 0000). Any remaining memory may be used for CMA pools or Linux userspace. Data beyond 2 GB must go into a separate memory map region, and 32-bit cores would require address translation. Please view the TRM for more details

    The exact size and addresses may vary somewhat between SDK versions, but they are nominally stable.

    SDK 11.1 Changes

    In SDK 11.1, a new region was added:
    • DDR_DM_R5F_VISS_CONFIG_HEAP: Dedicated heap for VISS (Vision Imaging Subsystem) configuration, which fits into the last 4 MB from DDR_SHARED_MEM (starting from 0xADC0 0000)

    Additional Region Usage Details

    The following regions are most commonly modified and optimized for size:

    DDR_SHARED_MEM:
    • Used for actual image/frame data shared between processors
    • TIOVX and GStreamer pipelines allocate buffers from this region for shared buffer pools. ISP, MSC, LDC (VPAC) hardware accelerators, C7 NPU access this memory for inputs/outputs
    • Monitor utilization: `cat /sys/kernel/debug/dma_buf/bufinfo` (shows instantaneous usage)
    • TIOVX apps print cumulative statistics for all allocations at end of execution

    DDR_C7X_1_LOCAL_HEAP:
    • Stores deep learning model weights and metadata
    • Holds intermediate tensors during inference, especially is model preemption is enabled (default)
    • There is a similar (but smaller) non-cacheable version of this region
    • Monitor Utilization: `/opt/vision_apps/vx_app_heap_stats.out`


    DDR_C7X_1_SCRATCH:
    • Designed for intermediate tensor storage during inference
    • With model preemption enabled (default), utilization may be low (~2%) and size can be reduced
    • There is a similar (but smaller) non-cacheable version of this region
    • Without preemption, all intermediate tensors use scratch (higher utilization)
    • Monitor Utilization: `/opt/vision_apps/vx_app_heap_stats.out`

    DDR_DM_R5F_LOCAL_HEAP:
    • Used by VPAC drivers for ISP/VISS, MSC, LDC for intermediate data storage
    • Monitor Utilization: `/opt/vision_apps/vx_app_heap_stats.out`
    Next, let's look at how we alter the memory map
  • How to Change the Memory Map

    Prerequisites

    1. Firmware Builder Environment: You need the AM62A firmware builder set up. Request access to FIRMWARE-BUILDER-AM62A and follow the steps with the psdk_rtos/docs inside to set this up
    2. Vision Apps Source: `vision_apps/platform/am62a/rtos/` in the firmware-builder
    3. Device Tree Source: Original and EdgeAI device tree paths, part of SDK in the `board-support/ti-linux-kernel-X.XX.XX+git-ti/arch/arm64/boot/dts/ti` directory
    • Your linux-kernel version (and thus, the path) will depend on the SDK version

    Step 1: Export Device Tree Paths (For 11.1 SDK)

    SDK's prior to v11.1 may skip this step. It will be handled manually later. 
    export ORG_DTS_PATH=${LINUX_INSTALL_PATH}/board-support/ti-linux-kernel-6.12.34+git-ti/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
    export EDGEAI_DTS_PATH=${LINUX_INSTALL_PATH}/board-support/ti-linux-kernel-6.12.34+git-ti/arch/arm64/boot/dts/ti/k3-am62a7-sk-edgeai.dtso

    Step 2: Modify gen_linker_mem_map.py

    Edit `vision_apps/platform/am62a/rtos/gen_linker_mem_map.py` to change memory regions.

    Example: Increase DDR_SHARED_MEM size

    Locate the `ddr_shared_mem` section (around line 213):
    # Original
    ddr_shared_mem_addr  = tiovx_log_rt_mem_addr + tiovx_log_rt_mem_size;
    ddr_shared_mem_size  = 172*MB;
    
    # Modified (increase to 256 MB)
    ddr_shared_mem_addr  = tiovx_log_rt_mem_addr + tiovx_log_rt_mem_size;
    ddr_shared_mem_size  = 256*MB;

    Example: Reduce C7x scratch memory

    Locate the `ddr_c7x_1_scratch` section:
    # Original
    ddr_c7x_1_scratch_addr = ddr_c7x_1_local_heap_addr + ddr_c7x_1_local_heap_size;
    ddr_c7x_1_scratch_size = 128*MB;
    
    # Modified (reduce to 64 MB)
    ddr_c7x_1_scratch_addr = ddr_c7x_1_local_heap_addr + ddr_c7x_1_local_heap_size;
    ddr_c7x_1_scratch_size = 64*MB;

    Step 3: Understand Memory Constraints

    The script handles alignment automatically, but be aware of constraints:

    • Size constraints: Some regions have minimum sizes required by firmware/libraries
    • Alignment requirements: Regions must be aligned to specific boundaries (handled by script)
    • Cache settings: CACHED vs NON_CACHED regions affect performance
    • Address ordering: Regions must not overlap; script calculates addresses sequentially
    The script takes care of alignment, but not necessarily size constraints. Please refer to the firmware builder documentation for these constraints.

    Step 4: Generate Memory Map Files

    Run the generator script:

    cd vision_apps/platform/am62a/rtos/
    python3 gen_linker_mem_map.py

    This generates multiple output files in the same directory:
    • Linker command files for R5F and C7x firmwares within vision_apps/out. As part of this, 'dpl' (device porting layer) files will be generated when the firmware is actually being build, including the actual MMU/MPU configurations
    • Memory map headers for libraries (`app_mem_map.h`)
    • Device tree overlays (DTSO) with memory carveouts
    In SDK 11.1 and onward, the device tree changes occur automatically when the ORG_DTS_PATH and EDGEAI_DTS_PATH variables are set, thereby modifying the k3-am62a7-sk.dts and k3-am62a7-sk-edgeai.dtso, respectively. Otherwise, the script will print updated regions, and it is the user's responsibility to modify the DTS file themselves.

    Step 5: Verify Generated Files

    Check that files were updated in:
    • `vision_apps/platform/am62a/rtos/` (linker files)
      • Check the `c7x_1` directory (and `generated` sub-directory) for C7 NPU
      • Check the `mcu1_0` directory (and `generated` sub-directory) for DM R5 running VPAC/ISP
    • Device tree paths (DTSO files with memory reservations)

    How to apply the changes on the processor

    Now we will apply the changes by rebuilding and replacing key software components. 

    Step 1: Build Firmwares, Libraries with Firmware Builder

    The sdk_builder within the ti-firmware-builder will use makefiles to build the firmwares and relevant libraries. You can use the `sdk` and `firmware` make targets to rebuild these files.

    Note that this will also rebuild u-boot by default, using the generated DM R5 firmware to produce a new tiboot3.bin within the u-boot directory of the SDK as `board_support/u-boot-buid/r5/tiboot3.bin`

    The firmware builder must be used to rebuild:

    1. DM R5F firmware (included into bootloader - tiboot3.bin (or SBL); )
    • tiboot3 placed in BOOT partition of SD card
    • Sets up initial memory carveouts during boot

    2. C7x DSP firmware (TIDL inference firmware)
    • Placed in `/usr/lib/firmware/` on rootfs
    • Nominally boots via remoteproc driver in Linux
    • Uses new memory map for AI model execution

    3. libtivision_apps.so library
       - Located in `/usr/lib/` on the rootfs partition
       - Must match memory map used by firmwares

    Step 2: Deploy updated libraries and firmware to SD Card

    Copy rebuilt components to SD card:

    # Copy from staging area to the SD card
    make linux_fs_install_sd
    # If this gives permissions errors, use 
    sudo -E make linux_fs_install_sd
    
    There are equivalent make targets for putting all generated/built files for the target filesystem into a staging area. This may be more appropriate depending on the use-case.

    You may need to update the path to the SD card within `sdk_builder/tools_path`. Permissions on the SD card and other files may require SUDO rights to write updated files, so it may be necessary in your system to run this with elevated privileges. Make sure to set environment variables like `SOC=am62a` or use `sudo -E` to inherit the environment from the calling script/terminal.  

    Step 3: Update Device Tree

    If using an SDK older than 11.1, there will be some manual steps to copy portions of the printed DTS into the appropriate file in the linux kernel. For 11.1, those files will be edited in place.

    Follow SDK documentation for rebuilding device tree ('dtbs'). This involves the `make linux-dtbs` make target from the top-level SDK makefile. The built .DTB, DTBO files will be in the linux kernel tree under `arch/arm64/boot/dtb/ti`. The resulting .DTB and .DTBO must be placed into the /boot/dtb directory of the rootfs partition.

    Additional information

    SDK 11.1 Specific Changes

    New Region: DDR_DM_R5F_VISS_CONFIG_HEAP

    SDK 11.1 introduced a dedicated heap for VISS configuration:
    ddr_dm_r5f_viss_config_heap_addr = <calculated>;
    ddr_dm_r5f_viss_config_heap_size = <size>*MB;

    This separates VISS configuration memory from other R5F heaps for better isolation and predictability.

    Migration Notes

    When migrating from SDK 10.x to 11.1:
    1. Update `gen_linker_mem_map.py` to include VISS_CONFIG_HEAP region
    2. Adjust addresses to accommodate new region
    3. Rebuild all firmwares and libraries
    4. Update device tree with new carveouts
    However, it is recommended to migrate your own changes into the baseline script in the firmware-builder, as there are additional changes that automate modifications like the device tree. 
  • And let me include further information for checking your work, debugging, and common issues:

    Monitoring Memory Utilization

    During Runtime (Linux)

    DDR_SHARED_MEM (instantaneous):
    cat /sys/kernel/debug/dma_buf/bufinfo
    # Shows each allocated buffer with size

    Overall Memory:
    free -h
    cat /proc/meminfo

    Per core heap utilization
    /opt/vision_apps/vx_app_heap_stats.out

    After Application Execution

    TIOVX Application Statistics:

    Run any EdgeAI TIOVX application to see memory statistics at exit:
    ./bin/Release/edgeai-tiovx-apps-main configs/linux/object_detection.yaml
    When the application ends, the printout includes:
    DDR_SHARED_MEM: Alloc's: 47 alloc's of 48344052 bytes
    DDR_SHARED_MEM: Free's : 47 free's of 48344052 bytes
    DDR_SHARED_MEM: Open's : 0 allocs of 0 bytes

    Best Practices and Tips

    The simplest visual representation of the memory map is located in `vision_apps/platform/am62a/rtos/system_memory_map.html`, which tells each region, the address range, and overall size. This is worth verifying against alignment and sizing requirements, and should be provided in any support ticket on the matter.

    Sizing Recommendations

    1. Monitor before changing: Run your application and check actual utilization. If there are TIOVX verification failures due to memory allocation, you will likely need to modify sizes
    2. DDR_SHARED_MEM: Size based on resolution, color format, and pipeline depth
    • Example: 1920x1080 NV12 = ~3 MB per frame
    • Pipeline with 10 buffers = ~30 MB minimum
    • Pool size per Gstreamer/TIOVX element
    3. C7x heaps: Size based on model requirements
    • LOCAL_HEAP: Stores most model data, including weights. Allocations during initialization will show the peak usage, which happens during TIOVX verification (before the application starts processing).
    • SCRATCH: Often underutilized (~2%), can reduce significantly if preemption is enabled (true by default)
    4. Leave margin: Don't size regions to exact usage; allow 20-30% headroom. The peak allocation will occur during initialization as most all memory is preallocated before the application starts processing frames. 

    Common Pitfalls

    1. Forgetting full rebuild: Changing memory map requires rebuilding bootloader, firmwares, and libraries, followed by updating those files
    2. Mismatched versions: Libraries in Linux/HLOS and firmware must use same memory map
    3. Size constraints: Some regions have minimum sizes or constraints (for example, divisible by 16MB); check firmware builder documentation
    4. Alignment issues: While script handles alignment, manual edits may break this

    Testing Strategy

    1. Verify IPC communication: Ensure cores can still communicate after changes
    2. TIOVX conformance tests under /opt/vision_apps: This requires a test dataset be extracted into /opt/vision_apps/test_data. Firmware builder documentation gives guidance on running this
    3. Test against a small end-to-end demo: `/opt/edgeai-gst-apps` and `/opt/edgeai-tiovx-apps` include config-file-based applications. Using small applications like image_classification.yaml is a good verification that the new memory map was applied correctly
    3. Test with representative workload
    4. Monitor for OOM errors: Check kernel logs, utilities for out-of-memory issues

    Troubleshooting

    Issue: Boot failure after memory map change
    • Symptoms: System doesn't boot or hangs at bootloader
    • Likely cause: Bootloader (tiboot3.bin) not updated with new memory map. Solution: Ensure DM R5F firmware (tiboot3.bin) was rebuilt and deployed to BOOT partition
    • Likely solution: Ensure DM R5F firmware (tiboot3.bin) was rebuilt and deployed to BOOT partition
    If there is no response whatsoever over UART logs during boot, it may have been the wrong tiboot3.bin applied. This is related to GP, HS, and HS-FS silicon. HS-FS is most common, and is what is used by default on starter kit EVMs.

    Issue: TIOVX application crashes

    Symptoms: Segmentation fault or memory allocation errors

    Likely cause:
    • Region may be too small for application needs
    • Library/firmware mismatch (e.g., using original firmware with updated tivision_apps.so library)

    Likely Solution:
    1. Check memory statistics from previous successful runs
    2. Ensure all firmwares and libraries rebuilt with same memory map
    3. Increase region sizes if needed

    Issue: IPC communication failures

    Symptoms: Remote cores not responding, timeout errors
    Likely cause: IPC or RPMSG regions modified incorrectly
    Likely Solution: Verify VRING and RPMSG region sizes match firmware expectations

    Issue: Device tree doesn't reserve memory
    Symptoms: Linux kernel uses memory intended for remote cores
    Likely cause: Device tree not updated or incorrect carveout addresses
    Likely Solution:
    1. Verify DTSO file generated correctly by gen_linker_mem_map.py
    2. Check device tree includes memory reservations
    3. Boot and check `/proc/device-tree/reserved-memory/` and dmesg logs

    References

    • Firmware Builder Documentation: `docs/user_guide/getting_started_am62a.rst`
    • Memory Map Generator Script: `vision_apps/platform/am62a/rtos/gen_linker_mem_map.py`
    • TI E2E Support Forums: Search for AM62A memory map discussions