Exemplo n.º 1
0
int flash_emu_dev_create (struct node *bdev_node, /*const*/ char *flash_node_path) {
	struct flash_dev *flash;
	struct block_dev * bdev;
	size_t block_size, factor;

	if(NULL == (bdev = (struct block_dev *)
				bdev_node->nas->fi->privdata)) {
		return -ENOTBLK;
	}

	flash = flash_create(flash_node_path, bdev->size);
	if(err(flash)) {
		return err(flash);
	}

	flash->privdata = bdev;
	/* XXX */
	flash->block_info.block_size = FLASH_ERASE_BLOCK_SIZE;
	block_size = bdev->driver->ioctl(bdev, IOCTL_GETBLKSIZE, NULL, 0);
	factor = FLASH_ERASE_BLOCK_SIZE / block_size;
	if(0 == factor) {
		factor++;
	}
	flash->block_info.blocks = bdev->driver->ioctl(bdev, IOCTL_GETDEVSIZE, NULL, 0);
	flash->block_info.blocks /= factor;

	flash->start = 0;
	flash->end = bdev->size;

	flash->drv = &flash_emu_drv;

	return 0;
}
Exemplo n.º 2
0
int parse_flash_partition(uint8_t *data, unsigned int length, const char *partition_name, uint32_t offset, const char *filepath, int detected_device)
{
	struct flash_file *flash;
	int file_device;
	
	flash = flash_create(data, length);
	if(!flash) {
		fprintf(stderr, "%s: Memory error\n", program);
		return 0;
	}
	
	switch(flash->header->magic) {
		case AOS_ZMfX_MAGIC: {
			if(verbose) printf("\t%s: Stage 2 bootloader\n", filepath);
			break;
		}
		case AOS_KERNEL_MAGIC: {
			if(verbose) printf("\t%s: Kernel (zImage+initramfs)\n", filepath);
			break;
		}
		case AOS_GZIP_MAGIC: {
			if(verbose) printf("\t%s: Boot Logo\n", filepath);
			break;
		}
		default: {
			if(offset == 0x3f8000 || offset == 0x000000) {
				// We know those are never signed, so we don't warn about them
				flash_free(flash);
				return 0;
			}
			
			printf("\t%s: Unknown magic, this is weird.\n", filepath);
			flash_free(flash);
			return 0;
		}
	}
	
	if(flash->header->magic != AOS_GZIP_MAGIC) {
		if(flash->header->bits != 0x400) {
			if(verbose)
				printf("\t%s: Signature is 0 bits long (SDE Firmware?).\n", filepath);
		}
		else {
			if(!flash_is_signed(flash)) {
				if(verbose)
					printf("\t%s: File is not signed.\n", filepath);
			}
			else {
				if(!flash_detect_key(flash, Bootloader_Keys, MPK_KNOWN_DEVICES, &file_device)) {
					printf("WARNING: %s: Signature is not valid.\n", filepath);
				}
				else {
					if(detected_device != file_device) {
						printf("WARNING: %s: The detected device type for this file does not match the .aos device type (detected %s).\n", filepath, mpk_device_type(file_device));
					}
					else {
						if(verbose)
							printf("\t%s: Signature is valid, detected device type %s.\n", filepath, mpk_device_type(file_device));
					}
				}
			}
		}
	}
	
	if(flash->header->magic == AOS_KERNEL_MAGIC) {
		unsigned int gz_length;
		uint8_t *gz_data;
		char *folder_name;
		char *device_shortname;
		
		gz_data = (uint8_t *)flash->header+flash->header->cpio;
		gz_length = (flash->length - flash->header->cpio);
		
		if(*(uint32_t *)gz_data == AOS_GZIP_MAGIC) {
			folder_name = strdup((const char *)&gz_data[10]);
			if(endswith(folder_name, ".cpio"))
				folder_name[strlen(folder_name)-strlen(".cpio")] = 0;
		}
		else if((*(uint32_t *)gz_data & AOS_GZIP_NONAME_MASK) == AOS_GZIP_NONAME_MAGIC) {
			folder_name = bprintf("%s", partition_name);
		}
		else {
			printf("error: Could not find GZIP magic at given offset in %s.\n", filepath);
			flash_free(flash);
			return 0;
		}
		
		switch(detected_device) {
			case MPK_DEVICE_A5: device_shortname = "a5"; break;
			case MPK_DEVICE_A5IT: device_shortname = "a5it"; break;
			case MPK_DEVICE_A3GP: device_shortname = "a3g"; break;
			default: device_shortname = "unk"; break;
		}
		
		// Unpack script
		log_write("unpack.sh", "## zImage+initramfs: %s\n", filepath);
		log_write("unpack.sh", "rm -f -r unpacked/%s/\n", folder_name);
		log_write("unpack.sh", "mkdir -p unpacked/%s/initramfs/\n", folder_name);
		log_write("unpack.sh", "aos-unpack %s --%s --output unpacked/%s/ --zimage zImage --initramfs initramfs.cpio.gz\n", filepath, device_shortname, folder_name);
		log_write("unpack.sh", "gunzip --decompress unpacked/%s/initramfs.cpio.gz\n", folder_name);
		log_write("unpack.sh", "(cd unpacked/%s/initramfs/ && cpio -i -d -H newc -F ../initramfs.cpio --no-absolute-filenames)\n", folder_name, folder_name);
		log_write("unpack.sh", "rm unpacked/%s/initramfs.cpio\n", folder_name);
		log_write("unpack.sh", "\n");
		
		// Repack script
		log_write("repack.sh", "## zImage+initramfs: %s\n", filepath);
		log_write("repack.sh", "(cd unpacked/%s/initramfs/ && find . | cpio -o -H newc -F ../initramfs.cpio)\n", folder_name);
		log_write("repack.sh", "rm -f -r unpacked/%s/initramfs/\n", folder_name);
		log_write("repack.sh", "gzip --name --best unpacked/%s/initramfs.cpio\n", folder_name);
		log_write("repack.sh", "aos-repack --kernel --output %s --zimage unpacked/%s/zImage --initramfs unpacked/%s/initramfs.cpio.gz\n", filepath, folder_name, folder_name);
		log_write("repack.sh", "rm -f -r  unpacked/%s/\n", folder_name);
		log_write("repack.sh", "\n");
		
		free(folder_name);
	}
	else if(flash->header->magic == AOS_GZIP_MAGIC) {
		const char *gz_name = (const char *)&data[10];
		
		log_write("unpack.sh", "## .gz: %s\n", filepath);
		log_write("unpack.sh", "mkdir -p unpacked/\n", gz_name);
		log_write("unpack.sh", "rm -f unpacked/%s\n", gz_name);
		log_write("unpack.sh", "cp %s unpacked/%s.gz\n", filepath, gz_name);
		log_write("unpack.sh", "gunzip -d unpacked/%s.gz\n", gz_name);
		log_write("unpack.sh", "\n");
		
		log_write("repack.sh", "## .gz: %s\n", filepath);
		log_write("repack.sh", "gzip -N --best unpacked/%s\n", gz_name);
		log_write("repack.sh", "cp unpacked/%s.gz %s\n", gz_name, filepath);
		log_write("repack.sh", "rm -f unpacked/%s.gz\n", gz_name);
		log_write("repack.sh", "\n");
	}
	
	flash_free(flash);
	
	return 1;
}
Exemplo n.º 3
0
int parse_cramfs_archive(const char *filename, uint8_t *data, unsigned int length, const char *filepath, int detected_device)
{
	struct flash_file *flash;
	int file_device;
	char cramfs_name[2048];
	
	flash = flash_create(data, length);
	if(!flash) {
		fprintf(stderr, "%s: Memory error\n", program);
		return 0;
	}
	
	if(flash->header->magic != AOS_CRAMFS_MAGIC) {
		fprintf(stderr, "%s: Invalid Cramfs magic on file.\n", filename);
		flash_free(flash);
		return 0;
	}
	
	if(!flash_detect_key(flash, Bootloader_Keys, MPK_KNOWN_DEVICES, &file_device)) {
		printf("WARNING: %s: Signature is invalid.\n", filename);
	}
	else {
		if(detected_device != file_device) {
			printf("WARNING: %s: The detected device type for this file does not match the .aos device type (detected %s).\n", filename, mpk_device_type(file_device));
		}
		else {
			if(verbose)
				printf("\t%s: Signature is valid, detected device type %s\n", filename, mpk_device_type(file_device));
		}
	}
	
	strcpy(cramfs_name, filename);
	cramfs_name[strlen(cramfs_name)-strlen(".secure")] = 0;
	
	log_write("unpack.sh", "## .cramfs.secure: %s\n", filepath);
	log_write("unpack.sh", "rm -f -r unpacked/%s\n", cramfs_name);
	log_write("unpack.sh", "mkdir -p unpacked\n");
	if(*(uint32_t *)&flash->header->data[0] == 0x28cd3d45 /* CRAMFS_MAGIC */) {
		/* this is a cramfs with a small header (0x100 bytes), which is nonstandard for a cramfs file. */
		log_write("unpack.sh", "dd if=%s of=unpacked/%s.stripped bs=256 skip=1\n", filepath, cramfs_name);
		log_write("unpack.sh", "(cd unpacked/ && cramfsck -v -x %s %s.stripped)\n", cramfs_name, cramfs_name);
		log_write("unpack.sh", "rm unpacked/%s.stripped\n", cramfs_name);
	} else {
		/* this is a cramfs file with either no header or a standard cramfs header (0x200 bytes). */
		log_write("unpack.sh", "cramfsck -x unpacked/%s %s\n", cramfs_name, filepath);
	}
	log_write("unpack.sh", "\n");
	
	log_write("repack.sh", "## .cramfs.secure: %s\n", filepath);
	if(*(uint32_t *)&flash->header->data[0] == 0x28cd3d45 /* CRAMFS_MAGIC */) {
		log_write("repack.sh", "mkcramfs unpacked/%s unpacked/%s.tmp\n", cramfs_name, cramfs_name);
		log_write("repack.sh", "rm -f -r unpacked/%s\n", cramfs_name);
		log_write("repack.sh", "aos-fix --add-header unpacked/%s.tmp\n", cramfs_name);
		log_write("repack.sh", "mv unpacked/%s.tmp unpacked/%s.secure\n", cramfs_name, cramfs_name);
	} else {
		// create a cramfs with padding for the header, and write the header in-place
		log_write("repack.sh", "mkcramfs -p unpacked/%s unpacked/%s.secure\n", cramfs_name, cramfs_name);
		log_write("repack.sh", "rm -f -r unpacked/%s\n", cramfs_name);
		log_write("repack.sh", "aos-fix --add-header --overwrite unpacked/%s.secure\n", cramfs_name);
	}
	log_write("repack.sh", "mv unpacked/%s.secure %s\n", cramfs_name, filepath);
	log_write("repack.sh", "\n");
	
	flash_free(flash);
	
	return 1;
}