OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [disk/] [tools/] [mkpart/] [mkpart.c] - Blame information for rev 23

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 17 hellwig
/*
2
 * mkpart.c -- make partitions on a disk
3
 */
4
 
5
 
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
#include <stdarg.h>
10
 
11
 
12
#define SECTOR_SIZE     512
13
#define NPE             (SECTOR_SIZE / sizeof(PartEntry))
14
#define DESCR_SIZE      20
15
 
16
#define LINE_SIZE       100
17
 
18
 
19
unsigned char buf[32 * SECTOR_SIZE];
20
 
21
 
22
typedef struct {
23
  unsigned long type;
24
  unsigned long start;
25
  unsigned long size;
26
  char descr[DESCR_SIZE];
27
} PartEntry;
28
 
29
PartEntry ptr[NPE];
30
 
31
 
32
/**************************************************************/
33
 
34
 
35
void error(char *fmt, ...) {
36
  va_list ap;
37
 
38
  va_start(ap, fmt);
39
  printf("Error: ");
40
  vprintf(fmt, ap);
41
  printf("\n");
42
  va_end(ap);
43
  exit(1);
44
}
45
 
46
 
47
/**************************************************************/
48
 
49
 
50
void convertNumber(unsigned char *p, unsigned long val) {
51
  *(p + 0) = val >> 24;
52
  *(p + 1) = val >> 16;
53
  *(p + 2) = val >>  8;
54
  *(p + 3) = val >>  0;
55
}
56
 
57
 
58
void convertPartitionTable(PartEntry *e, int n) {
59
  int i;
60
  unsigned char *p;
61
 
62
  for (i = 0; i < n; i++) {
63
    p = (unsigned char *) &e[i];
64
    convertNumber(p + 0, e[i].type);
65
    convertNumber(p + 4, e[i].start);
66
    convertNumber(p + 8, e[i].size);
67
  }
68
}
69
 
70
 
71
/**************************************************************/
72
 
73
 
74
int parseNumber(char **pc, unsigned long *pi) {
75
  char *p;
76
  unsigned int base, dval;
77
  unsigned long n;
78
 
79
  p = *pc;
80
  while (*p == ' ' || *p == '\t') {
81
    p++;
82
  }
83
  if (*p == '\0' || *p == '\n') {
84
    printf("Error: number is missing!\n");
85
    return 0;
86
  }
87
  base = 10;
88
  if (*p == '0') {
89
    p++;
90
    if (*p != '\0' && *p != '\n') {
91
      if (*p == 'x' || *p == 'X') {
92
        base = 16;
93
        p++;
94
      } else {
95
        base = 8;
96
      }
97
    }
98
  }
99
  n = 0;
100
  while ((*p >= '0' && *p <= '9') ||
101
         (*p >= 'a' && *p <= 'f') ||
102
         (*p >= 'A' && *p <= 'F')) {
103
    if (*p >= '0' && *p <= '9') {
104
      dval = (*p - '0');
105
    } else
106
    if (*p >= 'a' && *p <= 'f') {
107
      dval = (*p - 'a' + 10);
108
    } else
109
    if (*p >= 'A' && *p <= 'F') {
110
      dval = (*p - 'A' + 10);
111
    }
112
    if (dval >= base) {
113
      printf("Error: digit value %d is illegal in number base %d\n",
114
             dval, base);
115
      return 0;
116
    }
117
    n *= base;
118
    n += dval;
119
    p++;
120
  }
121
  while (*p == ' ' || *p == '\t') {
122
    p++;
123
  }
124
  *pc = p;
125
  *pi = n;
126
  return 1;
127
}
128
 
129
 
130
int parseString(char **pc, char *dst) {
131
  char *p;
132
 
133
  p = *pc;
134
  while (*p == ' ' || *p == '\t') {
135
    p++;
136
  }
137
  if (*p != '\"') {
138
    return 0;
139
  }
140
  p++;
141
  while (*p != '\"' && *p != '\0' && *p != '\n') {
142
    *dst++ = *p++;
143
  }
144
  if (*p != '\"') {
145
    return 0;
146
  }
147
  p++;
148
  while (*p == ' ' || *p == '\t') {
149
    p++;
150
  }
151
  *pc = p;
152
  *dst = '\0';
153
  return 1;
154
}
155
 
