/*! * \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(); }
/*! * \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(); }
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; }
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; }
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 = {
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);
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; }
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; }