diff miscprog/grokdsn.c @ 191:0c631396b8ce

started grokdsn utility, parses header successfully
author Michael Spacefalcon <falcon@ivan.Harhan.ORG>
date Wed, 07 Jan 2015 06:55:33 +0000
parents
children 5d84f63eff72
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscprog/grokdsn.c	Wed Jan 07 06:55:33 2015 +0000
@@ -0,0 +1,128 @@
+/*
+ * We have TI's Leonardo reference schematics in the form of 3 different PDF
+ * versions and an OrCAD DSN file corresponding to one of them.  The latter
+ * appears (based on a cursory strings(1) inspection) to contain more
+ * juicy information than is present in the PDF prints.  We need to extract
+ * as much of this information as we can in order to replicate the lost
+ * Leonardo board as closely as possible.
+ *
+ * The top level structure of this DSN file appears to be Microsoft CDF.
+ * Therefore, I shall begin by parsing this "archive" structure and
+ * extracting the individual files contained therein, in an effort to gain
+ * more insight as to what goes with what than can be gleaned from strings(1)
+ * on the raw DSN file.  This hack-utility is my CDF parser written for
+ * this specific purpose.
+ */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <endian.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <strings.h>
+
+#define	HEADER_MFAT_ENTRIES	109
+struct cdf_header {
+	u_char		magic[8];
+	u_char		uid[16];
+	uint16_t	fmt_minor;
+	uint16_t	fmt_major;
+	uint16_t	byte_order;
+	uint16_t	sector_size;
+	uint16_t	subsec_size;
+	u_char		rsvd1[10];
+	uint32_t	fat_sectors;
+	uint32_t	dir_start;
+	u_char		rsvd2[4];
+	uint32_t	min_large_file;
+	uint32_t	subfat_start;
+	uint32_t	subfat_sectors;
+	uint32_t	mfat_start;
+	uint32_t	mfat_sectors;
+	uint32_t	fat_secids[HEADER_MFAT_ENTRIES];
+};
+
+char *dsnfilename;
+u_char *filemapping;
+struct cdf_header *cdf_header;
+unsigned total_sectors;
+
+open_and_mmap_file()
+{
+	int fd;
+	struct stat st;
+
+	fd = open(dsnfilename, O_RDONLY);
+	if (fd < 0) {
+		perror(dsnfilename);
+		exit(1);
+	}
+	fstat(fd, &st);
+	if (!S_ISREG(st.st_mode)) {
+		fprintf(stderr, "error: %s is not a regular file\n",
+			dsnfilename);
+		exit(1);
+	}
+	if (st.st_size < 512) {
+		fprintf(stderr, "error: %s is shorter than 512 bytes\n",
+			dsnfilename);
+		exit(1);
+	}
+	if (st.st_size % 512) {
+		fprintf(stderr, "error: %s is not a multiple of 512 bytes\n",
+			dsnfilename);
+		exit(1);
+	}
+	filemapping = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+	if (filemapping == MAP_FAILED) {
+		perror("mmap");
+		exit(1);
+	}
+	close(fd);
+	cdf_header = (struct cdf_header *) filemapping;
+	total_sectors = st.st_size / 512 - 1;
+	return(0);
+}
+
+dump_cdf_header()
+{
+	printf("Magic: %02X %02X %02X %02X %02X %02X %02X %02X\n",
+		cdf_header->magic[0], cdf_header->magic[1],
+		cdf_header->magic[2], cdf_header->magic[3],
+		cdf_header->magic[4], cdf_header->magic[5],
+		cdf_header->magic[6], cdf_header->magic[7]);
+	printf("Format version: %04X.%04X\n", le16toh(cdf_header->fmt_major),
+		le16toh(cdf_header->fmt_minor));
+	printf("Sector / subsector shift: %u / %u\n",
+		le16toh(cdf_header->sector_size),
+		le16toh(cdf_header->subsec_size));
+	printf("Total FAT sectors: %u\n", le32toh(cdf_header->fat_sectors));
+	printf("Directory start sector: %u\n", le32toh(cdf_header->dir_start));
+	printf("File size threshold: %u\n",
+		le32toh(cdf_header->min_large_file));
+	return(0);
+}
+
+main(argc, argv)
+	char **argv;
+{
+	if (sizeof(struct cdf_header) != 512) {
+		fprintf(stderr, "error: struct cdf_header is misdefined\n");
+		exit(1);
+	}
+	if (argc != 3) {
+		fprintf(stderr, "usage: %s binfile.dsn <operation>\n", argv[0]);
+		exit(1);
+	}
+	dsnfilename = argv[1];
+	open_and_mmap_file();
+	if (!strcmp(argv[2], "hdr"))
+		return dump_cdf_header();
+	fprintf(stderr, "error: \"%s\" is not a recognized command\n", argv[2]);
+	exit(1);
+}