156
 
157
/**************************************************************/
158
 
159
 
160
int main(int argc, char *argv[]) {
161
  char *diskName;
162
  char *confName;
163
  FILE *disk;
164
  FILE *conf;
165
  unsigned long diskSize;
166
  unsigned long numSectors;
167
  char line[LINE_SIZE];
168
  char *p, *q;
169
  int lineNumber;
170
  FILE *mbootblk;
171
  long mbootblkSize;
172
  int i;
173
  unsigned long partNum;
174
  unsigned long bootable;
175
  unsigned long partType;
176
  unsigned long partStart;
177
  unsigned long partLast;
178
  unsigned long partSize;
179
  char descr[LINE_SIZE];
180
 
181
  /* check command line arguments */
182
  if (argc != 3) {
183
    printf("Usage: %s <disk image file> <configuration file>\n", argv[0]);
184
    exit(1);
185
  }
186
  diskName = argv[1];
187
  confName = argv[2];
188
  /* determine disk size */
189
  disk = fopen(diskName, "rb");
190
  if (disk == NULL) {
191
    error("cannot open disk image '%s'", diskName);
192
  }
193
  fseek(disk, 0, SEEK_END);
194
  diskSize = ftell(disk);
195
  numSectors = diskSize / SECTOR_SIZE;
196
  fclose(disk);
197
  printf("Disk '%s' has %lu (0x%lX) sectors.\n",
198
         diskName, numSectors, numSectors);
199
  if (numSectors < 32) {
200
    error("disk is too small");
201
  }
202
  if (diskSize % SECTOR_SIZE != 0) {
203
    printf("Warning: disk size is not a multiple of sector size!\n");
204
  }
205
  /* create partition table */
206
  conf = fopen(confName, "rt");
207
  if (conf == NULL) {
208
    error("cannot open configuration file '%s'", confName);
209
  }
210
  lineNumber = 0;
211
  /* first, handle master boot block specification */
212
  while (fgets(line, LINE_SIZE, conf) != NULL) {
213
    lineNumber++;
214
    p = line;
215
    while (*p == ' ' || *p == '\t') {
216
      p++;
217
    }
218
    if (*p == '\0' || *p == '\n' || *p == '#') {
219
      continue;
220
    }
221
    q = p;
222
    while (*q > 0x20 && *q < 0x7F) {
223
      q++;
224
    }
225
    *q = '\0';
226
    if (strcmp(p, "-noboot-") == 0) {
227
      /* master boot block not wanted */
228
    } else {
229
      /* p points to name of master boot block file */
230
      mbootblk = fopen(p, "rb");
231
      if (mbootblk == NULL) {
232
        error("cannot open master boot block file '%s'", p);
233
      }
234
      fseek(mbootblk, 0, SEEK_END);
235
      mbootblkSize = ftell(mbootblk);
236
      fseek(mbootblk, 0, SEEK_SET);
237
      if (mbootblkSize > 32 * SECTOR_SIZE) {
238
        error("master boot block file '%s' is bigger than 32 sectors", p);
239
      }
240
      for (i = 0; i < 32 * SECTOR_SIZE; i++) {
241
        buf[i] = '\0';
242
      }
243
      if (fread(buf, 1, mbootblkSize, mbootblk) != mbootblkSize) {
244
        error("cannot read master boot block file '%s'", p);
245
      }
246
      fclose(mbootblk);
247
      disk = fopen(diskName, "r+b");
248
      if (disk == NULL) {
249
        error("cannot open disk image '%s'", diskName);
250
      }
251
      if (fwrite(buf, 1, 32 * SECTOR_SIZE, disk) != 32 * SECTOR_SIZE) {
252
        error("cannot write master boot block to disk image '%s'", diskName);
253
      }
254
      fclose(disk);
255
    }
256
    break;
257
  }
258
  /* then, handle partition table entries */
259
  while (fgets(line, LINE_SIZE, conf) != NULL) {
260
    lineNumber++;
261
    p = line;
262
    while (*p == ' ' || *p == '\t') {
263
      p++;
264
    }
265
    if (*p == '\0' || *p == '\n' || *p == '#') {
266
      continue;
267
    }
268
    if (!parseNumber(&p, &partNum)) {
269
      error("cannot read partition number in config file '%s', line %d",
270
            confName, lineNumber);
271
    }
272
    if (partNum >= 16) {
273
      error("illegal partition number in config file '%s', line %d",
274
            confName, lineNumber);
275
    }
276
    if (*p == '*') {
277
      p++;
278
      bootable = 0x80000000;
279
    } else {
280
      bootable = 0x00000000;
281
    }
282
    if (!parseNumber(&p, &partType)) {
283
      error("cannot read partition type in config file '%s', line %d",
284
            confName, lineNumber);
285
    }
286
    if ((partType & 0x80000000) != 0) {
287
      error("illegal partition type in config file '%s', line %d",
288
            confName, lineNumber);
289
    }
290
    if (!parseNumber(&p, &partStart)) {
291
      error("cannot read start sector in config file '%s', line %d",
292
            confName, lineNumber);
293
    }
294
    if (partStart < 32 || partStart >= numSectors) {
295
      error("illegal start sector in config file '%s', line %d",
296
            confName, lineNumber);
297
    }
298
    if (!parseNumber(&p, &partLast)) {
299
      error("cannot read last sector in config file '%s', line %d",
300
            confName, lineNumber);
301
    }
302
    if (partLast < partStart || partLast >= numSectors) {
303
      error("illegal last sector in config file '%s', line %d",
304
            confName, lineNumber);
305
    }
306
    partSize = partLast - partStart + 1;
307
    if (!parseString(&p, descr)) {
308
      error("cannot read description in config file '%s', line %d",
309
            confName, lineNumber);
310
    }
311
    if (strlen(descr) >= DESCR_SIZE) {
312
      error("description too long in config file '%s', line %d",
313
            confName, lineNumber);
314
    }
315
    if (partType != 0) {
316
      ptr[partNum].type = bootable | partType;
317
      ptr[partNum].start = partStart;
318
      ptr[partNum].size = partSize;
319
      memset(ptr[partNum].descr, 0, DESCR_SIZE);
320
      strcpy(ptr[partNum].descr, descr);
321
    } else {
322
      ptr[partNum].type = 0;
323
      ptr[partNum].start = 0;
324
      ptr[partNum].size = 0;
325
      memset(ptr[partNum].descr, 0, DESCR_SIZE);
326
    }
327
  }
328
  fclose(conf);
329
  /* next, show partition table */
330
  printf("Partitions:\n");
331
  printf(" # b type       start      last       size       description\n");
332
  for (partNum = 0; partNum < NPE; partNum++) {
333
    if (ptr[partNum].type != 0) {
334
      partLast = ptr[partNum].start + ptr[partNum].size - 1;
335
    } else {
336
      partLast = 0;
337
    }
338
    printf("%2lu %s 0x%08lX 0x%08lX 0x%08lX 0x%08lX %s\n",
339
           partNum,
340
           ptr[partNum].type & 0x80000000 ? "*" : " ",
341
           ptr[partNum].type & 0x7FFFFFFF,
342
           ptr[partNum].start,
343
           partLast,
344
           ptr[partNum].size,
345
           ptr[partNum].descr);
346
  }
347
  /* finally, write partition table record */
348
  convertPartitionTable(ptr, NPE);
349
  disk = fopen(diskName, "r+b");
350
  if (disk == NULL) {
351
    error("cannot open disk image '%s'", diskName);
352
  }
353
  fseek(disk, 1 * SECTOR_SIZE, SEEK_SET);
354
  if (fwrite(ptr, 1, SECTOR_SIZE, disk) != SECTOR_SIZE) {
355
    error("cannot write partition table to disk image '%s'", diskName);
356
  }
357
  fclose(disk);
358
  /* done */
359
  return 0;
360
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.