summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2014-03-27 22:48:48 +0000
committermarcel <marcel@FreeBSD.org>2014-03-27 22:48:48 +0000
commit452aa44886fc63062f3cf8e2b515d35f3e36e5c9 (patch)
treed83e7ad78af3d4691fb29281e3459bdf1d29f0cb
parentbfd31b94a3266570f0104f7c67d77d5aa3485bd9 (diff)
downloadFreeBSD-src-452aa44886fc63062f3cf8e2b515d35f3e36e5c9.zip
FreeBSD-src-452aa44886fc63062f3cf8e2b515d35f3e36e5c9.tar.gz
Give vtoc8 a change to work: when setting the physical block size to 4K,
sectors/track to 8 and number or heads to 1, partitions that are block aligned are also cyclinder aligned. With that trick, fix the vtoc8: 1. Set physcyls, ncyls, altcyls, nheads and nsecs appropriately. 2. Truncate the image size to exactly ncyls * nheads * nsecs * secsz. 3. Properly write the cylinder number as the start of the partition. 4. Oh, and actually calculate the checksum of the label...
-rw-r--r--vtoc8.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/vtoc8.c b/vtoc8.c
index 00be107..f263026 100644
--- a/vtoc8.c
+++ b/vtoc8.c
@@ -62,7 +62,9 @@ vtoc8_write(int fd, lba_t imgsz, void *bootcode __unused)
{
struct vtoc8 vtoc8;
struct part *part;
+ u_char *p;
int error;
+ uint16_t ofs, sum;
memset(&vtoc8, 0, sizeof(vtoc8));
sprintf(vtoc8.ascii, "FreeBSD%lldM", (long long)(imgsz / 2048));
@@ -70,21 +72,31 @@ vtoc8_write(int fd, lba_t imgsz, void *bootcode __unused)
be16enc(&vtoc8.nparts, VTOC8_NPARTS);
be32enc(&vtoc8.sanity, VTOC_SANITY);
be16enc(&vtoc8.rpm, 3600);
- be16enc(&vtoc8.physcyls, 2); /* XXX */
- be16enc(&vtoc8.ncyls, 0); /* XXX */
- be16enc(&vtoc8.altcyls, 2);
- be16enc(&vtoc8.nheads, 1); /* XXX */
- be16enc(&vtoc8.nsecs, 1); /* XXX */
+ be16enc(&vtoc8.physcyls, ncyls);
+ be16enc(&vtoc8.ncyls, ncyls);
+ be16enc(&vtoc8.altcyls, 0);
+ be16enc(&vtoc8.nheads, nheads);
+ be16enc(&vtoc8.nsecs, nsecs);
be16enc(&vtoc8.magic, VTOC_MAGIC);
+ ftruncate(fd, ncyls * nheads * nsecs *secsz);
+
STAILQ_FOREACH(part, &partlist, link) {
be16enc(&vtoc8.part[part->index].tag,
ALIAS_TYPE2INT(part->type));
be32enc(&vtoc8.map[part->index].cyl,
- part->block); /* XXX */
+ part->block / (nsecs * nheads));
be32enc(&vtoc8.map[part->index].nblks,
part->size);
}
+
+ /* Calculate checksum. */
+ sum = 0;
+ p = (void *)&vtoc8;
+ for (ofs = 0; ofs < sizeof(vtoc8) - 2; ofs += 2)
+ sum ^= be16dec(p + ofs);
+ be16enc(&vtoc8.cksum, sum);
+
error = mkimg_seek(fd, 0);
if (error == 0) {
if (write(fd, &vtoc8, sizeof(vtoc8)) != sizeof(vtoc8))
OpenPOWER on IntegriCloud