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: stable/11/usr.bin/mkimg/vtoc8.c 329059 2018-02-09 09:15:43Z manu $");
29263409Smarcel
30263442Smarcel#include <sys/errno.h>
31329059Smanu#include <stdint.h>
32263699Smarcel#include <stdio.h>
33263409Smarcel#include <stdlib.h>
34263699Smarcel#include <string.h>
35263699Smarcel#include <unistd.h>
36263409Smarcel
37329059Smanu#include <sys/vtoc.h>
38329059Smanu
39329059Smanu#include "endian.h"
40266176Smarcel#include "image.h"
41263409Smarcel#include "mkimg.h"
42263409Smarcel#include "scheme.h"
43263409Smarcel
44328976Smanu#ifndef VTOC_TAG_FREEBSD_NANDFS
45328976Smanu#define	VTOC_TAG_FREEBSD_NANDFS	0x0905
46328976Smanu#endif
47328976Smanu
48263409Smarcelstatic struct mkimg_alias vtoc8_aliases[] = {
49263699Smarcel    {	ALIAS_FREEBSD_NANDFS, ALIAS_INT2TYPE(VTOC_TAG_FREEBSD_NANDFS) },
50263699Smarcel    {	ALIAS_FREEBSD_SWAP, ALIAS_INT2TYPE(VTOC_TAG_FREEBSD_SWAP) },
51263699Smarcel    {	ALIAS_FREEBSD_UFS, ALIAS_INT2TYPE(VTOC_TAG_FREEBSD_UFS) },
52263699Smarcel    {	ALIAS_FREEBSD_VINUM, ALIAS_INT2TYPE(VTOC_TAG_FREEBSD_VINUM) },
53263699Smarcel    {	ALIAS_FREEBSD_ZFS, ALIAS_INT2TYPE(VTOC_TAG_FREEBSD_NANDFS) },
54263487Smarcel    {	ALIAS_NONE, 0 }
55263409Smarcel};
56263409Smarcel
57271881Smarcelstatic lba_t
58271881Smarcelvtoc8_metadata(u_int where, lba_t blk)
59263409Smarcel{
60263409Smarcel
61271881Smarcel	blk += (where == SCHEME_META_IMG_START) ? 1 : 0;
62271881Smarcel	return (round_cylinder(blk));
63263409Smarcel}
64263409Smarcel
65263442Smarcelstatic int
66266176Smarcelvtoc8_write(lba_t imgsz, void *bootcode __unused)
67263442Smarcel{
68263699Smarcel	struct vtoc8 vtoc8;
69263699Smarcel	struct part *part;
70263845Smarcel	u_char *p;
71263893Smarcel	int error, n;
72263845Smarcel	uint16_t ofs, sum;
73263699Smarcel
74266514Smarcel	imgsz = (lba_t)ncyls * nheads * nsecs;
75263893Smarcel
76263699Smarcel	memset(&vtoc8, 0, sizeof(vtoc8));
77263893Smarcel	sprintf(vtoc8.ascii, "FreeBSD%lldM",
78263893Smarcel	    (long long)(imgsz * secsz / 1048576));
79263699Smarcel	be32enc(&vtoc8.version, VTOC_VERSION);
80263699Smarcel	be16enc(&vtoc8.nparts, VTOC8_NPARTS);
81263699Smarcel	be32enc(&vtoc8.sanity, VTOC_SANITY);
82263699Smarcel	be16enc(&vtoc8.rpm, 3600);
83263845Smarcel	be16enc(&vtoc8.physcyls, ncyls);
84263845Smarcel	be16enc(&vtoc8.ncyls, ncyls);
85263845Smarcel	be16enc(&vtoc8.altcyls, 0);
86263845Smarcel	be16enc(&vtoc8.nheads, nheads);
87263845Smarcel	be16enc(&vtoc8.nsecs, nsecs);
88263699Smarcel	be16enc(&vtoc8.magic, VTOC_MAGIC);
89263699Smarcel
90263893Smarcel	be32enc(&vtoc8.map[VTOC_RAW_PART].nblks, imgsz);
91329059Smanu	TAILQ_FOREACH(part, &partlist, link) {
92263893Smarcel		n = part->index + ((part->index >= VTOC_RAW_PART) ? 1 : 0);
93263893Smarcel		be16enc(&vtoc8.part[n].tag, ALIAS_TYPE2INT(part->type));
94263893Smarcel		be32enc(&vtoc8.map[n].cyl, part->block / (nsecs * nheads));
95263893Smarcel		be32enc(&vtoc8.map[n].nblks, part->size);
96263699Smarcel	}
97263845Smarcel
98263845Smarcel	/* Calculate checksum. */
99263845Smarcel	sum = 0;
100263845Smarcel	p = (void *)&vtoc8;
101263845Smarcel	for (ofs = 0; ofs < sizeof(vtoc8) - 2; ofs += 2)
102263845Smarcel		sum ^= be16dec(p + ofs);
103263845Smarcel	be16enc(&vtoc8.cksum, sum);
104263845Smarcel
105266176Smarcel	error = image_write(0, &vtoc8, 1);
106263699Smarcel	return (error);
107263442Smarcel}
108263442Smarcel
109263409Smarcelstatic struct mkimg_scheme vtoc8_scheme = {
110263409Smarcel	.name = "vtoc8",
111263409Smarcel	.description = "SMI VTOC8 disk labels",
112263409Smarcel	.aliases = vtoc8_aliases,
113263440Smarcel	.metadata = vtoc8_metadata,
114263442Smarcel	.write = vtoc8_write,
115263893Smarcel	.nparts = VTOC8_NPARTS - 1,
116263700Smarcel	.maxsecsz = 512
117263409Smarcel};
118263409Smarcel
119263409SmarcelSCHEME_DEFINE(vtoc8_scheme);
120