📄 mkboot.c.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 + -