1. 程式人生 > 實用技巧 >海思Hi3559AV100記憶體分配——MMZ

海思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} echoUBOOT_LINUX_ENTRY_NEW=$UBOOT_LINUX_ENTRY_NEW echoLITEOS_DDR_MEM_BASE_NEW=$LITEOS_DDR_MEM_BASE ... echoLINUX_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}"MODULEISINVALID!"${DONE} exit1 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模組初始化時,後預先分配記憶體池的大小,分配的大小過大,導致記憶體越界,出現不開預知的錯誤