ZYNQ平台SylixOS系统启动过程占用时间最长的操作

文章详细描述了内核启动过程中,特别是__vmmLibPageMap函数在物理地址映射中的时间消耗,重点在于PL端寄存器空间映射占用了约7秒。文章探讨了如何通过减少页映射来优化启动时间,如果排除PL映射,启动过程大约需要3秒。
摘要由CSDN通过智能技术生成

内核启动过程中调用关系:

API_KernelStart
    ->usrStartup
        ->halPrimaryCpuInit
            ->API_VmmLibPrimaryInit
                ->__vmmLibPrimaryInit
                    ->__vmmLibGlobalMap
                        ->if(i == 17) {
                            pphydesc[i].PHYD_uiType = LW_PHYSICAL_MEM_BOOTSFR;
                            __vmmLibPageMap //占用大概7s时间
                          }

 注意这个函数,主要时间消耗都在这里:

//初始化 vmm 库    
API_VmmLibPrimaryInit(_G_physicalDesc,
                          _G_virtualDesc,
                          ARM_MACHINE_A9);  

 物理地址映射表_G_physicalDesc:

static LW_MMU_PHYSICAL_DESC    _G_physicalDesc[] = {
        {                                                               /*  中断向量表                  */
                BSP_CFG_RAM_BASE,
                0,
                LW_CFG_VMM_PAGE_SIZE,
                LW_PHYSICAL_MEM_VECTOR,
        },

        {                                                               /*  内核代码段                  */
                BSP_CFG_RAM_BASE,
                BSP_CFG_RAM_BASE,
                BSP_CFG_TEXT_SIZE,
                LW_PHYSICAL_MEM_TEXT,
        },

        {                                                               /*  内核数据段                  */
                BSP_CFG_RAM_BASE + BSP_CFG_TEXT_SIZE,
                BSP_CFG_RAM_BASE + BSP_CFG_TEXT_SIZE,
                BSP_CFG_DATA_SIZE,
                LW_PHYSICAL_MEM_DATA,
        },

        {                                                               /*  DMA 缓冲区                  */
                BSP_CFG_RAM_BASE + BSP_CFG_TEXT_SIZE + BSP_CFG_DATA_SIZE,
                BSP_CFG_RAM_BASE + BSP_CFG_TEXT_SIZE + BSP_CFG_DATA_SIZE,
                BSP_CFG_DMA_SIZE,
                LW_PHYSICAL_MEM_DMA,
        },

        {                                                               /*  APP 通用内存                */
                BSP_CFG_RAM_BASE + BSP_CFG_TEXT_SIZE + BSP_CFG_DATA_SIZE + BSP_CFG_DMA_SIZE,
                BSP_CFG_RAM_BASE + BSP_CFG_TEXT_SIZE + BSP_CFG_DATA_SIZE + BSP_CFG_DMA_SIZE,
                BSP_CFG_APP_SIZE,
                LW_PHYSICAL_MEM_APP,
        },

        /*
         * sfr
         */
        {
                0xF8900000 ,                                           /*  intc 中断的物理地址         */
                0xF8900000 ,                                           /*  映射到的虚拟地址            */
                0xF8F02FFF - 0xF8900000 + 1,                           /*  映射的大小                  */
        		LW_PHYSICAL_MEM_BOOTSFR
        },

        {
                    0xE0000000,                                         /*  Debug 串口0 的物理地址      */
                    0xE0000000,                                         /*  映射到的虚拟地址            */
                    LW_CFG_VMM_PAGE_SIZE,                               /*  映射的大小                  */
                    LW_PHYSICAL_MEM_BOOTSFR
        },

        {
                0xE0001000,                                             /*  Debug 串口1的物理地址       */
                0xE0001000,                                             /*  映射到的虚拟地址            */
                LW_CFG_VMM_PAGE_SIZE,                                   /*  映射的大小                  */
                LW_PHYSICAL_MEM_BOOTSFR                                 /*  映射的属性                  */
        },

        {
                0xE000A000,                                             /*  GPIO 的物理地址             */
                0xE000A000,                                             /*  映射到的虚拟地址            */
                LW_CFG_VMM_PAGE_SIZE,                                   /*  映射的大小                  */
                LW_PHYSICAL_MEM_BOOTSFR                                 /*  映射的属性                  */
        },

        {
                0xE0002000,                                             /*  USB0 的物理地址             */
                0xE0002000,                                             /*  映射到的虚拟地址            */
                LW_CFG_VMM_PAGE_SIZE,                                   /*  映射的大小                  */
                LW_PHYSICAL_MEM_BOOTSFR                                 /*  映射的属性                  */
        },

        {
                0xE0003000,                                             /*  USB1 的物理地址             */
                0xE0003000,                                             /*  映射到的虚拟地址            */
                LW_CFG_VMM_PAGE_SIZE,                                   /*  映射的大小                  */
                LW_PHYSICAL_MEM_BOOTSFR                                 /*  映射的属性                  */
        },

        {
                0xE000B000,                                             /*  GMAC0(MDIO) 的物理地址      */
                0xE000B000,                                             /*  映射到的虚拟地址            */
                LW_CFG_VMM_PAGE_SIZE,                                   /*  映射的大小                  */
                LW_PHYSICAL_MEM_BOOTSFR                                 /*  映射的属性                  */
        },

        {
                0xF8000000,                                             /*  SLCR  的物理地址            */
                0xF8000000,                                             /*  映射到的虚拟地址            */
                LW_CFG_VMM_PAGE_SIZE,                                   /*  映射的大小                  */
                LW_PHYSICAL_MEM_BOOTSFR                                 /*  映射的属性                  */
        },

        {
                0xF8005000,                                             /*  SWDT 的物理地址             */
                0xF8005000,                                             /*  映射到的虚拟地址            */
                LW_CFG_VMM_PAGE_SIZE,                                   /*  映射的大小                  */
                LW_PHYSICAL_MEM_BOOTSFR                                 /*  映射的属性                  */
        },

        {
                0xF8007000,                                             /*  device config 的物理地址    */
                0xF8007000,                                             /*  映射到的虚拟地址            */
                LW_CFG_VMM_PAGE_SIZE,                                   /*  映射的大小                  */
                LW_PHYSICAL_MEM_BOOTSFR                                 /*  映射的属性                  */
        },

        {
                0xF8F00000,                                              /*  SCU Timer0 的物理地址      */
                0xF8F00000,
                LW_CFG_VMM_PAGE_SIZE,
                LW_PHYSICAL_MEM_BOOTSFR,
        },

        {
                0xFFFFF000,                                             /*  CPU1 启动物理地址           */
                0xFFFFF000,                                             /*  映射到的虚拟地址            */
                LW_CFG_VMM_PAGE_SIZE,                                   /*  映射的大小                  */
                LW_PHYSICAL_MEM_BOOTSFR                                 /*  映射的属性                  */
        },
#ifdef BSP_ZYNQ_FPGA_MAP
        BSP_ZYNQ_FPGA_MAP
#endif
#ifdef BSP_PL_HDMI_MAP
        BSP_PL_HDMI_MAP
#endif

#ifdef BSP_CFG_QEMU_MAP
                BSP_CFG_QEMU_MAP
#endif

        {                                                               /*  结束                        */
                0,
                0,
                0,
                0
        }
};

 其中pphydesc[17]的映射最耗时,大约7s左右,主要时间都在做PL端寄存器空间的映射:

