URL
https://opencores.org/ocsvn/eco32/eco32/trunk
Subversion Repositories eco32
[/] [eco32/] [trunk/] [stdalone/] [mkpart/] [mkptbl/] [mkptbl.c] - Rev 50
Go to most recent revision | Compare with Previous | Blame | View Log
/* * mkptbl.c -- make partition table */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #define SECTOR_SIZE 512 #define NPE (SECTOR_SIZE / sizeof(PartEntry)) #define DESCR_SIZE 20 #define LINE_SIZE 100 typedef struct { unsigned long type; unsigned long start; unsigned long size; char descr[DESCR_SIZE]; } PartEntry; PartEntry ptr[NPE]; void error(char *fmt, ...) { va_list ap; va_start(ap, fmt); printf("Error: "); vprintf(fmt, ap); printf("\n"); va_end(ap); exit(1); } void convertNumber(unsigned char *p, unsigned long val) { *(p + 0) = val >> 24; *(p + 1) = val >> 16; *(p + 2) = val >> 8; *(p + 3) = val >> 0; } void convertPartitionTable(PartEntry *e, int n) { int i; unsigned char *p; for (i = 0; i < n; i++) { p = (unsigned char *) &e[i]; convertNumber(p + 0, e[i].type); convertNumber(p + 4, e[i].start); convertNumber(p + 8, e[i].size); } } int parseNumber(char **pc, unsigned long *pi) { char *p; unsigned int base, dval; unsigned long n; p = *pc; while (*p == ' ' || *p == '\t') { p++; } if (*p == '\0' || *p == '\n') { printf("Error: number is missing!\n"); return 0; } base = 10; if (*p == '0') { p++; if (*p != '\0' && *p != '\n') { if (*p == 'x' || *p == 'X') { base = 16; p++; } else { base = 8; } } } n = 0; while ((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F')) { if (*p >= '0' && *p <= '9') { dval = (*p - '0'); } else if (*p >= 'a' && *p <= 'f') { dval = (*p - 'a' + 10); } else if (*p >= 'A' && *p <= 'F') { dval = (*p - 'A' + 10); } if (dval >= base) { printf("Error: digit value %d is illegal in number base %d\n", dval, base); return 0; } n *= base; n += dval; p++; } while (*p == ' ' || *p == '\t') { p++; } *pc = p; *pi = n; return 1; } int parseString(char **pc, char *dst) { char *p; p = *pc; while (*p == ' ' || *p == '\t') { p++; } if (*p != '\"') { return 0; } p++; while (*p != '\"' && *p != '\0' && *p != '\n') { *dst++ = *p++; } if (*p != '\"') { return 0; } p++; while (*p == ' ' || *p == '\t') { p++; } *pc = p; *dst = '\0'; return 1; } int main(int argc, char *argv[]) { char *confName; char *outName; FILE *conf; FILE *out; char line[LINE_SIZE]; char *p; int lineNumber; unsigned long partNum; unsigned long bootable; unsigned long partType; unsigned long partStart; unsigned long partLast; unsigned long partSize; char descr[LINE_SIZE]; /* check command line arguments */ if (argc != 3) { printf("Usage: %s <configuration file> <output file>\n", argv[0]); exit(1); } confName = argv[1]; outName = argv[2]; /* create partition table */ conf = fopen(confName, "rt"); if (conf == NULL) { error("cannot open configuration file '%s'", confName); } lineNumber = 0; /* handle partition table entries */ while (fgets(line, LINE_SIZE, conf) != NULL) { lineNumber++; p = line; while (*p == ' ' || *p == '\t') { p++; } if (*p == '\0' || *p == '\n' || *p == '#') { continue; } if (!parseNumber(&p, &partNum)) { error("cannot read partition number in config file '%s', line %d", confName, lineNumber); } if (partNum >= 16) { error("illegal partition number in config file '%s', line %d", confName, lineNumber); } if (*p == '*') { p++; bootable = 0x80000000; } else { bootable = 0x00000000; } if (!parseNumber(&p, &partType)) { error("cannot read partition type in config file '%s', line %d", confName, lineNumber); } if ((partType & 0x80000000) != 0) { error("illegal partition type in config file '%s', line %d", confName, lineNumber); } if (!parseNumber(&p, &partStart)) { error("cannot read start sector in config file '%s', line %d", confName, lineNumber); } if (partStart < 32) { error("illegal start sector in config file '%s', line %d", confName, lineNumber); } if (!parseNumber(&p, &partLast)) { error("cannot read last sector in config file '%s', line %d", confName, lineNumber); } if (partLast < partStart) { error("illegal last sector in config file '%s', line %d", confName, lineNumber); } partSize = partLast - partStart + 1; if (!parseString(&p, descr)) { error("cannot read description in config file '%s', line %d", confName, lineNumber); } if (strlen(descr) >= DESCR_SIZE) { error("description too long in config file '%s', line %d", confName, lineNumber); } if (partType != 0) { ptr[partNum].type = bootable | partType; ptr[partNum].start = partStart; ptr[partNum].size = partSize; memset(ptr[partNum].descr, 0, DESCR_SIZE); strcpy(ptr[partNum].descr, descr); } else { ptr[partNum].type = 0; ptr[partNum].start = 0; ptr[partNum].size = 0; memset(ptr[partNum].descr, 0, DESCR_SIZE); } } fclose(conf); /* next, show partition table */ printf("Partitions:\n"); printf(" # b type start last size description\n"); for (partNum = 0; partNum < NPE; partNum++) { if (ptr[partNum].type != 0) { partLast = ptr[partNum].start + ptr[partNum].size - 1; } else { partLast = 0; } printf("%2lu %s 0x%08lX 0x%08lX 0x%08lX 0x%08lX %s\n", partNum, ptr[partNum].type & 0x80000000 ? "*" : " ", ptr[partNum].type & 0x7FFFFFFF, ptr[partNum].start, partLast, ptr[partNum].size, ptr[partNum].descr); } /* finally, write partition table to output file */ convertPartitionTable(ptr, NPE); out = fopen(outName, "wb"); if (out == NULL) { error("cannot open output file '%s'", outName); } if (fwrite(ptr, 1, SECTOR_SIZE, out) != SECTOR_SIZE) { error("cannot write partition table to output file '%s'", outName); } fclose(out); /* done */ return 0; }
Go to most recent revision | Compare with Previous | Blame | View Log