summaryrefslogtreecommitdiff
path: root/ubi-utils/new-utils/src
diff options
context:
space:
mode:
Diffstat (limited to 'ubi-utils/new-utils/src')
-rw-r--r--ubi-utils/new-utils/src/common.h25
-rw-r--r--ubi-utils/new-utils/src/libubi.c11
-rw-r--r--ubi-utils/new-utils/src/libubigen.c100
-rw-r--r--ubi-utils/new-utils/src/ubiattach.c4
-rw-r--r--ubi-utils/new-utils/src/ubinize.c72
5 files changed, 112 insertions, 100 deletions
diff --git a/ubi-utils/new-utils/src/common.h b/ubi-utils/new-utils/src/common.h
index bd99341..720dec1 100644
--- a/ubi-utils/new-utils/src/common.h
+++ b/ubi-utils/new-utils/src/common.h
@@ -43,24 +43,29 @@ extern "C" {
#define normsg_cont(fmt, ...) do { \
printf(PROGRAM_NAME ": " fmt, ##__VA_ARGS__); \
} while(0)
+#define normsg_cont(fmt, ...) do { \
+ printf(PROGRAM_NAME ": " fmt, ##__VA_ARGS__); \
+} while(0)
/* Error messages */
-#define errmsg(fmt, ...) ({ \
- fprintf(stderr, PROGRAM_NAME " error: " fmt "\n", ##__VA_ARGS__); \
- -1; \
+#define errmsg(fmt, ...) ({ \
+ fprintf(stderr, PROGRAM_NAME ": error!: " fmt "\n", ##__VA_ARGS__); \
+ -1; \
})
/* System error messages */
-#define sys_errmsg(fmt, ...) ({ \
- int _err = errno; \
- fprintf(stderr, PROGRAM_NAME " error: " fmt "\n", ##__VA_ARGS__); \
- fprintf(stderr, "error %d (%s)\n", _err, strerror(_err)); \
- -1; \
+#define sys_errmsg(fmt, ...) ({ \
+ int _err = errno, _i; \
+ fprintf(stderr, PROGRAM_NAME ": error!: " fmt "\n", ##__VA_ARGS__); \
+ for (_i = 0; _i < sizeof(PROGRAM_NAME) + 1; _i++) \
+ fprintf(stderr, " "); \
+ fprintf(stderr, "error %d (%s)\n", _err, strerror(_err)); \
+ -1; \
})
/* Warnings */
-#define warnmsg(fmt, ...) do { \
- fprintf(stderr, PROGRAM_NAME " warning: " fmt "\n", ##__VA_ARGS__); \
+#define warnmsg(fmt, ...) do { \
+ fprintf(stderr, PROGRAM_NAME ": warning!: " fmt "\n", ##__VA_ARGS__); \
} while(0)
long long ubiutils_get_bytes(const char *str);
diff --git a/ubi-utils/new-utils/src/libubi.c b/ubi-utils/new-utils/src/libubi.c
index 5e6f9b1..8f95108 100644
--- a/ubi-utils/new-utils/src/libubi.c
+++ b/ubi-utils/new-utils/src/libubi.c
@@ -477,12 +477,13 @@ static int dev_node2num(struct libubi *lib, const char *node, int *dev_num)
return -1;
}
-static int mtd_num2ubi_dev(struct libubi *lib, int mtd_num, int *dev_num)
+int mtd_num2ubi_dev(libubi_t desc, int mtd_num, int *dev_num)
{
struct ubi_info info;
int i, ret, mtd_num1;
+ struct libubi *lib = desc;
- if (ubi_get_info((libubi_t *)lib, &info))
+ if (ubi_get_info(desc, &info))
return -1;
for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) {
@@ -500,7 +501,7 @@ static int mtd_num2ubi_dev(struct libubi *lib, int mtd_num, int *dev_num)
}
}
- errno = ENODEV;
+ errno = 0;
return -1;
}
@@ -714,8 +715,10 @@ int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num)
int ret, ubi_dev;
ret = mtd_num2ubi_dev(desc, mtd_num, &ubi_dev);
- if (ret == -1)
+ if (ret == -1) {
+ errno = ENODEV;
return ret;
+ }
return ubi_remove_dev(desc, node, ubi_dev);
}
diff --git a/ubi-utils/new-utils/src/libubigen.c b/ubi-utils/new-utils/src/libubigen.c
index bee6f77..70ef0ca 100644
--- a/ubi-utils/new-utils/src/libubigen.c
+++ b/ubi-utils/new-utils/src/libubigen.c
@@ -26,11 +26,11 @@
#include <stdlib.h>
#include <stdint.h>
-#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <mtd/ubi-header.h>
+#include <mtd_swab.h>
#include <libubigen.h>
#include "crc32.h"
#include "common.h"
@@ -46,11 +46,9 @@
* @min_io_size if does not exist)
* @vid_hdr_offs: offset of the VID header
* @ubi_ver: UBI version
- * @ec: initial erase counter
*/
void ubigen_info_init(struct ubigen_info *ui, int peb_size, int min_io_size,
- int subpage_size, int vid_hdr_offs, int ubi_ver,
- long long ec)
+ int subpage_size, int vid_hdr_offs, int ubi_ver)
{
if (!vid_hdr_offs) {
vid_hdr_offs = UBI_EC_HDR_SIZE + subpage_size - 1;
@@ -66,12 +64,11 @@ void ubigen_info_init(struct ubigen_info *ui, int peb_size, int min_io_size,
ui->data_offs *= min_io_size;
ui->leb_size = peb_size - ui->data_offs;
ui->ubi_ver = ubi_ver;
- ui->ec = ec;
- ui->vtbl_size = ui->leb_size;
- if (ui->vtbl_size > UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE)
- ui->vtbl_size = UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE;
- ui->max_volumes = ui->vtbl_size / UBI_VTBL_RECORD_SIZE;
+ ui->max_volumes = ui->leb_size / UBI_VTBL_RECORD_SIZE;
+ if (ui->max_volumes > UBI_MAX_VOLUMES)
+ ui->max_volumes = UBI_MAX_VOLUMES;
+ ui->vtbl_size = ui->max_volumes * UBI_VTBL_RECORD_SIZE;
}
/**
@@ -88,11 +85,11 @@ struct ubi_vtbl_record *ubigen_create_empty_vtbl(const struct ubigen_info *ui)
vtbl = calloc(1, ui->vtbl_size);
if (!vtbl) {
- errmsg("cannot allocate %d bytes of memory", ui->vtbl_size);
+ sys_errmsg("cannot allocate %d bytes of memory", ui->vtbl_size);
return NULL;
}
- for (i = 0; i < UBI_MAX_VOLUMES; i++) {
+ for (i = 0; i < ui->max_volumes; i++) {
uint32_t crc = crc32(UBI_CRC32_INIT, &vtbl[i],
UBI_VTBL_RECORD_SIZE_CRC);
vtbl[i].crc = cpu_to_be32(crc);
@@ -144,12 +141,13 @@ int ubigen_add_volume(const struct ubigen_info *ui,
}
/**
- * init_ec_hdr - initialize EC header.
+ * ubigen_init_ec_hdr - initialize EC header.
* @ui: libubigen information
* @hdr: the EC header to initialize
+ * @ec: erase counter value
*/
-static void init_ec_hdr(const struct ubigen_info *ui,
- struct ubi_ec_hdr *hdr)
+void ubigen_init_ec_hdr(const struct ubigen_info *ui,
+ struct ubi_ec_hdr *hdr, long long ec)
{
uint32_t crc;
@@ -157,7 +155,7 @@ static void init_ec_hdr(const struct ubigen_info *ui,
hdr->magic = cpu_to_be32(UBI_EC_HDR_MAGIC);
hdr->version = ui->ubi_ver;
- hdr->ec = cpu_to_be64(ui->ec);
+ hdr->ec = cpu_to_be64(ec);
hdr->vid_hdr_offset = cpu_to_be32(ui->vid_hdr_offs);
hdr->data_offset = cpu_to_be32(ui->data_offs);
@@ -210,6 +208,7 @@ static void init_vid_hdr(const struct ubigen_info *ui,
* ubigen_write_volume - write UBI volume.
* @ui: libubigen information
* @vi: volume information
+ * @ec: erase coutner value to put to EC headers
* @bytes: volume size in bytes
* @in: input file descriptor (has to be properly seeked)
* @out: output file descriptor
@@ -219,8 +218,8 @@ static void init_vid_hdr(const struct ubigen_info *ui,
* %-1 on failure.
*/
int ubigen_write_volume(const struct ubigen_info *ui,
- const struct ubigen_vol_info *vi,
- long long bytes, FILE *in, FILE *out)
+ const struct ubigen_vol_info *vi, long long ec,
+ long long bytes, int in, int out)
{
int len = vi->usable_leb_size, rd, lnum = 0;
char inbuf[ui->leb_size], outbuf[ui->peb_size];
@@ -234,7 +233,7 @@ int ubigen_write_volume(const struct ubigen_info *ui,
vi->alignment, ui->leb_size);
memset(outbuf, 0xFF, ui->data_offs);
- init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf);
+ ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec);
while (bytes) {
int l;
@@ -246,13 +245,9 @@ int ubigen_write_volume(const struct ubigen_info *ui,
l = len;
do {
- rd = fread(inbuf + len - l, 1, l, in);
- if (rd == 0) {
- if (ferror(in))
- return errmsg("cannot read %d bytes from the input file", l);
- else
- return errmsg("not enough data in the input file");
- }
+ rd = read(in, inbuf + len - l, l);
+ if (rd != l)
+ return sys_errmsg("cannot read %d bytes from the input file", l);
l -= rd;
} while (l);
@@ -264,8 +259,8 @@ int ubigen_write_volume(const struct ubigen_info *ui,
memset(outbuf + ui->data_offs + len, 0xFF,
ui->peb_size - ui->data_offs - len);
- if (fwrite(outbuf, 1, ui->peb_size, out) != ui->peb_size)
- return errmsg("cannot write %d bytes from the output file", l);
+ if (write(out, outbuf, ui->peb_size) != ui->peb_size)
+ return sys_errmsg("cannot write %d bytes to the output file", ui->peb_size);
lnum += 1;
}
@@ -276,27 +271,30 @@ int ubigen_write_volume(const struct ubigen_info *ui,
/**
* ubigen_write_layout_vol - write UBI layout volume
* @ui: libubigen information
+ * @peb1: physical eraseblock number to write the first volume table copy
+ * @peb2: physical eraseblock number to write the second volume table copy
+ * @ec1: erase counter value for @peb1
+ * @ec2: erase counter value for @peb1
* @vtbl: volume table
- * @out: output file stream
+ * @fd: output file descriptor seeked to the proper position
*
* This function creates the UBI layout volume which contains 2 copies of the
* volume table. Returns zero in case of success and %-1 in case of failure.
*/
-int ubigen_write_layout_vol(const struct ubigen_info *ui,
- struct ubi_vtbl_record *vtbl, FILE *out)
+int ubigen_write_layout_vol(const struct ubigen_info *ui, int peb1, int peb2,
+ long long ec1, long long ec2,
+ struct ubi_vtbl_record *vtbl, int fd)
{
- int size = ui->leb_size;
+ int ret;
struct ubigen_vol_info vi;
char outbuf[ui->peb_size];
struct ubi_vid_hdr *vid_hdr;
-
- if (size > UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE)
- size = UBI_MAX_VOLUMES * UBI_VTBL_RECORD_SIZE;
+ off_t seek;
vi.bytes = ui->leb_size * UBI_LAYOUT_VOLUME_EBS;
vi.id = UBI_LAYOUT_VOLUME_ID;
vi.alignment = UBI_LAYOUT_VOLUME_ALIGN;
- vi.data_pad = ui->leb_size % UBI_LAYOUT_VOLUME_ALIGN;
+ vi.data_pad = ui->leb_size % UBI_LAYOUT_VOLUME_ALIGN;
vi.usable_leb_size = ui->leb_size - vi.data_pad;
vi.data_pad = ui->leb_size - vi.usable_leb_size;
vi.type = UBI_LAYOUT_VOLUME_TYPE;
@@ -306,19 +304,27 @@ int ubigen_write_layout_vol(const struct ubigen_info *ui,
memset(outbuf, 0xFF, ui->data_offs);
vid_hdr = (struct ubi_vid_hdr *)(&outbuf[ui->vid_hdr_offs]);
- init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf);
- memcpy(outbuf + ui->data_offs, vtbl, size);
- memset(outbuf + ui->data_offs + size, 0xFF,
- ui->peb_size - ui->data_offs - size);
-
+ memcpy(outbuf + ui->data_offs, vtbl, ui->vtbl_size);
+ memset(outbuf + ui->data_offs + ui->vtbl_size, 0xFF,
+ ui->peb_size - ui->data_offs - ui->vtbl_size);
+
+ seek = peb1 * ui->peb_size;
+ if (lseek(fd, seek, SEEK_SET) != seek)
+ return sys_errmsg("cannot seek output file");
+ ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec1);
init_vid_hdr(ui, &vi, vid_hdr, 0, NULL, 0);
- size = fwrite(outbuf, 1, ui->peb_size, out);
- if (size == ui->peb_size) {
- init_vid_hdr(ui, &vi, vid_hdr, 1, NULL, 0);
- size = fwrite(outbuf, 1, ui->peb_size, out);
- if (size != ui->peb_size)
- return sys_errmsg("cannot write %d bytes", ui->peb_size);
- }
+ ret = write(fd, outbuf, ui->peb_size);
+ if (ret != ui->peb_size)
+ return sys_errmsg("cannot write %d bytes", ui->peb_size);
+
+ seek = peb2 * ui->peb_size;
+ if (lseek(fd, seek, SEEK_SET) != seek)
+ return sys_errmsg("cannot seek output file");
+ ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec2);
+ init_vid_hdr(ui, &vi, vid_hdr, 1, NULL, 0);
+ ret = write(fd, outbuf, ui->peb_size);
+ if (ret != ui->peb_size)
+ return sys_errmsg("cannot write %d bytes", ui->peb_size);
return 0;
}
diff --git a/ubi-utils/new-utils/src/ubiattach.c b/ubi-utils/new-utils/src/ubiattach.c
index 04a2f9c..3e19eca 100644
--- a/ubi-utils/new-utils/src/ubiattach.c
+++ b/ubi-utils/new-utils/src/ubiattach.c
@@ -84,7 +84,7 @@ static int parse_opt(int argc, char * const argv[])
int key;
char *endp;
- key = getopt_long(argc, argv, "m:d:OhV", long_options, NULL);
+ key = getopt_long(argc, argv, "m:d:O:hV", long_options, NULL);
if (key == -1)
break;
@@ -103,7 +103,7 @@ static int parse_opt(int argc, char * const argv[])
break;
- case 'o':
+ case 'O':
args.vidoffs = strtoul(optarg, &endp, 0);
if (*endp != '\0' || endp == optarg || args.vidoffs <= 0)
return errmsg("bad VID header offset: \"%s\"", optarg);
diff --git a/ubi-utils/new-utils/src/ubinize.c b/ubi-utils/new-utils/src/ubinize.c
index bd1b07b..dab224b 100644
--- a/ubi-utils/new-utils/src/ubinize.c
+++ b/ubi-utils/new-utils/src/ubinize.c
@@ -24,12 +24,14 @@
* Oliver Lohmann
*/
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <stdlib.h>
#include <getopt.h>
-#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <sys/stat.h>
+#include <fcntl.h>
#include <mtd/ubi-header.h>
#include <libubigen.h>
@@ -49,7 +51,7 @@ static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION
"parameters, do not specify them and let the utility to use default values.";
static const char *optionsstr =
-"-o, --output=<file name> output file name (default is stdout)\n"
+"-o, --output=<file name> output file name\n"
"-p, --peb-size=<bytes> size of the physical eraseblock of the flash\n"
" this UBI image is created for in bytes,\n"
" kilobytes (KiB), or megabytes (MiB)\n"
@@ -61,14 +63,14 @@ static const char *optionsstr =
" flash (equivalent to the minimum input/output\n"
" unit size by default)\n"
"-O, --vid-hdr-offset=<num> offset if the VID header from start of the\n"
-" physical eraseblock (default is the second\n"
-" minimum I/O unit or sub-page, if it was\n"
-" specified)\n"
+" physical eraseblock (default is the next\n"
+" minimum I/O unit or sub-page after the EC\n"
+" header)\n"
"-e, --erase-counter=<num> the erase counter value to put to EC headers\n"
" (default is 0)\n"
"-x, --ubi-ver=<num> UBI version number to put to EC headers\n"
" (default is 1)\n"
-"-v --verbose be verbose\n"
+"-v, --verbose be verbose\n"
"-h, --help print help message\n"
"-V, --version print program version";
@@ -128,7 +130,7 @@ struct option long_options[] = {
struct args {
const char *f_in;
const char *f_out;
- FILE *fp_out;
+ int out_fd;
int peb_size;
int min_io_size;
int subpage_size;
@@ -140,14 +142,10 @@ struct args {
};
static struct args args = {
- .f_out = NULL,
.peb_size = -1,
.min_io_size = -1,
.subpage_size = -1,
- .vid_hdr_offs = 0,
- .ec = 0,
.ubi_ver = 1,
- .verbose = 0,
};
static int parse_opt(int argc, char * const argv[])
@@ -162,9 +160,10 @@ static int parse_opt(int argc, char * const argv[])
switch (key) {
case 'o':
- args.fp_out = fopen(optarg, "wb");
- if (!args.fp_out)
- return errmsg("cannot open file \"%s\"", optarg);
+ args.out_fd = open(optarg, O_CREAT | O_TRUNC | O_WRONLY,
+ S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH);
+ if (args.out_fd == -1)
+ return sys_errmsg("cannot open file \"%s\"", optarg);
args.f_out = optarg;
break;
@@ -242,16 +241,14 @@ static int parse_opt(int argc, char * const argv[])
if (args.subpage_size < 0)
args.subpage_size = args.min_io_size;
- if (!args.f_out) {
- args.f_out = "stdout";
- args.fp_out = stdout;
- }
+ if (!args.f_out)
+ return errmsg("output file was not specified (use -h for help)");
return 0;
}
-int read_section(const char *sname, struct ubigen_vol_info *vi,
- const char **img)
+static int read_section(const char *sname, struct ubigen_vol_info *vi,
+ const char **img)
{
char buf[256];
const char *p;
@@ -401,6 +398,7 @@ int main(int argc, char * const argv[])
int err = -1, sects, i, volumes;
struct ubigen_info ui;
struct ubi_vtbl_record *vtbl;
+ off_t seek;
err = parse_opt(argc, argv);
if (err)
@@ -408,7 +406,7 @@ int main(int argc, char * const argv[])
ubigen_info_init(&ui, args.peb_size, args.min_io_size,
args.subpage_size, args.vid_hdr_offs,
- args.ubi_ver, args.ec);
+ args.ubi_ver);
verbose(args.verbose, "LEB size: %d", ui.leb_size);
verbose(args.verbose, "PEB size: %d", ui.peb_size);
@@ -444,8 +442,9 @@ int main(int argc, char * const argv[])
* Skip 2 PEBs at the beginning of the file for the volume table which
* will be written later.
*/
- if (fseek(args.fp_out, ui.peb_size * 2, SEEK_SET) == -1) {
- errmsg("cannot seek file \"%s\"", args.f_out);
+ seek = ui.peb_size * 2;
+ if (lseek(args.out_fd, seek, SEEK_SET) != seek) {
+ sys_errmsg("cannot seek file \"%s\"", args.f_out);
goto out_dict;
}
@@ -454,7 +453,7 @@ int main(int argc, char * const argv[])
struct ubigen_vol_info vi;
const char *img = NULL;
struct stat st;
- FILE *f;
+ int fd;
if (!sname) {
errmsg("ini-file parsing error (iniparser_getsecname)");
@@ -472,6 +471,10 @@ int main(int argc, char * const argv[])
volumes += 1;
init_vol_info(&ui, &vi);
+ if (vi.id >= ui.max_volumes)
+ return errmsg("too high volume ID %d, max. is %d",
+ vi.id, ui.max_volumes);
+
verbose(args.verbose, "adding volume %d", vi.id);
err = ubigen_add_volume(&ui, &vi, vtbl);
@@ -498,8 +501,8 @@ int main(int argc, char * const argv[])
goto out_dict;
}
- f = fopen(img, "r");
- if (!f) {
+ fd = open(img, O_RDONLY);
+ if (fd == -1) {
sys_errmsg("cannot open \"%s\"", img);
goto out_dict;
}
@@ -507,8 +510,8 @@ int main(int argc, char * const argv[])
verbose(args.verbose, "writing volume %d", vi.id);
verbose(args.verbose, "image file: %s", img);
- err = ubigen_write_volume(&ui, &vi, st.st_size, f, args.fp_out);
- fclose(f);
+ err = ubigen_write_volume(&ui, &vi, args.ec, st.st_size, fd, args.out_fd);
+ close(fd);
if (err) {
errmsg("cannot write volume for section \"%s\"", sname);
goto out_dict;
@@ -520,12 +523,7 @@ int main(int argc, char * const argv[])
verbose(args.verbose, "writing layout volume");
- if (fseek(args.fp_out, 0, SEEK_SET) == -1) {
- errmsg("cannot seek file \"%s\"", args.f_out);
- goto out_dict;
- }
-
- err = ubigen_write_layout_vol(&ui, vtbl, args.fp_out);
+ err = ubigen_write_layout_vol(&ui, 0, 1, args.ec, args.ec, vtbl, args.out_fd);
if (err) {
errmsg("cannot write layout volume");
goto out_dict;
@@ -535,7 +533,7 @@ int main(int argc, char * const argv[])
iniparser_freedict(args.dict);
free(vtbl);
- fclose(args.fp_out);
+ close(args.out_fd);
return 0;
out_dict:
@@ -543,7 +541,7 @@ out_dict:
out_vtbl:
free(vtbl);
out:
- fclose(args.fp_out);
+ close(args.out_fd);
remove(args.f_out);
return err;
}