#ifndef __UBI_HEADER_H__
#define __UBI_HEADER_H__
+#include <stdint.h>
#include <asm/byteorder.h>
/* The version of UBI images supported by this implementation */
#define UBI_VID_HDR_SIZE sizeof(struct ubi_vid_hdr)
/* Sizes of UBI headers without the ending CRC */
-#define UBI_EC_HDR_SIZE_CRC (UBI_EC_HDR_SIZE - sizeof(__be32))
-#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(__be32))
+#define UBI_EC_HDR_SIZE_CRC (UBI_EC_HDR_SIZE - sizeof(uint32_t))
+#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(uint32_t))
/**
* struct ubi_ec_hdr - UBI erase counter header.
* eraseblocks.
*/
struct ubi_ec_hdr {
- __be32 magic;
- __u8 version;
- __u8 padding1[3];
- __be64 ec; /* Warning: the current limit is 31-bit anyway! */
- __be32 vid_hdr_offset;
- __be32 data_offset;
- __u8 padding2[36];
- __be32 hdr_crc;
+ uint32_t magic;
+ uint8_t version;
+ uint8_t padding1[3];
+ uint64_t ec; /* Warning: the current limit is 31-bit anyway! */
+ uint32_t vid_hdr_offset;
+ uint32_t data_offset;
+ uint8_t padding2[36];
+ uint32_t hdr_crc;
} __attribute__ ((packed));
/**
* software (say, cramfs) on top of the UBI volume.
*/
struct ubi_vid_hdr {
- __be32 magic;
- __u8 version;
- __u8 vol_type;
- __u8 copy_flag;
- __u8 compat;
- __be32 vol_id;
- __be32 lnum;
- __be32 leb_ver; /* obsolete, to be removed, don't use */
- __be32 data_size;
- __be32 used_ebs;
- __be32 data_pad;
- __be32 data_crc;
- __u8 padding1[4];
- __be64 sqnum;
- __u8 padding2[12];
- __be32 hdr_crc;
+ uint32_t magic;
+ uint8_t version;
+ uint8_t vol_type;
+ uint8_t copy_flag;
+ uint8_t compat;
+ uint32_t vol_id;
+ uint32_t lnum;
+ uint32_t leb_ver; /* obsolete, to be removed, don't use */
+ uint32_t data_size;
+ uint32_t used_ebs;
+ uint32_t data_pad;
+ uint32_t data_crc;
+ uint8_t padding1[4];
+ uint64_t sqnum;
+ uint8_t padding2[12];
+ uint32_t hdr_crc;
} __attribute__ ((packed));
/* Internal UBI volumes count */
/* The layout volume contains the volume table */
-#define UBI_LAYOUT_VOL_ID UBI_INTERNAL_VOL_START
+#define UBI_LAYOUT_VOLUME_ID UBI_INTERNAL_VOL_START
+#define UBI_LAYOUT_VOLUME_TYPE UBI_VID_DYNAMIC
+#define UBI_LAYOUT_VOLUME_ALIGN 1
#define UBI_LAYOUT_VOLUME_EBS 2
#define UBI_LAYOUT_VOLUME_NAME "layout volume"
#define UBI_LAYOUT_VOLUME_COMPAT UBI_COMPAT_REJECT
#define UBI_VTBL_RECORD_SIZE sizeof(struct ubi_vtbl_record)
/* Size of the volume table record without the ending CRC */
-#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(__be32))
+#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(uint32_t))
/**
* struct ubi_vtbl_record - a record in the volume table.
* Empty records contain all zeroes and the CRC checksum of those zeroes.
*/
struct ubi_vtbl_record {
- __be32 reserved_pebs;
- __be32 alignment;
- __be32 data_pad;
- __u8 vol_type;
- __u8 upd_marker;
- __be16 name_len;
- __u8 name[UBI_VOL_NAME_MAX+1];
- __u8 flags;
- __u8 padding[23];
- __be32 crc;
+ uint32_t reserved_pebs;
+ uint32_t alignment;
+ uint32_t data_pad;
+ uint8_t vol_type;
+ uint8_t upd_marker;
+ uint16_t name_len;
+ uint8_t name[UBI_VOL_NAME_MAX+1];
+ uint8_t flags;
+ uint8_t padding[23];
+ uint32_t crc;
} __attribute__ ((packed));
#endif /* !__UBI_HEADER_H__ */
*
* Volume update should be done via the %UBI_IOCVOLUP IOCTL command of the
* corresponding UBI volume character device. A pointer to a 64-bit update
- * size should be passed to the IOCTL. After then, UBI expects user to write
+ * size should be passed to the IOCTL. After this, UBI expects user to write
* this number of bytes to the volume character device. The update is finished
* when the claimed number of bytes is passed. So, the volume update sequence
* is something like:
* ioctl(fd, UBI_IOCVOLUP, &image_size);
* write(fd, buf, image_size);
* close(fd);
+ *
+ * Atomic eraseblock change
+ * ~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * Atomic eraseblock change operation is done via the %UBI_IOCEBCH IOCTL
+ * command of the corresponding UBI volume character device. A pointer to
+ * &struct ubi_leb_change_req has to be passed to the IOCTL. Then the user is
+ * expected to write the requested amount of bytes. This is similar to the
+ * "volume update" IOCTL.
*/
/*
#define UBI_IOCVOLUP _IOW(UBI_VOL_IOC_MAGIC, 0, int64_t)
/* An eraseblock erasure command, used for debugging, disabled by default */
#define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t)
+/* An atomic eraseblock change command */
+#define UBI_IOCEBCH _IOW(UBI_VOL_IOC_MAGIC, 2, int32_t)
/* Maximum MTD device name length supported by UBI */
#define MAX_UBI_MTD_NAME_LEN 127
+/*
+ * UBI data type hint constants.
+ *
+ * UBI_LONGTERM: long-term data
+ * UBI_SHORTTERM: short-term data
+ * UBI_UNKNOWN: data persistence is unknown
+ *
+ * These constants are used when data is written to UBI volumes in order to
+ * help the UBI wear-leveling unit to find more appropriate physical
+ * eraseblocks.
+ */
+enum {
+ UBI_LONGTERM = 1,
+ UBI_SHORTTERM = 2,
+ UBI_UNKNOWN = 3,
+};
+
/*
* UBI volume type constants.
*
*/
enum {
UBI_DYNAMIC_VOLUME = 3,
- UBI_STATIC_VOLUME = 4,
+ UBI_STATIC_VOLUME = 4,
};
/**
*
* This data structure is used to specify MTD device UBI has to attach and the
* parameters it has to use. The number which should be assigned to the new UBI
- * device is passed in @ubi_num. UBI may automatically assing the number if
+ * device is passed in @ubi_num. UBI may automatically assign the number if
* @UBI_DEV_NUM_AUTO is passed. In this case, the device number is returned in
* @ubi_num.
*
* @padding2: reserved for future, not used, has to be zeroed
* @name: volume name
*
- * This structure is used by userspace programs when creating new volumes. The
+ * This structure is used by user-space programs when creating new volumes. The
* @used_bytes field is only necessary when creating static volumes.
*
* The @alignment field specifies the required alignment of the volume logical
int32_t vol_id;
} __attribute__ ((packed));
+/**
+ * struct ubi_leb_change_req - a data structure used in atomic logical
+ * eraseblock change requests.
+ * @lnum: logical eraseblock number to change
+ * @bytes: how many bytes will be written to the logical eraseblock
+ * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN)
+ * @padding: reserved for future, not used, has to be zeroed
+ */
+struct ubi_leb_change_req {
+ int32_t lnum;
+ int32_t bytes;
+ uint8_t dtype;
+ uint8_t padding[7];
+} __attribute__ ((packed));
+
#endif /* __UBI_USER_H__ */
#ifndef __LIBUBI_H__
#define __LIBUBI_H__
+#include <ctype.h>
#include <stdint.h>
#include <mtd/ubi-user.h>
-#include <ctype.h>
#include <mtd/ubi-header.h>
#ifdef __cplusplus
#include <stdint.h>
#include <stdio.h>
-#include <asm/byteorder.h>
+#include <endian.h>
#ifdef __cplusplus
extern "C" {
* introduce this stupid mechanism. Until no final
* decision of the VTAB structure is made... Good enough.
*/
- rc = ubigen_create(&u, UBI_LAYOUT_VOL_ID, UBI_VID_DYNAMIC,
+ rc = ubigen_create(&u, UBI_LAYOUT_VOLUME_ID, UBI_VID_DYNAMIC,
pdd->eb_size, DEFAULT_ERASE_COUNT,
1, UBI_VERSION,
pdd->vid_hdr_offset, UBI_COMPAT_REJECT,
memcpy(ptr, vol_tab, vol_tab_size_limit);
fp_leb = my_fmemopen(ptr, leb_size, "r");
- rc = ubigen_create(&u, UBI_LAYOUT_VOL_ID, UBI_VID_DYNAMIC,
+ rc = ubigen_create(&u, UBI_LAYOUT_VOLUME_ID, UBI_VID_DYNAMIC,
pdd->eb_size, DEFAULT_ERASE_COUNT,
1, UBI_VERSION, pdd->vid_hdr_offset,
UBI_COMPAT_REJECT, leb_size * UBI_LAYOUT_VOLUME_EBS,
fseek(fpin, __be32_to_cpu(cur->ec.data_offset), SEEK_CUR);
/* prepare output file */
- if (__be32_to_cpu(cur->vid.vol_id) != UBI_LAYOUT_VOL_ID)
+ if (__be32_to_cpu(cur->vid.vol_id) != UBI_LAYOUT_VOLUME_ID)
return -2;
memset(filename, 0, MAXPATH + 1);
snprintf(filename, MAXPATH, FN_VITBL, path, num);
/* extract info-table */
if (a->itable &&
- (__be32_to_cpu(cur->vid.vol_id) == UBI_LAYOUT_VOL_ID)) {
+ (__be32_to_cpu(cur->vid.vol_id) == UBI_LAYOUT_VOLUME_ID)) {
extract_itable(fpin, cur, a->bsize,
itable_num, a->odir_path);
itable_num++;
size = UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE;
vi.bytes = ui->leb_size * UBI_LAYOUT_VOLUME_EBS;
- vi.id = UBI_LAYOUT_VOL_ID;
+ vi.id = UBI_LAYOUT_VOLUME_ID;
vi.alignment = 1;
vi.data_pad = 0;
vi.usable_leb_size = ui->leb_size;