Files
Linux_Drivers/build/tools/common/emmc_tool/creat_pack.c
sam.xiang a4f213ceb0 [build] add cvitek build scripts
Change-Id: If63ce4a669e5d4d72b8e3b9253336dd99bf74c30
2023-03-10 20:35:59 +08:00

261 lines
5.7 KiB
C

#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include <getopt.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <libxml/parser.h>
#include "crc.h"
#define BM_PACK_HEADER_MAGIC "bm_pack"
#define BM_PACK_MAX_ITEMS (8)
#define BM_PACK_BLOCK_SIZE (512)
struct bm_pack_item {
char name[16];
uint64_t offset;
uint64_t size;
uint8_t reserved[8];
uint8_t md5[16];
};
struct bm_pack_header {
char magic[15];
uint8_t item_num;
uint32_t blksz;
struct bm_pack_item item[BM_PACK_MAX_ITEMS];
uint8_t reserved[36];
uint32_t hdr_crc;
};
struct bm_pack_header bm_header;
static const char *xml_path = ".";
static const char *output_file;
static void usage(void)
{
printf("Usage:\n");
printf("mk_package [options]\n\n"
"options:\n"
" -p, --path xml path\n"
" -o, --output output file\n"
" -h, --help display this help and exit\n");
exit(EXIT_FAILURE);
}
static void parse_commandline(int argc, char **argv)
{
int c;
static struct option long_options[] = {
{"path", 1, 0, 'p'},
{"output", 1, 0, 'o'},
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
};
while (1) {
c = getopt_long(argc, argv, "p:o:h", long_options, NULL);
if (c == -1)
break;
switch (c) {
case 'p':
xml_path = optarg;
break;
case 'o':
output_file = optarg;
break;
case 'h':
default:
usage();
}
}
if (output_file == NULL) {
fprintf(stderr, "output file : NULL\n");
usage();
}
}
char *hexstr2bin (char* out_p, const char* input_p, const int in_len)
{
int i=0;
int tc;
for (i = 0; i < in_len ; i++)
{
sscanf(input_p+i*2, "%02X", (unsigned int*)(out_p+i));
}
return out_p;
}
#define MAX_BUF_SIZE 4096
static void write_item(int o_fd, xmlNodePtr xml_node, struct bm_pack_item *item)
{
uint8_t buf[MAX_BUF_SIZE];
xmlChar *prop = NULL;
uint64_t size = 0;
static int i = 0;
int i_fd = -1, err = -1;
prop = xmlGetProp(xml_node, BAD_CAST"name");
if (prop == NULL) {
fprintf(stderr, "name is NULL\n");
exit(-1);
}
strncpy(item->name, prop, sizeof(item->name));
xmlFree(prop);
prop = xmlGetProp(xml_node, BAD_CAST"path");
if (prop == NULL) {
fprintf(stderr, "path is NULL\n");
exit(-1);
}
i_fd = open(prop, O_RDWR);
if (i_fd < 0) {
fprintf(stderr, "open %s error\n", prop);
exit(-1);
}
item->offset = lseek64(o_fd, 0, SEEK_CUR);
while (1) {
err = read(i_fd, buf, sizeof(buf));
if (err < 0) {
fprintf(stderr, "read %s error\n", prop);
exit(-1);
}
size += err;
if (err == 0) {
break;
}
err = write(o_fd, buf, err);
if (err < 0) {
fprintf(stderr, "write %s error\n", prop);
exit(-1);
}
}
memset(buf, 0, sizeof(buf));
write(o_fd, buf, BM_PACK_BLOCK_SIZE - (size & (BM_PACK_BLOCK_SIZE - 1)));
item->size = size;
xmlFree(prop);
close(i_fd);
prop = xmlGetProp(xml_node, BAD_CAST"md5");
if (prop == NULL) {
fprintf(stderr, "md5 is NULL\n");
exit(-1);
}
printf("%s\n", prop);
hexstr2bin(item->md5, prop, sizeof(item->md5));
xmlFree(prop);
}
int main(int argc, char **argv)
{
int ret = -1;
int fd = -1;
uint64_t size = 0;
xmlDocPtr xml_doc = NULL;
xmlNodePtr xml_node = NULL;
xmlChar *prop = NULL;
char file_name[PATH_MAX];
parse_commandline(argc, argv);
printf("xml_path : %s\n", xml_path);
printf("output_file : %s\n", output_file);
fd = open(output_file, O_CREAT | O_TRUNC | O_RDWR | O_LARGEFILE, 0666);
if (fd < 0) {
fprintf(stderr, "open %s error\n", output_file);
goto RETURN;
}
memset((void *)&bm_header, 0, sizeof(bm_header));
strcpy(bm_header.magic, BM_PACK_HEADER_MAGIC);
bm_header.blksz = BM_PACK_BLOCK_SIZE;
if (bm_header.blksz < sizeof(bm_header)) {
printf("block size must bigger than package header struct!!!\n");
return -1;
}
lseek64(fd, bm_header.blksz, SEEK_SET);
snprintf(file_name, PATH_MAX, "%s/package.xml", xml_path);
xml_doc = xmlReadFile(file_name, "UTF-8", XML_PARSE_RECOVER);
if (xml_doc == NULL) {
fprintf(stderr, "xmlReadFile %s error\n", file_name);
goto RETURN;
}
xml_node = xmlDocGetRootElement(xml_doc);
while (xml_node != NULL) {
if (xml_node->type == XML_ELEMENT_NODE)
if (strcmp("header",
(char *)xml_node->name) == 0) {
prop = xmlGetProp(xml_node, BAD_CAST"time");
if (prop != NULL) {
printf("[hq] create time:%s\n", prop);
xmlFree(prop);
}
break;
}
xml_node = xml_node->next;
}
if (!xml_node) {
fprintf(stderr, "find xml header failed\n");
goto RETURN;
}
xml_node = xml_node->xmlChildrenNode;
while (xml_node != NULL) {
if (xml_node->type == XML_ELEMENT_NODE) {
if (strcmp("item", (char *)xml_node->name) == 0) {
write_item(fd, xml_node, &bm_header.item[bm_header.item_num]);
bm_header.item_num++;
}
else
printf("unknown node %s\n", xml_node->name);
}
xml_node = xml_node->next;
}
bm_header.hdr_crc = crc32(0, (uint8_t *)&bm_header, sizeof(bm_header) - sizeof(bm_header.hdr_crc));
lseek64(fd, 0, SEEK_SET);
write(fd, &bm_header, sizeof(bm_header));
printf("\n");
printf("header->magic:%s\n", bm_header.magic);
printf("header->item_num:0x%x\n", bm_header.item_num);
printf("header->hdr_crc32:0x%x\n", bm_header.hdr_crc);
printf("\n");
struct bm_pack_item *item_ptr = NULL;
for (int i = 0; i < bm_header.item_num; ++i) {
item_ptr = &bm_header.item[i];
printf("\titem->name:%s\n", item_ptr->name);
printf("\titem->size:0x%lx\n", item_ptr->size);
printf("\titem->offset:0x%lx\n", item_ptr->offset);
printf("\titem->md5:");
for (int j = 0; j < sizeof(item_ptr->md5); ++j) {
printf("%x", item_ptr->md5[j]);
}
printf("\n");
printf("\n");
}
RETURN:
if (xml_doc != NULL)
xmlFreeDoc(xml_doc);
if (fd >= 0)
close(fd);
return ret;
}