diff pirollback/init.c @ 42:15c2ac2c5c73

pirollback: started
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sat, 06 Jul 2013 20:16:34 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pirollback/init.c	Sat Jul 06 20:16:34 2013 +0000
@@ -0,0 +1,113 @@
+#include <sys/types.h>
+#include <sys/file.h>
+#include <endian.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "types.h"
+#include "struct.h"
+
+u8 blank_flash_line[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+			   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+char *imgfile;
+u8 image[0x480000];
+struct inode_info inode[0x4000];
+int last_inode;
+
+static u8 magichdr_first[9] = {'F','f','s','#', 0x10, 0x02, 0xFF, 0xFF, 0xAB};
+static u8 magichdr_mid[9]   = {'F','f','s','#', 0x10, 0x02, 0xFF, 0xFF, 0xBD};
+static u8 magichdr_last[9]  = {'F','f','s','#', 0x10, 0x02, 0xFF, 0xFF, 0xBF};
+
+read_img_file()
+{
+	int i, fd, cc;
+	u8 *blk, *compare;
+
+	fd = open(imgfile, O_RDONLY);
+	if (fd < 0) {
+		perror(imgfile);
+		exit(1);
+	}
+	cc = read(fd, image, sizeof image);
+	close(fd);
+	if (cc != sizeof image) {
+inv:		fprintf(stderr,
+		"%s does not appear to be a \"virgin\" Pirelli FFS image\n",
+			imgfile);
+		exit(1);
+	}
+	for (i = 0; i < 18; i++) {
+		blk = image + i * 0x40000;
+		if (i == 0)
+			compare = magichdr_first;
+		else if (i == 17)
+			compare = magichdr_last;
+		else
+			compare = magichdr_mid;
+		if (bcmp(blk, compare, 9))
+			goto inv;
+	}
+}
+
+static int
+convert_ptr(ptr, ino, which)
+	int ptr, ino;
+	char *which;
+{
+	if (ptr >= 1 && ptr <= 0x3FFF)
+		return(ptr);
+	if (ptr == 0xFFFF)
+		return(0);
+	fprintf(stderr, "error in inode #%x: invalid %s pointer\n", ino, which);
+	exit(1);
+}
+
+read_inodes()
+{
+	int ino;
+	struct inode_flash *fl;
+	struct inode_info *inf;
+
+	for (ino = 1; ino < 0x4000; ino++) {
+		fl = (struct inode_flash *) image + ino;
+		if (!bcmp(fl, blank_flash_line, 16))
+			break;
+		inf = inode + ino;
+		inf->flash = fl;
+		inf->len = le16toh(fl->len);
+		if (!inf->len) {
+			fprintf(stderr, "error: inode %x has zero length\n",
+				ino);
+			exit(1);
+		}
+		if (inf->len & 0xF) {
+			fprintf(stderr, "error: inode %x has bad length\n",
+				ino);
+			exit(1);
+		}
+		inf->type = fl->type;
+		inf->descend = convert_ptr(le16toh(fl->descend), ino,
+						"descendant");
+		inf->sibling = convert_ptr(le16toh(fl->sibling), ino,
+						"sibling");
+		inf->rawloc = le32toh(fl->dataptr);
+		if (inf->rawloc >= 0x48000) {
+invdptr:		fprintf(stderr,
+			"error: inode %x data pointer is out of bounds\n",
+				ino);
+			exit(1);
+		}
+		inf->offset = inf->rawloc << 4;
+		if (inf->offset + inf->len > 0x480000)
+			goto invdptr;
+		inf->dataptr = image + inf->offset;
+	}
+	last_inode = ino - 1;
+	if (!last_inode) {
+		fprintf(stderr, "error: no inodes found!\n");
+		exit(1);
+	}
+}