view ffstools/tiffs-rd/basics.c @ 461:10e168596dfd

doc/SIM-hardware-debugging: article written
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 10 Feb 2019 20:40:56 +0000
parents e7502631a0f9
children
line wrap: on
line source

/*
 * This C module implements the "basics" of TIFFS image analysis.
 */

#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include "types.h"
#include "struct.h"
#include "globals.h"

u8 tiffs_header[6] = {'F', 'f', 's', '#', 0x10, 0x02};

read_ffs_image()
{
	int fd;
	struct stat st;

	fd = open(imgfile, O_RDONLY);
	if (fd < 0) {
		perror(imgfile);
		exit(1);
	}
	fstat(fd, &st);
	if (!S_ISREG(st.st_mode)) {
		fprintf(stderr, "error: %s is not a regular file\n", imgfile);
		exit(1);
	}
	if (st.st_size < imgfile_offset) {
		fprintf(stderr,
		"error: offset given with -o exceeds the size of the file\n");
		exit(1);
	}
	if (st.st_size - imgfile_offset < total_ffs_size) {
		fprintf(stderr,
			"error: %s is shorter than FFS size of 0x%lx bytes\n",
			imgfile, (u_long)total_ffs_size);
		exit(1);
	}
	image = mmap(NULL, total_ffs_size, PROT_READ, MAP_PRIVATE, fd,
			imgfile_offset);
	if (image == MAP_FAILED) {
		perror("mmap");
		exit(1);
	}
	close(fd);
}

cmd_blkhdr()
{
	int blk;
	u8 *blkhdr;

	read_ffs_image();
	for (blk = 0; blk < total_blocks; blk++) {
		printf("Block %3d: ", blk);
		blkhdr = image + blk * eraseblk_size;
		if (bcmp(blkhdr, tiffs_header, sizeof tiffs_header)) {
			printf("No TIFFS header\n");
			continue;
		}
		printf("age %02X%02X, type/status %02X\n",
			blkhdr[7], blkhdr[6], blkhdr[8]);
	}
	exit(0);
}

find_inode_block()
{
	int i, abcnt;
	u8 *ptr;

	if (index_blk_num >= 0) {
		if (index_blk_num >= total_blocks) {
			fprintf(stderr,
				"invalid block # given with the -a option\n");
			exit(1);
		}
		ptr = image + index_blk_num * eraseblk_size;
		if (bcmp(ptr, tiffs_header, sizeof tiffs_header)) {
			fprintf(stderr,
			"error: block specified with -a has no TIFFS header\n");
			exit(1);
		}
		if (ptr[8] != 0xAB) {
			fprintf(stderr,
			"error: block specified with -a is not an AB block\n");
			exit(1);
		}
		inode_block = ptr;
		return(0);
	}
	abcnt = 0;
	for (ptr = image, i = 0; i < total_blocks; i++, ptr += eraseblk_size) {
		if (bcmp(ptr, tiffs_header, sizeof tiffs_header)) {
			fprintf(stderr,
		"warning: no TIFFS signature in erase block #%d (offset %x)\n",
				i, ptr - image);
			continue;
		}
		switch (ptr[8]) {
		case 0xAB:
			if (verbose)
				fprintf(stderr,
			"Found AB index in erase block #%d (offset %x)\n",
					i, ptr - image);
			index_blk_num = i;
			inode_block = ptr;
			abcnt++;
			continue;
		case 0xBD:
		case 0xBF:
			continue;
		}
		fprintf(stderr,
		"warning: unexpected block type/status %02X at offset %x\n",
			ptr[8], ptr - image);
	}
	if (!inode_block) {
		fprintf(stderr,
			"error: could not find an active inode block in %s\n",
			imgfile);
		exit(1);
	}
	if (abcnt > 1) {
		fprintf(stderr,
			"error: found more than one AB block; use -a\n");
		exit(1);
	}
	return(0);
}

cmd_fsinfo()
{
	read_ffs_image();
	find_inode_block();
	printf("Active inode block (AB) is block #%d\n", index_blk_num);
	alloc_inode_table();
	find_root_inode();
	printf("Root inode is #%x\n", root_inode);
	if (validate_obj_name(root_inode, 1)) {
		printf("Root inode (format) name: %s\n",
			inode_info[root_inode]->dataptr);
		exit(0);
	} else {
		printf("No valid name found in the root inode!\n");
		exit(1);
	}
}