⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkboot.c.svn-base

📁 RT-Thread是发展中的下一代微内核嵌入式实时操作系统
💻 SVN-BASE
字号:
#include <stdio.h>
#include <getopt.h>

#include "entry.h"

struct input_option
{
	unsigned long binary_address;
	int service_type;
	char filename[16];
};

int proc_hex_number(const char* str, unsigned long *value)
{
	int pos;
	int shift, t;

	pos = 0;
	if (str[pos++] != '0') return -1;
	if (str[pos] != 'x' && str[pos] != 'X') return -1;
	pos ++;

	shift = 4;
	while (str[pos] != '\0')
	{
		t = str[pos++];
		if ( t>='a' && t <='f' )
		{
			t = t - 'a' +10;
		}
		else if ( t >='A' && t <='F' )
		{
			t = t - 'A' +10;
		}
		else t = t - '0';

		*value = (*value << shift) | t;
	}

	return 0;
}

int full_write(FILE* fp, char* buffer, size_t length)
{
	size_t offset, result;

	if (fp == NULL || buffer == NULL || length == 0) return -1;
	offset = 0;

	while (offset < length)
	{
		result = fwrite(&buffer[offset], 1, length - offset, fp);
		if (result == 0) return -1;

		offset += result;
	}

	return 0;
}

int full_read(FILE* fp, char* buffer, size_t length)
{
	size_t offset, result;

	if (fp == NULL || buffer == NULL || length == 0) return -1;
	offset = 0;

	while (offset < length)
	{
		result = fread(&buffer[offset], 1, length - offset, fp);

		if (result == 0) return -1;

		offset += result;
	}

	return 0;
}

int mkservice(char* output, struct input_option* option, int count)
{
	int i;
	size_t offset;
	char buffer[512];
	struct service_description* description;
	struct service_entry* entry;

	if (count > 15) return -1;

	memset(&buffer[0], 0, sizeof(buffer));

	/* fill description */
	description = (struct service_description*) &buffer[0];

	/* set magic and count */
	description->magic[0] = 'R';
	description->magic[1] = 'T';
	description->magic[2] = 'T';
	description->magic[3] = '\0';
	description->count = count;

	entry = (struct service_entry*) &buffer[0];
	/* skip description */
	entry ++;

	offset = 0;
	for (i = 0; i < count; i++)
	{
		strncpy(&(entry->name[0]), &(option[i].filename[0]), NAME_MAX);
		entry->type = option[i].service_type;
		if (entry->type == SERVICE_TYPE_BINARY)
		{
			entry->phaddr = option[i].binary_address;
		}

		/* get file size */
		FILE* fp;

		fp = fopen(option[i].filename, "rb");
		if (fp != NULL)
		{
			fseek(fp, 0, SEEK_END);
			entry->size = ftell(fp);
			fclose(fp);
		}

		entry->offset = offset;
		/* align to 4 */
		offset += ((entry->size + 3) & ~3);

		/* increase entry */
		entry ++;
	}

	/* make output file */
	FILE* fout;
	size_t length;
	fout = fopen(output, "wb");
	if (fout != NULL)
	{
		/* write description */
		if (full_write(fout, buffer, sizeof(buffer)) == 0)
		{
			/* locate entry */
			entry = (struct service_entry*) &buffer[0];
			/* skip description */
			entry ++;
			for (i = 0; i < count; i++)
			{
				FILE* fp;
				unsigned char* ptr;

				ptr = (unsigned char*) malloc ((entry[i].size + 3) & ~3);
				if (ptr == NULL)
				{
					printf("no memory\n");
					return -1;
				}

				/* open file to read */
				fp = fopen(option[i].filename, "rb");
				if (full_read(fp, ptr, entry[i].size) != 0)
				{
					printf("read input file failed\n");
					free(ptr);
					fclose(fout);
					fclose(fp);

					return -1;
				}
				if (full_write(fout, ptr, (entry[i].size + 3) & ~3) != 0)
				{
					printf("write boot rom failed\n");
					free(ptr);
					fclose(fp);
					fclose(fout);

					return -1;
				}

				/* release memory */
				free(ptr);
				fclose(fp);
			}

			fclose(fout);
			return 0;
		}
	}
	else
	{
		printf("can't write output file\n");
	}

	return -1;
}

/* mkbootrom -o boot -b 0x8000 -f file -e -f file2 -el -f file4 -a -f file3 */
int main(int argc,char **argv)
{
	int ch;
	int input_file;

	char output[128];
	struct input_option input[16];

	/* clear output and input */
	memset(&output[0], 0, sizeof(output));
	memset(&input[0], 0, sizeof(input));

	opterr = 0;
	input_file = 0;
	while((ch = getopt(argc, argv, "aelb:o:f:h"))!= -1)
	{
		switch(ch)
		{
		case 'a':
			input[input_file].service_type = SERVICE_TYPE_ARCHIVE;
			break;

		case 'e':
			input[input_file].service_type = SERVICE_TYPE_ELF;
			break;

		case 'l':
			if (input[input_file].service_type == SERVICE_TYPE_ELF)
			{
				input[input_file].service_type = SERVICE_TYPE_ELF_LOADING;
			}
			break;

		case 'b':
			input[input_file].service_type = SERVICE_TYPE_BINARY;
			proc_hex_number(optarg, &(input[input_file].binary_address));
			break;
		
		case 'f':
			strncpy(&(input[input_file].filename[0]), optarg, 16);
			input_file ++;
			break;

		case 'o':
			if (output[0] == '\0')
			{
				strncpy(&output[0], optarg, 128);
			}
			break;

		case 'h':
			printf("Usage: mkbootrom -o boot -b 0x8000 -f file1 -e -f file2 -a -f file3\n");
			break;

		default:
			printf("other option :%c\n", ch);
		}
	}

	printf("out filename: %s\n", output);
	int i;
	for (i = 0; i < input_file; i++)
	{
		printf("input filename:%s, type: %d\n", input[i].filename, input[i].service_type);
		if (input[i].service_type == SERVICE_TYPE_BINARY)
		{
			printf("binary address: 0x%x\n", input[i].binary_address);
		}
	}

	if (mkservice(output, &input[0], input_file) != 0)
	{
		printf("make boot rom failed\n");
	}

	fflush(stdout);
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -