Пример #1
0
/*!
 * \brief Perform non-recursive search for a block device
 *
 * This function will non-recursively search \a search_dirs for a block device
 * named \a partition. \a /dev/block/ is implicitly added to the search paths.
 *
 * \param search_dirs Search paths
 * \param partition Block device name
 *
 * \return Block device path if found. Otherwise, an empty string.
 */
static std::string find_block_dev(const std::vector<std::string> &search_dirs,
                                  const std::string &partition)
{
    struct stat sb;

    if (util::starts_with(partition, "mmcblk")) {
        std::string path("/dev/block/");
        path += partition;

        if (stat(path.c_str(), &sb) == 0) {
            return path;
        }
    }

    for (const std::string &base_dir : search_dirs) {
        std::string block_dev(base_dir);
        block_dev += "/";
        block_dev += partition;

        if (stat(block_dev.c_str(), &sb) == 0) {
            return block_dev;
        }
    }

    return std::string();
}
Пример #2
0
/*!
 * \brief Perform non-recursive search for a block device
 *
 * This function will non-recursively search \a search_dirs for a block device
 * named \a partition. \a /dev/block/ is implicitly added to the search paths.
 *
 * \param search_dirs Search paths
 * \param partition Block device name
 *
 * \return Block device path if found. Otherwise, an empty string.
 */
static std::string find_block_dev(const char * const *search_dirs,
                                  const std::string &partition)
{
    struct stat sb;

    if (util::starts_with(partition, "mmcblk")) {
        std::string path("/dev/block/");
        path += partition;

        if (stat(path.c_str(), &sb) == 0) {
            return path;
        }
    }

    for (auto it = search_dirs; *it; ++it) {
        std::string block_dev(*it);
        block_dev += "/";
        block_dev += partition;

        if (stat(block_dev.c_str(), &sb) == 0) {
            return block_dev;
        }
    }

    return std::string();
}
Пример #3
0
static int idedisk_init (void *args) {
	hd_t *drive;
	size_t size;
	char path[PATH_MAX];
	drive = (hd_t *)args;
	struct block_dev *bdev = drive->bdev;
	/* Make new device */
	if ((drive->media == IDE_DISK) && (drive->udmamode == -1)) {
		*path = 0;
		strcat(path, "/dev/hd*");
		if (0 > (drive->idx = block_dev_named(path, idedisk_idx))) {
			return drive->idx;
		}
		drive->bdev = block_dev_create(path,
				&idedisk_pio_driver, drive);
		if (NULL != drive->bdev) {
			size = drive->blks * bdev->block_size;
			block_dev(drive->bdev)->size = size;
		} else {
			return -1;
		}
		create_partitions(drive);
	}
	return 0;
}
Пример #4
0
int block_dev_destroy(void *dev) {
	struct block_dev *bdev;

	bdev = block_dev(dev);
	vfs_del_leaf(bdev->dev_vfs_info);
	block_dev_free(bdev);

	return 0;
}
Пример #5
0
int fat_create_partition(void *bdev) {
	uint16_t bytepersec = 512;
	size_t num_sect = block_dev(bdev)->size / bytepersec;
	uint16_t secperfat = max(1, (uint16_t) 0xFFFF & (num_sect / bytepersec ));
	uint16_t rootentries = 0x0200; /* 512 for FAT16 */

	struct lbr lbr = {
		.jump = {0xeb, 0x3c, 0x90}, /* JMP 0x3c; NOP; */
		.oemid = {0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45}, /* ASCII "EEEEEEEE" */
		.bpb = {
Пример #6
0
static int idedisk_udma_init (void *args) {
//	struct ide_tab *ide;
	hd_t *drive;
	double size;
	char   path[PATH_MAX];

#if 0
	ide = ide_get_drive();

	for(int i = 0; i < HD_DRIVES; i++) {
		if (NULL == ide->drive[i]) {
			continue;
		} else {
			drive = (hd_t *) ide->drive[i];
#endif
			drive = (hd_t *)args;
			/* Make new device */
			if ((drive->media == IDE_DISK) && (drive->udmamode != -1)) {
				*path = 0;
				strcat(path, "/dev/hd*");
				if (0 > (drive->idx = block_dev_named(path, idedisk_idx))) {
					return drive->idx;
				}
				drive->bdev = block_dev_create(path,
						&idedisk_udma_driver, drive);
				if (NULL != drive->bdev) {
					size = (double) drive->param.cylinders *
						   (double) drive->param.heads *
						   (double) drive->param.unfbytes *
						   (double) (drive->param.sectors + 1);
					block_dev(drive->bdev)->size = (size_t) size;
				} else {
					return -1;
				}
				create_partitions(drive);
//			} else {
//				continue;
//			}
		}
//	}
	return 0;
}

EMBOX_BLOCK_DEV("idedisk_udma", &idedisk_udma_driver, idedisk_udma_init);
Пример #7
0
static int tmpfs_mount(void *dev, void *dir) {
	struct node *dir_node, *dev_node;
	struct nas *dir_nas, *dev_nas;
	struct tmpfs_file_info *fi;
	struct tmpfs_fs_info *fsi;
	struct node_fi *dev_fi;

	dev_node = dev;
	dev_nas = dev_node->nas;
	dir_node = dir;
	dir_nas = dir_node->nas;

	if (NULL == (dev_fi = dev_nas->fi)) {
		return -ENODEV;
	}

	if (NULL == (dir_nas->fs = filesystem_create("tmpfs"))) {
		return -ENOMEM;
	}
	dir_nas->fs->bdev = dev_fi->privdata;

	/* allocate this fs info */
	if(NULL == (fsi = pool_alloc(&tmpfs_fs_pool))) {
		filesystem_free(dir_nas->fs);
		return -ENOMEM;
	}
	memset(fsi, 0, sizeof(struct tmpfs_fs_info));
	dir_nas->fs->fsi = fsi;

	fsi->block_per_file = MAX_FILE_SIZE;
	fsi->block_size = PAGE_SIZE();
	fsi->numblocks = block_dev(dev_fi->privdata)->size / PAGE_SIZE();

	/* allocate this directory info */
	if(NULL == (fi = pool_alloc(&tmpfs_file_pool))) {
		return -ENOMEM;
	}
	memset(fi, 0, sizeof(struct tmpfs_file_info));
	fi->index = fi->mode = 0;
	dir_nas->fi->privdata = (void *) fi;

	return 0;
}
Пример #8
0
static int tmpfs_format(void *dev) {
	node_t *dev_node;
	struct nas *dev_nas;
	struct node_fi *dev_fi;

	if (NULL == (dev_node = dev)) {
		return -ENODEV;/*device not found*/
	}

	if(!node_is_block_dev(dev_node)) {
		return -ENODEV;
	}
	dev_nas = dev_node->nas;
	dev_fi = dev_nas->fi;

	if(MAX_FILE_SIZE > block_dev(dev_fi->privdata)->size / PAGE_SIZE()) {
		return -ENOSPC;
	}
	return 0;
}
Installer::ProceedState RomInstaller::on_checked_device()
{
    // /sbin is not going to be populated with anything useful in a normal boot
    // image. We can almost guarantee that a recovery image is going to be
    // installed though, so we'll open the recovery partition with libmbp and
    // extract its /sbin with libarchive into the chroot's /sbin.

    std::string block_dev(_recovery_block_dev);
    mbp::BootImage bi;
    mbp::CpioFile innerCpio;
    const unsigned char *ramdisk_data;
    std::size_t ramdisk_size;
    bool using_boot = false;

    // Check if the device has a combined boot/recovery partition. If the
    // FOTAKernel partition is listed, it will be used instead of the combined
    // ramdisk from the boot image
    bool combined = mb_device_flags(_device)
            & FLAG_HAS_COMBINED_BOOT_AND_RECOVERY;
    if (combined && block_dev.empty()) {
        block_dev = _boot_block_dev;
        using_boot = true;
    }

    if (block_dev.empty()) {
        display_msg("Could not determine the recovery block device");
        return ProceedState::Fail;
    }

    if (!bi.loadFile(block_dev)) {
        display_msg("Failed to load recovery partition image");
        return ProceedState::Fail;
    }

    // Load ramdisk
    bi.ramdiskImageC(&ramdisk_data, &ramdisk_size);

    if (using_boot) {
        if (!innerCpio.load(ramdisk_data, ramdisk_size)) {
            display_msg("Failed to load ramdisk from combined boot image");
            return ProceedState::Fail;
        }

        if (!innerCpio.contentsC("sbin/ramdisk-recovery.cpio",
                                 &ramdisk_data, &ramdisk_size)) {
            display_msg("Could not find recovery ramdisk in combined boot image");
            return ProceedState::Fail;
        }
    }

    autoclose::archive in(archive_read_new(), archive_read_free);
    autoclose::archive out(archive_write_disk_new(), archive_write_free);

    if (!in || !out) {
        LOGE("Out of memory");
        return ProceedState::Fail;
    }

    archive_entry *entry;

    // Set up input
    archive_read_support_filter_gzip(in.get());
    archive_read_support_filter_lzop(in.get());
    archive_read_support_filter_lz4(in.get());
    archive_read_support_filter_lzma(in.get());
    archive_read_support_filter_xz(in.get());
    archive_read_support_format_cpio(in.get());

    int ret = archive_read_open_memory(in.get(),
            const_cast<unsigned char *>(ramdisk_data), ramdisk_size);
    if (ret != ARCHIVE_OK) {
        LOGW("Failed to open recovery ramdisk: %s",
             archive_error_string(in.get()));
        return ProceedState::Fail;
    }

    // Set up output
    archive_write_disk_set_options(out.get(),
                                   ARCHIVE_EXTRACT_ACL |
                                   ARCHIVE_EXTRACT_FFLAGS |
                                   ARCHIVE_EXTRACT_PERM |
                                   ARCHIVE_EXTRACT_SECURE_NODOTDOT |
                                   ARCHIVE_EXTRACT_SECURE_SYMLINKS |
                                   ARCHIVE_EXTRACT_TIME |
                                   ARCHIVE_EXTRACT_UNLINK |
                                   ARCHIVE_EXTRACT_XATTR);

    while ((ret = archive_read_next_header(in.get(), &entry)) == ARCHIVE_OK) {
        std::string path = archive_entry_pathname(entry);

        if (path == "default.prop") {
            path = "default.recovery.prop";
        } else if (!util::starts_with(path, "sbin/")) {
            continue;
        }

        LOGE("Copying from recovery: %s", path.c_str());

        archive_entry_set_pathname(entry, in_chroot(path).c_str());

        if (util::libarchive_copy_header_and_data(
                in.get(), out.get(), entry) != ARCHIVE_OK) {
            return ProceedState::Fail;
        }

        archive_entry_set_pathname(entry, path.c_str());
    }

    if (ret != ARCHIVE_EOF) {
        LOGE("Archive extraction ended without reaching EOF: %s",
             archive_error_string(in.get()));
        return ProceedState::Fail;
    }

    // Create fake /etc/fstab file to please installers that read the file
    std::string etc_fstab(in_chroot("/etc/fstab"));
    if (access(etc_fstab.c_str(), R_OK) < 0 && errno == ENOENT) {
        autoclose::file fp(autoclose::fopen(etc_fstab.c_str(), "w"));
        if (fp) {
            auto system_devs = mb_device_system_block_devs(_device);
            auto cache_devs = mb_device_cache_block_devs(_device);
            auto data_devs = mb_device_data_block_devs(_device);

            // Set block device if it's provided and non-empty
            const char *system_dev =
                    system_devs && system_devs[0] && system_devs[0][0]
                    ? system_devs[0] : "dummy";
            const char *cache_dev =
                    cache_devs && cache_devs[0] && cache_devs[0][0]
                    ? cache_devs[0] : "dummy";
            const char *data_dev =
                    data_devs && data_devs[0] && data_devs[0][0]
                    ? data_devs[0] : "dummy";

            fprintf(fp.get(), "%s /system ext4 rw 0 0\n", system_dev);
            fprintf(fp.get(), "%s /cache ext4 rw 0 0\n", cache_dev);
            fprintf(fp.get(), "%s /data ext4 rw 0 0\n", data_dev);
        }
    }

    // Load recovery properties
    util::file_get_all_properties(
            in_chroot("/default.recovery.prop"), &_recovery_props);

    return ProceedState::Continue;
}