FreeCalypso > hg > freecalypso-reveng
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); + } +}