/*********************************************************************************************************
  PL(FPGA)端寄存器映射
*********************************************************************************************************/
#define LW_CFG_VMM_PGD_SHIFT                  20                        /*  2^20 = 1MB                  */
#define LW_CFG_VMM_PGD_SIZE                   (1ul << LW_CFG_VMM_PGD_SHIFT)
#define BSP_ZYNQ_FPGA_MAP                   \
        {                                   \
            0x40000000,                     \
            0x40000000,                     \
            LW_CFG_VMM_PGD_SIZE * 1024,     \
            LW_PHYSICAL_MEM_BOOTSFR         \
        },

当i = 17时,ulPageNum = 262144,1页是4Kb,换算一下就是1G的PL空间

//当i = 17时,ulPageNum[262144]
ulError = __vmmLibPageMap(pphydesc[i].PHYD_ulPhyAddr, 
                          pphydesc[i].PHYD_ulVirMap,
                          ulPageNum, LW_VMM_FLAG_DMA);

 可以看出__vmmLibPageMap是按页映射的,页越多占用时间越长

    for (i = 0; i < ulPageNum; i++) {
        p_pgdentry = __vmm_pgd_alloc(pmmuctx, ulVirtualAddr);
        if (p_pgdentry == LW_NULL) {
            return  (ERROR_VMM_LOW_LEVEL);
        }
        
        p_pmdentry = __vmm_pmd_alloc(pmmuctx, p_pgdentry, ulVirtualAddr);
        if (p_pmdentry == LW_NULL) {
            return  (ERROR_VMM_LOW_LEVEL);
        }
        
#if LW_CFG_VMM_PAGE_4L_EN > 0
        p_ptsentry = __vmm_pts_alloc(pmmuctx, p_pmdentry, ulVirtualAddr);
        if (p_ptsentry == LW_NULL) {
            return  (ERROR_VMM_LOW_LEVEL);
        }
        
        p_pteentry = __vmm_pte_alloc(pmmuctx, p_ptsentry, ulVirtualAddr);
#else
        p_pteentry = __vmm_pte_alloc(pmmuctx, p_pmdentry, ulVirtualAddr);
#endif                                                                  /*  LW_CFG_VMM_PAGE_4L_EN > 0   */

        if (p_pteentry == LW_NULL) {
            return  (ERROR_VMM_LOW_LEVEL);
        }
        
        iregInterLevel = KN_INT_DISABLE();                              /*  关闭中断                    */
        __VMM_MMU_MAKE_TRANS(pmmuctx, p_pteentry,
                             ulVirtualAddr,
                             paPhysicalAddr, ulFlag);                   /*  创建映射关系                */
        KN_INT_ENABLE(iregInterLevel);                                  /*  打开中断                    */
        
        paPhysicalAddr += LW_CFG_VMM_PAGE_SIZE;
        ulVirtualAddr  += LW_CFG_VMM_PAGE_SIZE;
    }

如果抛开zynq,如果不需要做PL寄存器地址的映射,启动过程大约需要3s左右。

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值