1193323Sed/*- 2193323Sed * Copyright (c) 2014 Juniper Networks, Inc. 3193323Sed * All rights reserved. 4193323Sed * 5193323Sed * Redistribution and use in source and binary forms, with or without 6193323Sed * modification, are permitted provided that the following conditions 7193323Sed * are met: 8193323Sed * 1. Redistributions of source code must retain the above copyright 9193323Sed * notice, this list of conditions and the following disclaimer. 10193323Sed * 2. Redistributions in binary form must reproduce the above copyright 11193323Sed * notice, this list of conditions and the following disclaimer in the 12193323Sed * documentation and/or other materials provided with the distribution. 13193323Sed * 14193323Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15193323Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16193323Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17234353Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18193323Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19193323Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20193323Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21193323Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22193323Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23193323Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24193323Sed * SUCH DAMAGE. 25193323Sed */ 26193323Sed 27193323Sed#include <sys/cdefs.h> 28193323Sed__FBSDID("$FreeBSD$"); 29193323Sed 30249423Sdim#include <sys/types.h> 31249423Sdim#include <sys/apm.h> 32249423Sdim#include <sys/endian.h> 33249423Sdim#include <sys/errno.h> 34193323Sed#include <stdlib.h> 35193323Sed#include <string.h> 36193323Sed#include <unistd.h> 37202375Srdivacky 38249423Sdim#include "image.h" 39288943Sdim#include "mkimg.h" 40193323Sed#include "scheme.h" 41193323Sed 42193323Sed#ifndef APM_ENT_TYPE_APPLE_BOOT 43193323Sed#define APM_ENT_TYPE_APPLE_BOOT "Apple_Bootstrap" 44193323Sed#endif 45234353Sdim#ifndef APM_ENT_TYPE_FREEBSD_NANDFS 46218893Sdim#define APM_ENT_TYPE_FREEBSD_NANDFS "FreeBSD-nandfs" 47218893Sdim#endif 48218893Sdim 49218893Sdimstatic struct mkimg_alias apm_aliases[] = { 50218893Sdim { ALIAS_FREEBSD, ALIAS_PTR2TYPE(APM_ENT_TYPE_FREEBSD) }, 51193323Sed { ALIAS_FREEBSD_BOOT, ALIAS_PTR2TYPE(APM_ENT_TYPE_APPLE_BOOT) }, 52193323Sed { ALIAS_FREEBSD_NANDFS, ALIAS_PTR2TYPE(APM_ENT_TYPE_FREEBSD_NANDFS) }, 53193323Sed { ALIAS_FREEBSD_SWAP, ALIAS_PTR2TYPE(APM_ENT_TYPE_FREEBSD_SWAP) }, 54193323Sed { ALIAS_FREEBSD_UFS, ALIAS_PTR2TYPE(APM_ENT_TYPE_FREEBSD_UFS) }, 55193323Sed { ALIAS_FREEBSD_VINUM, ALIAS_PTR2TYPE(APM_ENT_TYPE_FREEBSD_VINUM) }, 56198090Srdivacky { ALIAS_FREEBSD_ZFS, ALIAS_PTR2TYPE(APM_ENT_TYPE_FREEBSD_ZFS) }, 57193323Sed { ALIAS_NONE, 0 } 58193323Sed}; 59199481Srdivacky 60199481Srdivackystatic lba_t 61199481Srdivackyapm_metadata(u_int where, lba_t blk) 62199481Srdivacky{ 63199481Srdivacky 64276479Sdim blk += (where == SCHEME_META_IMG_START) ? nparts + 2 : 0; 65199481Srdivacky return (round_block(blk)); 66199481Srdivacky} 67193323Sed 68243830Sdimstatic int 69202375Srdivackyapm_write(lba_t imgsz, void *bootcode __unused) 70193323Sed{ 71193323Sed u_char *buf; 72202375Srdivacky struct apm_ddr *ddr; 73202375Srdivacky struct apm_ent *ent; 74193323Sed struct part *part; 75202375Srdivacky int error; 76193323Sed 77193323Sed buf = calloc(nparts + 2, secsz); 78202375Srdivacky if (buf == NULL) 79202375Srdivacky return (ENOMEM); 80193323Sed ddr = (void *)buf; 81243830Sdim be16enc(&ddr->ddr_sig, APM_DDR_SIG); 82193323Sed be16enc(&ddr->ddr_blksize, secsz); 83193323Sed be32enc(&ddr->ddr_blkcount, imgsz); 84193323Sed 85193323Sed /* partition entry for the partition table itself. */ 86193323Sed ent = (void *)(buf + secsz); 87193323Sed be16enc(&ent->ent_sig, APM_ENT_SIG); 88218893Sdim be32enc(&ent->ent_pmblkcnt, nparts + 1); 89193323Sed be32enc(&ent->ent_start, 1); 90193323Sed be32enc(&ent->ent_size, nparts + 1); 91193323Sed strncpy(ent->ent_type, APM_ENT_TYPE_SELF, sizeof(ent->ent_type)); 92193323Sed strncpy(ent->ent_name, "Apple", sizeof(ent->ent_name)); 93193323Sed 94193323Sed STAILQ_FOREACH(part, &partlist, link) { 95193323Sed ent = (void *)(buf + (part->index + 2) * secsz); 96193323Sed be16enc(&ent->ent_sig, APM_ENT_SIG); 97234353Sdim be32enc(&ent->ent_pmblkcnt, nparts + 1); 98193323Sed be32enc(&ent->ent_start, part->block); 99193323Sed be32enc(&ent->ent_size, part->size); 100193323Sed strncpy(ent->ent_type, ALIAS_TYPE2PTR(part->type), 101193323Sed sizeof(ent->ent_type)); 102193323Sed if (part->label != NULL) 103193323Sed strncpy(ent->ent_name, part->label, 104193323Sed sizeof(ent->ent_name)); 105234353Sdim } 106193323Sed 107193323Sed error = image_write(0, buf, nparts + 2); 108193323Sed free(buf); 109193323Sed return (error); 110193323Sed} 111193323Sed 112193323Sedstatic struct mkimg_scheme apm_scheme = { 113193323Sed .name = "apm", 114234353Sdim .description = "Apple Partition Map", 115221345Sdim .aliases = apm_aliases, 116193323Sed .metadata = apm_metadata, 117193323Sed .write = apm_write, 118193323Sed .nparts = 4096, 119193323Sed .labellen = APM_ENT_NAMELEN - 1, 120193323Sed .maxsecsz = 4096 121193323Sed}; 122193323Sed 123193323SedSCHEME_DEFINE(apm_scheme); 124193323Sed