Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/mkimg/mkimg.c
Show All 21 Lines | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | |||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <getopt.h> | #include <getopt.h> | ||||
#include <libutil.h> | #include <libutil.h> | ||||
#include <limits.h> | #include <limits.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <sysexits.h> | #include <sysexits.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include "image.h" | #include "image.h" | ||||
#include "format.h" | #include "format.h" | ||||
#include "mkimg.h" | #include "mkimg.h" | ||||
#include "scheme.h" | #include "scheme.h" | ||||
#define LONGOPT_FORMATS 0x01000001 | #define LONGOPT_FORMATS 0x01000001 | ||||
#define LONGOPT_SCHEMES 0x01000002 | #define LONGOPT_SCHEMES 0x01000002 | ||||
#define LONGOPT_VERSION 0x01000003 | #define LONGOPT_VERSION 0x01000003 | ||||
#define LONGOPT_CAPACITY 0x01000004 | |||||
static struct option longopts[] = { | static struct option longopts[] = { | ||||
{ "formats", no_argument, NULL, LONGOPT_FORMATS }, | { "formats", no_argument, NULL, LONGOPT_FORMATS }, | ||||
{ "schemes", no_argument, NULL, LONGOPT_SCHEMES }, | { "schemes", no_argument, NULL, LONGOPT_SCHEMES }, | ||||
{ "version", no_argument, NULL, LONGOPT_VERSION }, | { "version", no_argument, NULL, LONGOPT_VERSION }, | ||||
{ "capacity", required_argument, NULL, LONGOPT_CAPACITY }, | |||||
{ NULL, 0, NULL, 0 } | { NULL, 0, NULL, 0 } | ||||
}; | }; | ||||
static uint64_t capacity; | static uint64_t min_capacity = 0; | ||||
static uint64_t max_capacity = 0; | |||||
struct partlisthead partlist = TAILQ_HEAD_INITIALIZER(partlist); | struct partlisthead partlist = TAILQ_HEAD_INITIALIZER(partlist); | ||||
u_int nparts = 0; | u_int nparts = 0; | ||||
u_int unit_testing; | u_int unit_testing; | ||||
u_int verbose; | u_int verbose; | ||||
u_int ncyls = 0; | u_int ncyls = 0; | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | usage(const char *why) | ||||
fprintf(stderr, " options:\n"); | fprintf(stderr, " options:\n"); | ||||
fprintf(stderr, "\t--formats\t- list image formats\n"); | fprintf(stderr, "\t--formats\t- list image formats\n"); | ||||
fprintf(stderr, "\t--schemes\t- list partition schemes\n"); | fprintf(stderr, "\t--schemes\t- list partition schemes\n"); | ||||
fprintf(stderr, "\t--version\t- show version information\n"); | fprintf(stderr, "\t--version\t- show version information\n"); | ||||
fputc('\n', stderr); | fputc('\n', stderr); | ||||
fprintf(stderr, "\t-a <num>\t- mark num'th partion as active\n"); | fprintf(stderr, "\t-a <num>\t- mark num'th partion as active\n"); | ||||
fprintf(stderr, "\t-b <file>\t- file containing boot code\n"); | fprintf(stderr, "\t-b <file>\t- file containing boot code\n"); | ||||
fprintf(stderr, "\t-c <num>\t- capacity (in bytes) of the disk\n"); | fprintf(stderr, "\t-c <num>\t- minimum capacity (in bytes) of the disk\n"); | ||||
fprintf(stderr, "\t-C <num>\t- maximum capacity (in bytes) of the disk\n"); | |||||
fprintf(stderr, "\t-f <format>\n"); | fprintf(stderr, "\t-f <format>\n"); | ||||
fprintf(stderr, "\t-o <file>\t- file to write image into\n"); | fprintf(stderr, "\t-o <file>\t- file to write image into\n"); | ||||
fprintf(stderr, "\t-p <partition>\n"); | fprintf(stderr, "\t-p <partition>\n"); | ||||
fprintf(stderr, "\t-s <scheme>\n"); | fprintf(stderr, "\t-s <scheme>\n"); | ||||
fprintf(stderr, "\t-v\t\t- increase verbosity\n"); | fprintf(stderr, "\t-v\t\t- increase verbosity\n"); | ||||
fprintf(stderr, "\t-y\t\t- [developers] enable unit test\n"); | fprintf(stderr, "\t-y\t\t- [developers] enable unit test\n"); | ||||
fprintf(stderr, "\t-H <num>\t- number of heads to simulate\n"); | fprintf(stderr, "\t-H <num>\t- number of heads to simulate\n"); | ||||
fprintf(stderr, "\t-P <num>\t- physical sector size\n"); | fprintf(stderr, "\t-P <num>\t- physical sector size\n"); | ||||
▲ Show 20 Lines • Show All 213 Lines • ▼ Show 20 Lines | mkimg_chs(lba_t lba, u_int maxcyl, u_int *cylp, u_int *hdp, u_int *secp) | ||||
*cylp = lba; | *cylp = lba; | ||||
*hdp = hd; | *hdp = hd; | ||||
*secp = sec; | *secp = sec; | ||||
} | } | ||||
static int | static int | ||||
capacity_resize(lba_t end) | capacity_resize(lba_t end) | ||||
{ | { | ||||
lba_t capsz; | lba_t min_capsz, max_capsz; | ||||
capsz = (capacity + secsz - 1) / secsz; | min_capsz = (min_capacity + secsz - 1) / secsz; | ||||
if (end >= capsz) | max_capsz = (max_capacity + secsz - 1) / secsz; | ||||
if (max_capsz != 0 && end > max_capsz) | |||||
return (ENOSPC); | |||||
if (end >= min_capsz) | |||||
return (0); | return (0); | ||||
return (image_set_size(capsz)); | |||||
return (image_set_size(min_capsz)); | |||||
} | } | ||||
static void | static void | ||||
mkimg(void) | mkimg(void) | ||||
{ | { | ||||
FILE *fp; | FILE *fp; | ||||
struct part *part; | struct part *part; | ||||
lba_t block; | lba_t block; | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||
{ | { | ||||
int bcfd, outfd; | int bcfd, outfd; | ||||
int c, error; | int c, error; | ||||
bcfd = -1; | bcfd = -1; | ||||
outfd = 1; /* Write to stdout by default */ | outfd = 1; /* Write to stdout by default */ | ||||
while ((c = getopt_long(argc, argv, "a:b:c:f:o:p:s:vyH:P:S:T:", | while ((c = getopt_long(argc, argv, "a:b:c:C:f:o:p:s:vyH:P:S:T:", | ||||
longopts, NULL)) != -1) { | longopts, NULL)) != -1) { | ||||
switch (c) { | switch (c) { | ||||
case 'a': /* ACTIVE PARTITION, if supported */ | case 'a': /* ACTIVE PARTITION, if supported */ | ||||
error = parse_uint32(&active_partition, 1, 100, optarg); | error = parse_uint32(&active_partition, 1, 100, optarg); | ||||
if (error) | if (error) | ||||
errc(EX_DATAERR, error, "Partition ordinal"); | errc(EX_DATAERR, error, "Partition ordinal"); | ||||
break; | break; | ||||
case 'b': /* BOOT CODE */ | case 'b': /* BOOT CODE */ | ||||
if (bcfd != -1) | if (bcfd != -1) | ||||
usage("multiple bootcode given"); | usage("multiple bootcode given"); | ||||
bcfd = open(optarg, O_RDONLY, 0); | bcfd = open(optarg, O_RDONLY, 0); | ||||
if (bcfd == -1) | if (bcfd == -1) | ||||
err(EX_UNAVAILABLE, "%s", optarg); | err(EX_UNAVAILABLE, "%s", optarg); | ||||
break; | break; | ||||
case 'c': /* CAPACITY */ | case 'c': /* MINIMUM CAPACITY */ | ||||
error = parse_uint64(&capacity, 1, INT64_MAX, optarg); | error = parse_uint64(&min_capacity, 1, INT64_MAX, optarg); | ||||
if (error) | if (error) | ||||
errc(EX_DATAERR, error, "capacity in bytes"); | errc(EX_DATAERR, error, "minimum capacity in bytes"); | ||||
break; | break; | ||||
case 'C': /* MAXIMUM CAPACITY */ | |||||
error = parse_uint64(&max_capacity, 1, INT64_MAX, optarg); | |||||
if (error) | |||||
errc(EX_DATAERR, error, "maximum capacity in bytes"); | |||||
break; | |||||
case 'f': /* OUTPUT FORMAT */ | case 'f': /* OUTPUT FORMAT */ | ||||
if (format_selected() != NULL) | if (format_selected() != NULL) | ||||
usage("multiple formats given"); | usage("multiple formats given"); | ||||
error = format_select(optarg); | error = format_select(optarg); | ||||
if (error) | if (error) | ||||
errc(EX_DATAERR, error, "format"); | errc(EX_DATAERR, error, "format"); | ||||
break; | break; | ||||
case 'o': /* OUTPUT FILE */ | case 'o': /* OUTPUT FILE */ | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | while ((c = getopt_long(argc, argv, "a:b:c:C:f:o:p:s:vyH:P:S:T:", | ||||
case LONGOPT_SCHEMES: | case LONGOPT_SCHEMES: | ||||
print_schemes(0); | print_schemes(0); | ||||
exit(EX_OK); | exit(EX_OK); | ||||
/*NOTREACHED*/ | /*NOTREACHED*/ | ||||
case LONGOPT_VERSION: | case LONGOPT_VERSION: | ||||
print_version(); | print_version(); | ||||
exit(EX_OK); | exit(EX_OK); | ||||
/*NOTREACHED*/ | /*NOTREACHED*/ | ||||
case LONGOPT_CAPACITY: | |||||
error = parse_uint64(&min_capacity, 1, INT64_MAX, optarg); | |||||
if (error) | |||||
errc(EX_DATAERR, error, "capacity in bytes"); | |||||
max_capacity = min_capacity; | |||||
break; | |||||
default: | default: | ||||
usage("unknown option"); | usage("unknown option"); | ||||
} | } | ||||
} | } | ||||
if (argc > optind) | if (argc > optind) | ||||
usage("trailing arguments"); | usage("trailing arguments"); | ||||
if (scheme_selected() == NULL && nparts > 0) | if (scheme_selected() == NULL && nparts > 0) | ||||
usage("no scheme"); | usage("no scheme"); | ||||
if (nparts == 0 && capacity == 0) | if (nparts == 0 && min_capacity == 0) | ||||
usage("no partitions"); | usage("no partitions"); | ||||
if (max_capacity != 0 && min_capacity > max_capacity) | |||||
usage("minimum capacity cannot be larger than the maximum one"); | |||||
if (secsz > blksz) { | if (secsz > blksz) { | ||||
if (blksz != 0) | if (blksz != 0) | ||||
errx(EX_DATAERR, "the physical block size cannot " | errx(EX_DATAERR, "the physical block size cannot " | ||||
"be smaller than the sector size"); | "be smaller than the sector size"); | ||||
blksz = secsz; | blksz = secsz; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 49 Lines • Show Last 20 Lines |