共8条
1/1															1							跳转至页
		[原创]vxworks压缩技术
 
					
				
															
	在嵌入式系统中,我们通常会要求vxworks这个文件尽量的小,比如通过串口、软盘或tffs加载vxworks的时候,如果文件太大,可能无法存储,或加载失败。下面介绍一种利用Tornado和vxworks自带的deflate和inflate,对vxworks文件进行压缩和解压缩的技术。希望对大家有所帮助。
1  使用Tornado创建bootable的project,包括应用程序。对vxworks进行适当的裁减和配置。
2  如果准备将vxworks存储于硬盘,软盘或tffs上,应该在usrAppInit中使用usrNetEndDevStart和usrNetIfConfig启动网络接口。如果存储于tffs上,还要修改usrNetBoot.c中:
    if ( (strncmp (sysBootParams.bootDev, "scsi", 4) == 0) 
	|| (strncmp (sysBootParams.bootDev, "ide", 3) == 0) 
	|| (strncmp (sysBootParams.bootDev, "ata", 3) == 0) 
	|| (strncmp (sysBootParams.bootDev, "fd", 2) == 0))
  为:
    if ( (strncmp (sysBootParams.bootDev, "scsi", 4) == 0) 
	|| (strncmp (sysBootParams.bootDev, "ide", 3) == 0) 
	|| (strncmp (sysBootParams.bootDev, "ata", 3) == 0) 
	|| (strncmp (sysBootParams.bootDev, "tffs", 4) == 0) 
	|| (strncmp (sysBootParams.bootDev, "fd", 2) == 0))
3  在dos下运行 tornado/host/x86-win32/bin/torvars。
4  进入vxworks所在的目录,运行:
   deflate  vxWorks.z。这里我们默认.z文件是压缩文件。
5  如果准备将vxworks.z存储于硬盘,软盘或tffs上,需要首先创建相应的设备,并用dosFS初始化。如果是通过串口或网络加载vxworks.z,则需要初始化相应的接口。
6  修改bootConfig.c文件:
   a. 在LOCAL STATUS netLoad 函数的 tftpXfer和 ftpXfer这一部分代码结束的地方添加:
    if ( strstr(fileName,".z") || strstr(fileName,".Z") )
    {        
	printf("\nfile %s is compressed, now begin uncompressing...\n",fileName);
	if (bootLoadModuleInflate(fd, pEntry) != OK)
	    goto readErr;
    }
    else if (bootLoadModule (fd, pEntry) != OK)
	goto readErr;
   b. 在 LOCAL STATUS tffsLoad 函数的 usrTffsConfig和open这一部分代码结束的地方添加:
    if ( strstr(fileName,".z") || strstr(fileName,".Z") )
    {        
	printf("\nfile %s is compressed, now begin uncompressing...\n",fileName);
	if (bootLoadModuleInflate(fd, pEntry) != OK)
	    goto readErr;
    }
    else if (bootLoadModule (fd, pEntry) != OK)
	goto readErr;
   c. 在 LOCAL STATUS bootLoad 函数之前定义函数 bootLoadModuleInflate的原型:
	#define DECOMP_BUF_SIZE		(RAM_HIGH_ADRS - RAM_LOW_ADRS)
	#define COMP_BUF_SIZE		(DECOMP_BUF_SIZE / 3)
	STATUS bootLoadModuleInflate(int zfd, FUNCPTR *pEntry)
	{
	    char	*imageBuf = NULL;
	    char	*compBuf = NULL;
	    int			fd = -1;
	    int			rv = ERROR;
	    int			compSize, r;
	    extern STATUS	inflate(char *src, char *dst, int src_size);
	    if ((compBuf = malloc(COMP_BUF_SIZE)) == NULL) 
	    {
		printErr("No enough memory for image buffer\n");
		goto done;
	    }
	    compSize = 0;
	    while ((r = read(zfd, compBuf + compSize, COMP_BUF_SIZE - compSize)) > 0)
		compSize += r;
	    if (r < 0) 
	    {
		printErr("Read failed: errno = %d\n", errnoGet());
		goto done;
	    }
	    if (compSize == COMP_BUF_SIZE) 
	    {
		printErr("Compressed image too large\n");
		goto done;
	    }
	    printErr("Uncompressing %d bytes... ", compSize);
	    if ((imageBuf = malloc(DECOMP_BUF_SIZE)) == NULL) 
	    {
		printErr("Not enough memory for decompression buffer\n");
		goto done;
	    }
	    if ((r = inflate(compBuf, imageBuf, compSize)) < 0) 
	    {
		printErr("\nUncompress failed\n");
		goto done;
	    }
	    printErr("\nLoading image... ");
	    memDrv();
	    memDevCreate("mem:", imageBuf, DECOMP_BUF_SIZE);
	    if ((fd = open("mem:0", O_RDONLY, 0)) < 0) 
	    {
		printErr("\nCannot open memory device.\n");
		goto done;
	    }
	    if (bootLoadModule(fd, pEntry) != OK) 
	    {
		printErr("\nError loading: errno = %d\n", errnoGet());
		goto done;
	    }
	    printErr("\n");
	    rv = OK;
	 done:
	    if (fd >= 0)
		close(fd);
	    if (imageBuf)
		free(imageBuf);
	    if (compBuf)
		free(compBuf);
	    return rv;
	}
     d. 如果加载不成功,应读懂上一段代码,调整 RAM_HIGH_ADRS 和 RAM_LOW_ADRS的大小。
