1. 程式人生 > >VxWorks記憶體分配分析

VxWorks記憶體分配分析

記憶體顯示函式memPartShow

static PART_ID  testMemoryPartId = NULL;

void mem_test()

{

    char *memoryPool;

    void * pMemory;

    static const UINT   initialSize = 3000;

    if ((memoryPool =malloc (initialSize)) == NULL)

        return ERROR;

    if ((testMemoryPartId =memPartCreate (memoryPool, initialSize)) == NULL) {

        free (memoryPool);

        return ERROR;

    }

    pMemory = memPartAlloc (testMemoryPartId, 1500);

    memPartShow (testMemoryPartId, 2);

}


從程式上看,我們實際申請了3000B,但1236+1516+200=2952B

所以有48B用於儲存該分割槽資訊。

系統從啟動到執行過程中記憶體分配的分析:

系統啟動u-boot後,u-boot部分程式碼會配置DDR基地址以及DDR前期的其他初始化。在u-boot最後,通過u-boot命令”tftpboot 0x82000000 vxworks

”將VxWorks核心傳到記憶體的0x82000000地址處。

然後通過u-boot命令”bootelf 0x82000000”從0x82000000地址開始解析VxWorks映象,這個命令會呼叫u-boot中的do_bootelf並將0x82000000作為引數傳到該函式中。

int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])

{

         unsigned long addr;               /* Address of the ELF image     */

         unsigned long rc;                   /* Return value from user code  */

         char *sload, *saddr;

         int rcode = 0;

         sload = saddr = NULL;

         if (argc == 3) {

                   sload = argv[1];

                   saddr = argv[2]; //

         } else if (argc == 2) {

                   if (argv[1][0] == '-')

                            sload = argv[1];

                   else

                            saddr = argv[1];

         }

         if (saddr)

                   addr = simple_strtoul(saddr, NULL, 16); //0x82000000

         else

                   addr = load_addr;   //預設載入地址0x81000000

//校驗該地址處的核心映象檔案,判斷是否存在映象檔案,以及該檔案是否是可執行的二進位制檔案

         if (!valid_elf_image (addr)) 

                   return 1;

//解析該核心映象檔案,並將映象的入口地址(0x80020000)返回

         if (sload && sload[1] == 'p')

                   addr = load_elf_image_phdr(addr);  //0x80020000

         else

                   addr = load_elf_image_shdr(addr);

         printf ("#### Starting application at 0x%08lx ...\n", addr);

//開始執行0x80020000地址處的程式及VxWorks核心

         rc = do_bootelf_exec ((void *)addr, argc - 1, argv + 1);

         if (rc != 0)

                   rcode = 1;

         printf ("## Application terminated, rc = 0x%lx\n", rc);

         return rcode;

}


VxWorks執行時的記憶體分配,根據核心配置



可以推斷出核心在執行時的記憶體分佈:


DDR型號是MT41J128M16RE-15I,大小為256MB,定址範圍為0x800000000~0x90000000

地址與記憶體空間之間的關係是,每個地址儲存一個位元組的資料。

在系統分割槽中新增自定義分割槽

其中kernel Heap為系統記憶體分割槽,該分割槽內只有一個記憶體池,我們可以在該記憶體池中新增記憶體塊。

         當然我們也可以在系統分割槽內新增使用者定義的分割槽,新增方法如下示例:

static PART_ID  testMemoryPartId = NULL;

void mem_test()

{

    char *memoryPool;

    void * pMemory;

    static const UINT   initialSize = 3000;

    if ((memoryPool =malloc (initialSize)) == NULL)

        return ERROR;

    if ((testMemoryPartId =memPartCreate (memoryPool, initialSize)) == NULL) {

        free (memoryPool);

        return ERROR;   

}

    pMemory = memPartAlloc (testMemoryPartId, 1500);

    memPartShow (testMemoryPartId, 2);

}

記憶體分割槽、記憶體池和記憶體塊之間的關係如下: