r306325 by marcel: Replace the use of linker sets with constructors for both the formats and schemes. Formats and schemes are registered at runtime now, rather than collected at link time. r306329 by marcel: Eliminate the use of EDOOFUS. The error code was used to signal programming errors, but is really a poor substitute for assert. And less portable as well. r306330 by marcel: Avoid depending on the <sys/endian.h> header for le*enc and be*enc. Not only is the header unportable, the encoding/decoding functions are as well. Instead, duplicate the handful of small inlines we need into a private header called endian.h. Aside: an alternative approach is to move the encoding/decoding functions to a separate system header. While the header is still nonportable, such an approach would make it possible to re-use the definitions by playing games with include paths. This may be the preferred approach if more (build) utilities need this. This change does not preclude that. In fact, it makes it easier. r306333 by marcel: Portability changes: 1. macOS nor Linux have MAP_NOCORE nor MAP_NOSYNC. Define as 0. 2. macOS doesn't have SEEK_DATA nor SEEK_HOLE. Define as -1 so that lseek will return -1 (with errno set to EINVAL). 3. gcc correctly warns that error is assigned but not used in image_copyout_region(). Fix by returning on the first error. r306620 by marcel: Replace STAILQ with TAILQ. TAILQs are portable enough that they can be used on both macOS and Linux. STAILQs are not. In particular, STAILQ_LAST does not next on Linux. Since neither STAILQ_FOREACH_SAFE nor TAILQ_FOREACH_SAFE exist on Linux, replace its use with a regular TAILQ_FOREACH. The _SAFE variant was only used for having the next pointer in a local variable. r306621 by marcel: Prefer <stdint.h> over <sys/types.h>. While here remove redundant inclusion of <sys/queue.h>. Move the inclusion of the disk partitioning headers out of order and inbetween standard headers and local header. They will change in a subsequent commit. r306622 by marcel: Replace OFF_MAX with INT64_MAX. The former is defined on Linux. r307544 by marcel: o Provide a private definition for UUIDs (mkimg_uuid_t) because UUIDs are not portable. o Move mkimg_uuid() to a new file and merge both gpt_uuid_enc() and vhd_uuid_enc() into a single mkimg_uuid_enc() that lives in the same file. o Move the OS-specific implementation of generating a UUID to osdep_uuidgen() and provide the implementations for FreeBSD, macOS and Linux. o Expect the partitioning scheme headers to be found by having a search to the directory in which the headers live. This avoids conflicts on non-FreeBSD machines. r307550 by imp: Add a new flag to mkimg (-a num) to specify the active partition for those partitioning schemes that have this concept. Implement it as an override for mbr's setting 0x80 in the flags for the first partition when we have boot code. Differential Revision: https://reviews.freebsd.org/D4403 r318137: mkimg: Add -C argument to specify maximum capacity Add a -C option to specify a maximum capacity for the final image file. It is useful to control the size of the generated image for sdcard or when we will add dynamic size partition. Add --capacity which is a shorthand to define min and max capacity at the same time. Reviewed by: bapt, marcel, wblock (manpages) Sponsored by: Gandi.net Differential Revision: https://reviews.freebsd.org/D10509 r319125: mkimg: Correct an off by one error in the PMBR size The PMBR last sector should be number of sector - 1 (As stated in UEFI Spec 2.6 page 118 table 17). This fixes warning printed by linux tools like parted or fdisk. Sponsored by: Gandi.net r319295 by ngie: Update the usr.bin/mkimg golden test output files after ^/head@r319125 ^/head@r319125 changed the location of the backup pmbr, requiring the output files to be regenerated, since they're binary disk dumps. The output files were regenerated with "make rebase"--fixed in ^/head@r319294. MFC with: r319125, r319294 PR: 219673 Sponsored by: Dell EMC Isilon
126 lines
3.1 KiB
C
126 lines
3.1 KiB
C
/*-
|
|
* Copyright (c) 2016 Marcel Moolenaar
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* 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
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "endian.h"
|
|
#include "image.h"
|
|
#include "mkimg.h"
|
|
|
|
static void osdep_uuidgen(mkimg_uuid_t *);
|
|
|
|
#ifdef __APPLE__
|
|
#include <uuid/uuid.h>
|
|
|
|
static void
|
|
osdep_uuidgen(mkimg_uuid_t *uuid)
|
|
{
|
|
|
|
uuid_generate_time((void *)uuid);
|
|
}
|
|
#endif /* __APPLE__ */
|
|
|
|
#ifdef __FreeBSD__
|
|
#include <sys/uuid.h>
|
|
|
|
static void
|
|
osdep_uuidgen(mkimg_uuid_t *uuid)
|
|
{
|
|
|
|
uuidgen((void *)uuid, 1);
|
|
}
|
|
#endif /* __FreeBSD__ */
|
|
|
|
#ifdef __linux__
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
static void
|
|
osdep_uuidgen(mkimg_uuid_t *uuid)
|
|
{
|
|
struct timespec tp;
|
|
uint64_t time = 0x01B21DD213814000LL;
|
|
u_int i;
|
|
uint16_t seq;
|
|
|
|
if (clock_gettime(CLOCK_REALTIME, &tp) == -1)
|
|
abort();
|
|
|
|
time += (uint64_t)tp.tv_sec * 10000000LL;
|
|
time += tp.tv_nsec / 100;
|
|
|
|
uuid->time_low = (uint32_t)time;
|
|
uuid->time_mid = (uint16_t)(time >> 32);
|
|
uuid->time_hi_and_version = (uint16_t)(time >> 48) & 0xfff;
|
|
uuid->time_hi_and_version |= 1 << 12;
|
|
|
|
seq = random();
|
|
|
|
uuid->clock_seq_hi_and_reserved = (uint8_t)(seq >> 8) & 0x3f;
|
|
uuid->clock_seq_low = (uint8_t)seq;
|
|
|
|
for (i = 0; i < 6; i++)
|
|
uuid->node[i] = (uint8_t)random();
|
|
uuid->node[0] |= 0x01;
|
|
}
|
|
#endif /* __linux__ */
|
|
|
|
void
|
|
mkimg_uuid(mkimg_uuid_t *uuid)
|
|
{
|
|
static uint8_t gen[sizeof(mkimg_uuid_t)];
|
|
u_int i;
|
|
|
|
if (!unit_testing) {
|
|
osdep_uuidgen(uuid);
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < sizeof(gen); i++)
|
|
gen[i]++;
|
|
memcpy(uuid, gen, sizeof(*uuid));
|
|
}
|
|
|
|
void
|
|
mkimg_uuid_enc(void *buf, const mkimg_uuid_t *uuid)
|
|
{
|
|
uint8_t *p = buf;
|
|
u_int i;
|
|
|
|
le32enc(p, uuid->time_low);
|
|
le16enc(p + 4, uuid->time_mid);
|
|
le16enc(p + 6, uuid->time_hi_and_version);
|
|
p[8] = uuid->clock_seq_hi_and_reserved;
|
|
p[9] = uuid->clock_seq_low;
|
|
for (i = 0; i < 6; i++)
|
|
p[10 + i] = uuid->node[i];
|
|
}
|