pc98.c revision 272030
185815Sobrien/*- 2218822Sdim * Copyright (c) 2014 Juniper Networks, Inc. 3218822Sdim * All rights reserved. 485815Sobrien * 585815Sobrien * Redistribution and use in source and binary forms, with or without 6130561Sobrien * modification, are permitted provided that the following conditions 785815Sobrien * are met: 8130561Sobrien * 1. Redistributions of source code must retain the above copyright 9130561Sobrien * notice, this list of conditions and the following disclaimer. 10130561Sobrien * 2. Redistributions in binary form must reproduce the above copyright 11130561Sobrien * notice, this list of conditions and the following disclaimer in the 1285815Sobrien * documentation and/or other materials provided with the distribution. 13130561Sobrien * 14130561Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15130561Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16130561Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1785815Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18130561Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19130561Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20218822Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2185815Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22218822Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2385815Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2499461Sobrien * SUCH DAMAGE. 2585815Sobrien */ 2685815Sobrien 2785815Sobrien#include <sys/cdefs.h> 2885815Sobrien__FBSDID("$FreeBSD: stable/10/usr.bin/mkimg/pc98.c 272030 2014-09-23 16:05:23Z marcel $"); 2985815Sobrien 3085815Sobrien#include <sys/types.h> 3185815Sobrien#include <sys/diskpc98.h> 3285815Sobrien#include <sys/endian.h> 3385815Sobrien#include <sys/errno.h> 34218822Sdim#include <stdlib.h> 35218822Sdim#include <string.h> 3685815Sobrien#include <unistd.h> 3785815Sobrien 38130561Sobrien#include "image.h" 39130561Sobrien#include "mkimg.h" 40130561Sobrien#include "scheme.h" 41130561Sobrien 42130561Sobrien#ifndef PC98_MAGIC 43130561Sobrien#define PC98_MAGIC 0xaa55 44130561Sobrien#endif 45130561Sobrien#ifndef PC98_MAGICOFS 46130561Sobrien#define PC98_MAGICOFS 510 47130561Sobrien#endif 48130561Sobrien#ifndef PC98_NPARTS 49130561Sobrien#define PC98_NPARTS 16 50130561Sobrien#endif 51130561Sobrien#ifndef PC98_PTYP_386BSD 52130561Sobrien#define PC98_PTYP_386BSD 0xc494 53130561Sobrien#endif 54130561Sobrien 55130561Sobrien#define PC98_BOOTCODESZ 8192 56130561Sobrien 57130561Sobrienstatic struct mkimg_alias pc98_aliases[] = { 58130561Sobrien { ALIAS_FREEBSD, ALIAS_INT2TYPE(PC98_PTYP_386BSD) }, 59130561Sobrien { ALIAS_NONE, 0 } 60130561Sobrien}; 61130561Sobrien 62130561Sobrienstatic lba_t 63130561Sobrienpc98_metadata(u_int where, lba_t blk) 64130561Sobrien{ 65130561Sobrien if (where == SCHEME_META_IMG_START) 66130561Sobrien blk += PC98_BOOTCODESZ / secsz; 67130561Sobrien return (round_track(blk)); 68130561Sobrien} 69130561Sobrien 70130561Sobrienstatic void 71130561Sobrienpc98_chs(u_short *cyl, u_char *hd, u_char *sec, uint32_t lba __unused) 72130561Sobrien{ 73130561Sobrien 74130561Sobrien *cyl = 0xffff; /* XXX */ 75130561Sobrien *hd = 0xff; /* XXX */ 76130561Sobrien *sec = 0xff; /* XXX */ 77130561Sobrien} 78218822Sdim 79130561Sobrienstatic int 80130561Sobrienpc98_write(lba_t imgsz __unused, void *bootcode) 81130561Sobrien{ 82130561Sobrien struct part *part; 83130561Sobrien struct pc98_partition *dpbase, *dp; 84130561Sobrien u_char *buf; 85130561Sobrien int error, ptyp; 86130561Sobrien 87130561Sobrien buf = malloc(PC98_BOOTCODESZ); 88130561Sobrien if (buf == NULL) 89130561Sobrien return (ENOMEM); 90130561Sobrien if (bootcode != NULL) { 91130561Sobrien memcpy(buf, bootcode, PC98_BOOTCODESZ); 92130561Sobrien memset(buf + secsz, 0, secsz); 93130561Sobrien } else 94130561Sobrien memset(buf, 0, PC98_BOOTCODESZ); 95130561Sobrien le16enc(buf + PC98_MAGICOFS, PC98_MAGIC); 96130561Sobrien dpbase = (void *)(buf + secsz); 97218822Sdim STAILQ_FOREACH(part, &partlist, link) { 98130561Sobrien dp = dpbase + part->index; 99130561Sobrien ptyp = ALIAS_TYPE2INT(part->type); 100130561Sobrien dp->dp_mid = ptyp; 101130561Sobrien dp->dp_sid = ptyp >> 8; 102130561Sobrien pc98_chs(&dp->dp_scyl, &dp->dp_shd, &dp->dp_ssect, 103130561Sobrien part->block); 104130561Sobrien pc98_chs(&dp->dp_scyl, &dp->dp_shd, &dp->dp_ssect, 105130561Sobrien part->block + part->size - 1); 106218822Sdim if (part->label != NULL) 107218822Sdim memcpy(dp->dp_name, part->label, strlen(part->label)); 108218822Sdim } 109218822Sdim error = image_write(0, buf, PC98_BOOTCODESZ / secsz); 110218822Sdim free(buf); 111218822Sdim return (error); 112218822Sdim} 113218822Sdim 114218822Sdimstatic struct mkimg_scheme pc98_scheme = { 115218822Sdim .name = "pc98", 116218822Sdim .description = "PC-9800 disk partitions", 117218822Sdim .aliases = pc98_aliases, 118218822Sdim .metadata = pc98_metadata, 119218822Sdim .write = pc98_write, 120218822Sdim .bootcode = PC98_BOOTCODESZ, 121218822Sdim .labellen = 16, 122218822Sdim .nparts = PC98_NPARTS, 123218822Sdim .maxsecsz = 512 124218822Sdim}; 125218822Sdim 126218822SdimSCHEME_DEFINE(pc98_scheme); 127218822Sdim