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); } |
内存分区、内存池和内存块之间的关系如下: