int ubigen_set_lvol_rec(ubi_info_t u, size_t reserved_bytes, const char* vol_name, struct ubi_vol_tbl_record *lvol_rec) { uint32_t crc; if ((u == NULL) || (vol_name == NULL)) return -EINVAL; memset(lvol_rec, 0x0, UBI_VTBL_RECORD_SIZE); lvol_rec->reserved_pebs = cpu_to_ubi32(byte_to_blk(reserved_bytes, u->leb_size)); lvol_rec->alignment = cpu_to_ubi32(u->alignment); lvol_rec->data_pad = u->v->data_pad; lvol_rec->vol_type = u->v->vol_type; lvol_rec->name_len = cpu_to_ubi16((uint16_t)strlen((const char*)vol_name)); memcpy(lvol_rec->name, vol_name, UBI_VOL_NAME_MAX + 1); crc = clc_crc32(crc32_table, UBI_CRC32_INIT, lvol_rec, UBI_VTBL_RECORD_SIZE_CRC); lvol_rec->crc = cpu_to_ubi32(crc); return 0; }
/** * @precondition IO: File stream points to first byte of RAW data. * @postcondition IO: File stream points to first byte of next * or EOF. */ static int memorize_raw_eb(pfi_raw_t pfi_raw, pdd_data_t pdd, list_t *raw_pebs, io_t io) { int rc = 0; uint32_t i; size_t read, to_read, eb_num; size_t bytes_left; list_t pebs = *raw_pebs; peb_t peb = NULL; long old_file_pos = ftell(io->fp_pfi); for (i = 0; i < pfi_raw->starts_size; i++) { bytes_left = pfi_raw->data_size; rc = fseek(io->fp_pfi, old_file_pos, SEEK_SET); if (rc != 0) goto err; eb_num = byte_to_blk(pfi_raw->starts[i], pdd->eb_size); while (bytes_left) { to_read = MIN(bytes_left, pdd->eb_size); rc = peb_new(eb_num++, pdd->eb_size, &peb); if (rc != 0) goto err; read = fread(peb->data, 1, to_read, io->fp_pfi); if (read != to_read) { rc = -EIO; goto err; } pebs = append_elem(peb, pebs); bytes_left -= read; } } *raw_pebs = pebs; return 0; err: pebs = remove_all((free_func_t)&peb_free, pebs); return rc; }
int ubigen_create(ubi_info_t* u, uint32_t vol_id, uint8_t vol_type, uint32_t eb_size, uint64_t ec, uint32_t alignment, uint8_t version, uint32_t vid_hdr_offset, uint8_t compat_flag, size_t data_size, FILE* fp_in, FILE* fp_out) { int rc = 0; ubi_info_t res = NULL; uint32_t crc; uint32_t data_offset; if (alignment == 0) { rc = EUBIGEN_INVALID_ALIGNMENT; goto ubigen_create_err; } if ((fp_in == NULL) || (fp_out == NULL)) { rc = -EINVAL; goto ubigen_create_err; } res = (ubi_info_t) calloc(1, sizeof(struct ubi_info)); if (res == NULL) { rc = -ENOMEM; goto ubigen_create_err; } res->v = (struct ubi_vid_hdr*) calloc(1, sizeof(struct ubi_vid_hdr)); if (res->v == NULL) { rc = -ENOMEM; goto ubigen_create_err; } res->ec = (struct ubi_ec_hdr*) calloc(1, sizeof(struct ubi_ec_hdr)); if (res->ec == NULL) { rc = -ENOMEM; goto ubigen_create_err; } /* data which is needed in the general process */ vid_hdr_offset = vid_hdr_offset ? vid_hdr_offset : DEFAULT_VID_OFFSET; data_offset = vid_hdr_offset + UBI_VID_HDR_SIZE; res->bytes_total = data_size; res->eb_size = eb_size ? eb_size : DEFAULT_BLOCKSIZE; res->data_pad = (res->eb_size - data_offset) % alignment; res->leb_size = res->eb_size - data_offset - res->data_pad; res->leb_total = byte_to_blk(data_size, res->leb_size); res->alignment = alignment; if ((res->eb_size < (vid_hdr_offset + UBI_VID_HDR_SIZE))) { rc = EUBIGEN_TOO_SMALL_EB; goto ubigen_create_err; } res->fp_in = fp_in; res->fp_out = fp_out; /* vid hdr data which doesn't change */ res->v->magic = cpu_to_ubi32(UBI_VID_HDR_MAGIC); res->v->version = version ? version : UBI_VERSION; res->v->vol_type = vol_type; res->v->vol_id = cpu_to_ubi32(vol_id); res->v->compat = compat_flag; res->v->data_pad = cpu_to_ubi32(res->data_pad); /* static only: used_ebs */ if (res->v->vol_type == UBI_VID_STATIC) { res->v->used_ebs = cpu_to_ubi32(byte_to_blk (res->bytes_total, res->leb_size)); } /* ec hdr (fixed, doesn't change) */ res->ec->magic = cpu_to_ubi32(UBI_EC_HDR_MAGIC); res->ec->version = version ? version : UBI_VERSION; res->ec->ec = cpu_to_ubi64(ec); res->ec->vid_hdr_offset = cpu_to_ubi32(vid_hdr_offset); res->ec->data_offset = cpu_to_ubi32(data_offset); crc = clc_crc32(crc32_table, UBI_CRC32_INIT, res->ec, UBI_EC_HDR_SIZE_CRC); res->ec->hdr_crc = cpu_to_ubi32(crc); /* prepare a read buffer */ res->buf = (uint8_t*) malloc (res->eb_size * sizeof(uint8_t)); if (res->buf == NULL) { rc = -ENOMEM; goto ubigen_create_err; } /* point to distinct regions within the buffer */ res->ptr_ec_hdr = res->buf; res->ptr_vid_hdr = res->buf + ubi32_to_cpu(res->ec->vid_hdr_offset); res->ptr_data = res->buf + ubi32_to_cpu(res->ec->vid_hdr_offset) + UBI_VID_HDR_SIZE; rc = validate_ubi_info(res); if (rc != 0) { fprintf(stderr, "Volume validation failed: %d\n", rc); goto ubigen_create_err; } dump_info(res); *u = res; return rc; ubigen_create_err: if (res) { if (res->v) free(res->v); if (res->ec) free(res->ec); if (res->buf) free(res->buf); free(res); } *u = NULL; return rc; }