7  修改 config.h中的启动参数,比如启动设备为tffs=0,0(0,0),文件名为/tffs0/vxworks.z等等,重新制作bootrom,并写入flash。
8  启动时,修改启动参数,使系统仍然从网络加载vxworks,这个vxworks中应该实现了ftp或tftp功能。通过这些功能,把vxworks.z文件写入存储介质如tffs中。
9  重新启动从tffs或硬盘,软盘加载vxworks,即可成功。
10 可以首先通过网络启动,把启动文件名改为 vxworks.z来进行验证压缩和解压缩。
11 以上只是考虑了从网络和tffs来加载vxworks.z压缩文件,如果从fd, ata等加载,只需在相应地方添加和6.a中相同的代码即可。
12 本方法在ppc850上,利用tffs和网络加载进行了验证,完全适用。
										 
					
					
							
					
										
					
										关键词: 原创 vxworks 压缩 技术
 
					
				
															
	[quote][b]以下是引用[i]小容儿在2003-4-23 10:55:12[/i]的发言:[/b]
好啊!又学了一招。谢谢gem2000斑竹!
 不过我有个问题,在从存储设备调入和解压缩vxworks.z时,用了两次malloc() ,分配的内存达到(RAM_HIGH_ADRS - RAM_LOW_ADRS) * 4/3,也就是说大于(RAM_HIGH_ADRS - RAM_LOW_ADRS),可动态分配内存(堆?)一般会有这么大么?
[/quote] 其实只用了 1/3,第二次就是存放解压缩后的vxworks,其实用通常的方式加载,也会需要这一部分内存空间。此外,代码中使用了一个技巧,就是ram disk的使用方法。仔细领会一下。										
					
					
							
					
					 
					
				
															
	[quote][b]以下是引用[i]yong2000在2003-4-25 15:24:33[/i]的发言:[/b]
我这里有个问题,希望gem2000指点一下!
 我看了你的文章,试了一下,碰到这个问题:如果使用malloc分配内存,发现分配的内存不能超过1MB,如果超过了会出现memPartMalloc错误!
 我的target是x86,使用vxworks5.4!
 另外,难道每次使用的时候必须把全部的vxworks.z掉进内存才行吗??
[/quote]前面我讲了,可能没有引起你的注意,就是 RAM_HIGH_ADDR和RAM_LOW_ADDR的定义,在它们之间留出一定的空间。比如你的vxworks文件有2M,deflate的压缩率为67%,那么你需要留出 2.6M的空间,定义为3M就比较合适。修改完这两个定义后,重新作bootrom就可以了。
因为inflate解压缩的过程是在内存中完成,肯定要把vxworks.z调进内存。										
					
					
							
					
					共8条
1/1															1							跳转至页
		回复
| 有奖活动 | |
|---|---|
| 硬核工程师专属补给计划——填盲盒 | |
| “我踩过的那些坑”主题活动——第002期 | |
| 【EEPW电子工程师创研计划】技术变现通道已开启~ | |
| 发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
| 【EEPW在线】E起听工程师的声音! | |
| 高校联络员开始招募啦!有惊喜!! | |
| 【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
| 送您一块开发板,2025年“我要开发板活动”又开始了! | |


 
			
			
			
						
			 
					
				 我要赚赏金
 我要赚赏金 STM32
STM32 MCU
MCU 通讯及无线技术
通讯及无线技术 物联网技术
物联网技术 电子DIY
电子DIY 板卡试用
板卡试用 基础知识
基础知识 软件与操作系统
软件与操作系统 我爱生活
我爱生活 小e食堂
小e食堂

