1263409Smarcel/*- 2263409Smarcel * Copyright (c) 2014 Juniper Networks, Inc. 3263409Smarcel * All rights reserved. 4263409Smarcel * 5263409Smarcel * Redistribution and use in source and binary forms, with or without 6263409Smarcel * modification, are permitted provided that the following conditions 7263409Smarcel * are met: 8263409Smarcel * 1. Redistributions of source code must retain the above copyright 9263409Smarcel * notice, this list of conditions and the following disclaimer. 10263409Smarcel * 2. Redistributions in binary form must reproduce the above copyright 11263409Smarcel * notice, this list of conditions and the following disclaimer in the 12263409Smarcel * documentation and/or other materials provided with the distribution. 13263409Smarcel * 14263409Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15263409Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16263409Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17263409Smarcel * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18263409Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19263409Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20263409Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21263409Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22263409Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23263409Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24263409Smarcel * SUCH DAMAGE. 25263409Smarcel */ 26263409Smarcel 27263409Smarcel#include <sys/cdefs.h> 28263409Smarcel__FBSDID("$FreeBSD$"); 29263409Smarcel 30263409Smarcel#include <sys/types.h> 31263442Smarcel#include <sys/diskmbr.h> 32263674Smarcel#include <sys/endian.h> 33263442Smarcel#include <sys/errno.h> 34263409Smarcel#include <stdlib.h> 35263674Smarcel#include <string.h> 36263674Smarcel#include <unistd.h> 37263409Smarcel 38268161Smarcel#include "image.h" 39263409Smarcel#include "mkimg.h" 40263409Smarcel#include "scheme.h" 41263409Smarcel 42268161Smarcel#ifndef DOSPTYP_FAT32 43268161Smarcel#define DOSPTYP_FAT32 0x0b 44268161Smarcel#endif 45268161Smarcel 46263409Smarcelstatic struct mkimg_alias ebr_aliases[] = { 47263674Smarcel { ALIAS_FAT32, ALIAS_INT2TYPE(DOSPTYP_FAT32) }, 48263674Smarcel { ALIAS_FREEBSD, ALIAS_INT2TYPE(DOSPTYP_386BSD) }, 49263487Smarcel { ALIAS_NONE, 0 } 50263409Smarcel}; 51263409Smarcel 52272030Smarcelstatic lba_t 53272030Smarcelebr_metadata(u_int where, lba_t blk) 54263409Smarcel{ 55263409Smarcel 56272030Smarcel blk += (where == SCHEME_META_PART_BEFORE) ? 1 : 0; 57272030Smarcel return (round_track(blk)); 58263409Smarcel} 59263409Smarcel 60263674Smarcelstatic void 61263674Smarcelebr_chs(u_char *cyl, u_char *hd, u_char *sec, uint32_t lba __unused) 62263674Smarcel{ 63263674Smarcel 64263674Smarcel *cyl = 0xff; /* XXX */ 65263674Smarcel *hd = 0xff; /* XXX */ 66263674Smarcel *sec = 0xff; /* XXX */ 67263674Smarcel} 68263674Smarcel 69263442Smarcelstatic int 70268161Smarcelebr_write(lba_t imgsz __unused, void *bootcode __unused) 71263442Smarcel{ 72263674Smarcel u_char *ebr; 73263674Smarcel struct dos_partition *dp; 74263674Smarcel struct part *part, *next; 75263843Smarcel lba_t block; 76263674Smarcel int error; 77263674Smarcel 78263674Smarcel ebr = malloc(secsz); 79263674Smarcel if (ebr == NULL) 80263674Smarcel return (ENOMEM); 81263674Smarcel memset(ebr, 0, secsz); 82263674Smarcel le16enc(ebr + DOSMAGICOFFSET, DOSMAGIC); 83263674Smarcel 84263674Smarcel error = 0; 85263674Smarcel STAILQ_FOREACH_SAFE(part, &partlist, link, next) { 86263843Smarcel block = part->block - nsecs; 87263674Smarcel dp = (void *)(ebr + DOSPARTOFF); 88263843Smarcel ebr_chs(&dp->dp_scyl, &dp->dp_shd, &dp->dp_ssect, nsecs); 89263674Smarcel dp->dp_typ = ALIAS_TYPE2INT(part->type); 90263674Smarcel ebr_chs(&dp->dp_ecyl, &dp->dp_ehd, &dp->dp_esect, 91263674Smarcel part->block + part->size - 1); 92263843Smarcel le32enc(&dp->dp_start, nsecs); 93263674Smarcel le32enc(&dp->dp_size, part->size); 94263674Smarcel 95263674Smarcel /* Add link entry */ 96263674Smarcel if (next != NULL) { 97263674Smarcel dp++; 98263674Smarcel ebr_chs(&dp->dp_scyl, &dp->dp_shd, &dp->dp_ssect, 99263843Smarcel next->block - nsecs); 100263674Smarcel dp->dp_typ = DOSPTYP_EXT; 101263674Smarcel ebr_chs(&dp->dp_ecyl, &dp->dp_ehd, &dp->dp_esect, 102263674Smarcel next->block + next->size - 1); 103263843Smarcel le32enc(&dp->dp_start, next->block - nsecs); 104263843Smarcel le32enc(&dp->dp_size, next->size + nsecs); 105263674Smarcel } 106263674Smarcel 107268161Smarcel error = image_write(block, ebr, 1); 108263674Smarcel if (error) 109263674Smarcel break; 110263674Smarcel 111263674Smarcel memset(ebr + DOSPARTOFF, 0, 2 * DOSPARTSIZE); 112263674Smarcel } 113263674Smarcel 114263674Smarcel free(ebr); 115263674Smarcel return (error); 116263442Smarcel} 117263442Smarcel 118263409Smarcelstatic struct mkimg_scheme ebr_scheme = { 119263409Smarcel .name = "ebr", 120263409Smarcel .description = "Extended Boot Record", 121263409Smarcel .aliases = ebr_aliases, 122263440Smarcel .metadata = ebr_metadata, 123263442Smarcel .write = ebr_write, 124263700Smarcel .nparts = 4096, 125263700Smarcel .maxsecsz = 4096 126263409Smarcel}; 127263409Smarcel 128263409SmarcelSCHEME_DEFINE(ebr_scheme); 129