• 海思Hi3559AV100内存分配——MMZ


    硬件:Hi3559av100  4G+32G

    multi-core版本为单系统a73mp+a53mp版本

    一、内存分配说明

      Hi3559AV100 的 DDR 地址空间从 0x40000000 起始。

      Hi3559AV100 的 DDR 主要划分为如下几个部分:
    • 核间通信共享内存(A53MP+A73MP、A53UP、Cortex-M7、DSP 之间)
    • DSP0/1/2/3 Huawei LiteOS 系统内存
    • A53MP+A73MP Linux 系统内存
    • A53UP Huawei LiteOS 系统内存
    • A53MP+A73MP 使用的 MMZ 区域
    • A53UP 使用的 MMZ 区域。

      见下图

       内存分配的配置可以在osdrv目录下的osdrv_mem_cfg.sh文件中进行配置

    ...
    CHIP=$2
    AMP_TYPE=$3
    
    DDR_MEM_BASE=0x40000000
    DSP_MEM_SIZE=0x04000000 #64M
    
    #hi3559av100 memory config#
    if [ ${CHIP} == "hi3559av100" ]; then
        echo "CHIP:${CHIP}, memory config"
        if [ ${AMP_TYPE} == "linux" ]; then
            LINUX_SYS_MEM_BASE=0x`echo "obase=16;$[$DDR_MEM_BASE + $DSP_MEM_SIZE]"|bc`
            #LINUX_SYS_MEM_BASE=0x0x40000000 + 0x04000000(64M) = 0x44000000
            LINUX_ENTRY=0x`echo "obase=16;$[$LINUX_SYS_MEM_BASE + 0x00080000]"|bc`
            #LINUX_ENTRY=0x44000000 + 0x00080000 = 0x44080000
            ATF_ENTRY=0x`echo "obase=16;$[$LINUX_ENTRY + 0x02F80000]"|bc`
            #ATF_ENTRY=0x44080000 + 0x02F80000 = 0x47000000
            LINUX_MEM_SIZE=0x20000000
            #内核的基地址是0x44000000,内核大小为0x20000000即512M。内核结束地址=0x64000000
            LINUX_MMZ_SIZE=0xCC000000
            #MMZ的开始地址为0x64000000,大小为0xCC000000即3264M,MMZ结束地址=0x13000 0000
    
            LITEOS_SYS_MEM_BASE=0x`echo "obase=16;$[$LINUX_SYS_MEM_BASE+$LINUX_MEM_SIZE+$LINUX_MMZ_SIZE]" | bc`
            LITEOS_TEXT_OFFSET=0x01000000
            LITEOS_SYS_MEM_SIZE=0x0B000000
            LITEOS_MMZ_MEM_BASE=0x`echo "obase=16;$[$LITEOS_SYS_MEM_BASE+$LITEOS_TEXT_OFFSET+$LITEOS_SYS_MEM_SIZE]" | bc`
            LITEOS_MMZ_MEM_LEN=0x04000000
            CPU_TYPE=multi-core
        elif [ ${AMP_TYPE} == "linux_liteos" ]; then
    ...
    ####################################################################################################

    echo -e ${INFO}"config $1..."${DONE}
    echo UBOOT_LINUX_ENTRY_NEW=$UBOOT_LINUX_ENTRY_NEW
    echo LITEOS_DDR_MEM_BASE_NEW=$LITEOS_DDR_MEM_BASE
    ...
    echo LINUX_SYS_MEM_BASE_NEW =$LINUX_SYS_MEM_BASE_NEW

    if [ $1 == "uboot" ];then
    sed -i "s/$UBOOT_LINUX_ENTRY_MATCH/$UBOOT_LINUX_ENTRY_NEW/g"                ./opensource/uboot/u-boot-2016.11/configs/${CHIP}_defconfig
    sed -i "s/$UBOOT_LINUX_ENTRY_MATCH/$UBOOT_LINUX_ENTRY_NEW/g"                ./opensource/uboot/u-boot-2016.11/configs/${CHIP}_nand_defconfig
    sed -i "s/$UBOOT_LINUX_ENTRY_MATCH/$UBOOT_LINUX_ENTRY_NEW/g"                ./opensource/uboot/u-boot-2016.11/configs/${CHIP}_emmc_defconfig
    sed -i "s/$UBOOT_LINUX_ENTRY_MATCH/$UBOOT_LINUX_ENTRY_NEW/g"                ./opensource/uboot/u-boot-2016.11/configs/${CHIP}_ufs_defconfig
    elif [ $1 == "liteos" ];then
        if [ ${AMP_TYPE} == "linux" ]; then
            sed -i "s/$LITEOS_DDR_MEM_BASE_MATCH/$LITEOS_DDR_MEM_BASE_NEW/g"            ./platform/liteos_a53/liteos_user/platform/bsp/board/${CHIP}/cortex-a53_aarch64/include/board.h
    ...
    elif [ $1 == "atf" ];then
    sed -i "s/$ATF_ATF_ENTRY_MATCH/$ATF_ATF_ENTRY_NEW/g"                        ./opensource/arm-trusted-firmware/arm-trusted-firmware/plat/hisilicon/${CHIP}/include/platform_def.h
    elif [ $1 == "linux" ];then
    sed -i "s/$LINUX_ATF_ENTRY_MATCH/$LINUX_ATF_ENTRY_NEW/g"                    ./opensource/kernel/linux-4.9.y_${CPU_TYPE}/arch/arm64/boot/dts/hisilicon/${CHIP}-demb.dts
    sed -i "s/$LINUX_ATF_ENTRY_MATCH/$LINUX_ATF_ENTRY_NEW/g"                    ./opensource/kernel/linux-4.9.y_${CPU_TYPE}/arch/arm64/boot/dts/hisilicon/${CHIP}-demb-amp.dts
    sed -i "s/$LINUX_SYS_MEM_BASE_MATCH/$LINUX_SYS_MEM_BASE_NEW/g"              ./opensource/kernel/linux-4.9.y_${CPU_TYPE}/arch/arm64/boot/dts/hisilicon/${CHIP}-demb.dts
    sed -i "s/$LINUX_SYS_MEM_BASE_MATCH/$LINUX_SYS_MEM_BASE_NEW/g"              ./opensource/kernel/linux-4.9.y_${CPU_TYPE}/arch/arm64/boot/dts/hisilicon/${CHIP}-demb-amp.dts
    else
    echo -e ${ERROR}"MODULE IS INVALID!"${DONE}
    exit 1
    fi

      每次执行这个脚本时,会根据脚本的第一个参数$1,会不同的部分进行内存配置。

      可以看到在编译uboot,linux,atf时,都会将参数写入对应的config文件。

      在osdrv目录下的Makefile中会执行此脚本,如下:

      编译uboot时执行./osdrv_mem_cfg.sh脚本

     

     二、在加载驱动时指定MMZ内存参数

      load3559av100_multicore脚本原来是在mmp/out/linux/multi-core/ko文件夹下,生成文件系统时会将其拷贝到文件系统的根目录的/komod文件夹下

      ./load3559av100_multicore -i -sensor0 imx334 -sensor1 imx334 -sensor2 imx334 -sensor3 imx334

    示例,以下是核心板出厂自带的文件系统/komod下的脚本,厂家的config和uboot的bootargs: mem=2048M即给内核分配了2048M内存,MMZ的起始:0xE400 0000

      但是我烧录的海思默认配置的内核与文件系统(包含load3559av100_multicore),配置即内核的管理内存为512M,MMZ起始于0x64000000

     1 ...核心板出厂的...
     2 #DDR start:0x40000000,  DSP(64M);  kernel start:0x44000000,  OS(2048M); MMZ start:0xE4000000
     3 mmz_start=0xE4000000;         # mmz start addr
     4 mmz_size=1984M;               # 1984M, mmz size
     6 ##################################################################
     7 ...
     8 insert_ko()
     9 {
    10     insmod sys_config.ko g_online_flag=0 sensors=sns0=$SNS_TYPE0,sns1=$SNS_TYPE1,sns2=$SNS_TYPE2,sns3=$SNS_TYPE3,sns4=$SNS_TYPE4,sns5=$SNS_TYPE5,sns6=$SNS_TYPE6,sns7=$SNS_TYPE7 
    11 
    12     # driver load
    13     insmod hi_osal.ko anony=1 mmz_allocator=hisi mmz=anonymous,0,$mmz_start,$mmz_size || report_error15     insmod hi3559av100_sys.ko17 ...
    ...海思默认的...
    #DDR start:0x40000000,  DSP(64M);  kernel start:0x44000000,  OS(512M); MMZ start:0x64000000
    mmz_start=0x64000000;         # mmz start addr
    mmz_size=3520M;               # 3520M, mmz size
    ...

    烧录进入,启动开发板,第一次从SD烧录,可以进入内核并挂载文件系统,进入文件系统/komod目录下执行驱动加载脚本时,出现报错

     报错信息里面:

    kernel memory:(0x4000 0000, 0xC3FF FFFF), SIZE=0xC3FF FFFF - 0x4000 0000 = 2047M (kernel)+ 64M(DSP)

    kernel的默认内存不是512M吗?怎么变成2048M,因为config和uboot的bootargs里面也指定了mem=2048M

    如此,加载脚本里面又重新指定了MMZ的起始地址为0x6400 0000,加载的时候就和内核的地址空间 (0x4000 0000, 0xC3FF FFFF)冲突了,报内存错误。

    那就更改load3559av100_multicore脚本里面的参数为

     mmz_start=0xE4000000;         # mmz start addr
     mmz_size=1984M;               # 1984M, mmz size

    加载成功。

    执行推流程序,

     系统卡死,无法退出,也没有报错信息。

    尝试将内存配置改为kernel mem=512M, MMZ=3520M,重新执行./hi3559a 2,正常执行。

    判断,是因为kernel mem=2048M后,留给MMZ=1984M,在VB模块初始化时,后预先分配内存池的大小,分配的大小过大,导致内存越界,出现不开预知的错误

    boot args修改

    修改烧写文件的config文件里的参数

    进入boot界面后,printenv,查看参数,setenv bootargs...修改参数,最后savenv保存

    注意,bootargs每次save后都会写到emmc里面,以后每次启动就会从emmc里面读取配置信息,比如去哪里加载内核和文件系统,

    如果内核的参数或文件系统没有配置对,就会导致kernel panic, 挂载不上文件系统,所以一定要检查好配置参数。每次对bootargs修改后

    都要保存到emmc中,内核的实际大小一定要和config文件里写的要匹配。

     注意:

    烧写uboot时,一定一定要烧写与板子ddr参数匹配的uboot,因为第一次烧写不匹配的uboot.bin后是可以烧进去,但是同时会将ddr的参数重写

    会导致以后重启或再次烧写时,系统不知道去哪里运行程序,一直无法烧写,卡死在system  startup

     一旦出现这种情况,可以通过海思官方提供的HiTools来进行串口或网口烧写。

  • 相关阅读:
    对数组对象处理及其他小问题
    前端面试题库
    题解 P3371 【【模板】单源最短路径】
    题解 P2403 【[DOI2010]所驼门王的宝藏】
    题解 P2283 【[HNOI2003]多边形】
    题解 P1074 【靶形数独 】
    题解 P1064 【金明的预算方案】
    题解 CH1813 【双栈排序】
    题解 CH1809 【匹配统计】
    题解 CH0805 【防线】
  • 原文地址:https://www.cnblogs.com/y4247464/p/13572146.html
Copyright © 2020-2023  润新知