1*6bf2f4b9Smiod /* $OpenBSD: part.c,v 1.25 2001/11/07 01:27:33 miod Exp $ */ 2a1705421Sweingart 3a1705421Sweingart /* 4a1705421Sweingart * Copyright (c) 1997 Tobias Weingartner 5a1705421Sweingart * All rights reserved. 6a1705421Sweingart * 7a1705421Sweingart * Redistribution and use in source and binary forms, with or without 8a1705421Sweingart * modification, are permitted provided that the following conditions 9a1705421Sweingart * are met: 10a1705421Sweingart * 1. Redistributions of source code must retain the above copyright 11a1705421Sweingart * notice, this list of conditions and the following disclaimer. 12a1705421Sweingart * 2. Redistributions in binary form must reproduce the above copyright 13a1705421Sweingart * notice, this list of conditions and the following disclaimer in the 14a1705421Sweingart * documentation and/or other materials provided with the distribution. 15a1705421Sweingart * 3. All advertising materials mentioning features or use of this software 16a1705421Sweingart * must display the following acknowledgement: 17a1705421Sweingart * This product includes software developed by Tobias Weingartner. 18a1705421Sweingart * 4. The name of the author may not be used to endorse or promote products 19a1705421Sweingart * derived from this software without specific prior written permission. 20a1705421Sweingart * 21a1705421Sweingart * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22a1705421Sweingart * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23a1705421Sweingart * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24a1705421Sweingart * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25a1705421Sweingart * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26a1705421Sweingart * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27a1705421Sweingart * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28a1705421Sweingart * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29a1705421Sweingart * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30a1705421Sweingart * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31a1705421Sweingart */ 32a1705421Sweingart 33a1705421Sweingart #include <err.h> 34a1705421Sweingart #include <util.h> 35a1705421Sweingart #include <stdio.h> 36184a329bSmillert #include <string.h> 37a1705421Sweingart #include <unistd.h> 38a1705421Sweingart #include <sys/fcntl.h> 39a1705421Sweingart #include <sys/types.h> 40a1705421Sweingart #include <sys/stat.h> 41a1705421Sweingart #include <sys/disklabel.h> 42a1705421Sweingart #include <machine/param.h> 43a1705421Sweingart #include "disk.h" 44a1705421Sweingart #include "misc.h" 45a1705421Sweingart #include "mbr.h" 46a1705421Sweingart 47a1705421Sweingart 486c2b1c19Smickey static const struct part_type { 49a1705421Sweingart int type; 506c2b1c19Smickey char sname[14]; 514b464610Sderaadt char *lname; 52a1705421Sweingart } part_types[] = { 534b464610Sderaadt { 0x00, "unused ", "unused"}, 544b464610Sderaadt { 0x01, "DOS FAT-12 ", "Primary DOS with 12 bit FAT"}, 554b464610Sderaadt { 0x02, "XENIX / ", "XENIX / filesystem"}, 564b464610Sderaadt { 0x03, "XENIX /usr ", "XENIX /usr filesystem"}, 574b464610Sderaadt { 0x04, "DOS FAT-16 ", "Primary DOS with 16 bit FAT"}, 584b464610Sderaadt { 0x05, "Extended DOS", "Extended DOS"}, 594b464610Sderaadt { 0x06, "DOS > 32MB ", "Primary 'big' DOS (> 32MB)"}, 60f3f2107eSderaadt { 0x07, "HPFS/QNX/AUX", "OS/2 HPFS, QNX-2 or Advanced UNIX"}, 614b464610Sderaadt { 0x08, "AIX fs ", "AIX filesystem"}, 624b464610Sderaadt { 0x09, "AIX/Coherent", "AIX boot partition or Coherent"}, 634b464610Sderaadt { 0x0A, "OS/2 Bootmgr", "OS/2 Boot Manager or OPUS"}, 644b464610Sderaadt { 0x0B, "Win95 FAT-32", "Primary Win95 w/ 32-bit FAT"}, 65c3e3230dSderaadt { 0x0C, "Win95 FAT32L", "Primary Win95 w/ 32-bit FAT LBA-mapped"}, 664b464610Sderaadt { 0x0E, "DOS FAT-16 ", "Primary DOS w/ 16-bit FAT, CHS-mapped"}, 67c3e3230dSderaadt { 0x0F, "Extended LBA", "Extended DOS LBA-mapped"}, 684b464610Sderaadt { 0x10, "OPUS ", "OPUS"}, 6992ee32bfSkjell { 0x11, "OS/2 hidden ", "OS/2 BM: hidden DOS 12-bit FAT"}, 704b464610Sderaadt { 0x12, "Compaq Diag.", "Compaq Diagnostics"}, 7192ee32bfSkjell { 0x14, "OS/2 hidden ", "OS/2 BM: hidden DOS 16-bit FAT <32M or Novell DOS 7.0 bug"}, 7292ee32bfSkjell { 0x16, "OS/2 hidden ", "OS/2 BM: hidden DOS 16-bit FAT >=32M"}, 7392ee32bfSkjell { 0x17, "OS/2 hidden ", "OS/2 BM: hidden IFS"}, 7492ee32bfSkjell { 0x18, "AST swap ", "AST Windows swapfile"}, 7592ee32bfSkjell { 0x19, "Willowtech ", "Willowtech Photon coS"}, 7692ee32bfSkjell { 0x20, "Willowsoft ", "Willowsoft OFS1"}, 7792ee32bfSkjell { 0x24, "NEC DOS ", "NEC DOS"}, 7892ee32bfSkjell { 0x38, "Theos ", "Theos"}, 79a34f1fa7Smarkus { 0x39, "Plan 9 ", "Plan 9"}, 8092ee32bfSkjell { 0x40, "VENIX 286 ", "VENIX 286 or LynxOS"}, 8192ee32bfSkjell { 0x41, "Lin/Minux DR", "Linux/MINIX (sharing disk with DRDOS) or Personal RISC boot"}, 8292ee32bfSkjell { 0x42, "LinuxSwap DR", "SFS or Linux swap (sharing disk with DRDOS)"}, 8392ee32bfSkjell { 0x43, "Linux DR ", "Linux native (sharing disk with DRDOS)"}, 8492ee32bfSkjell { 0x4D, "QNX 4.2 Pri ", "QNX 4.2 Primary"}, 8592ee32bfSkjell { 0x4E, "QNX 4.2 Sec ", "QNX 4.2 Secondary"}, 8692ee32bfSkjell { 0x4F, "QNX 4.2 Ter ", "QNX 4.2 Tertiary"}, 8792ee32bfSkjell { 0x50, "DM ", "DM (disk manager)"}, 8892ee32bfSkjell { 0x51, "DM ", "DM6 Aux1 (or Novell)"}, 894b464610Sderaadt { 0x52, "CP/M or SysV", "CP/M or Microport SysV/AT"}, 9092ee32bfSkjell { 0x53, "DM ", "DM6 Aux3"}, 914b464610Sderaadt { 0x54, "Ontrack ", "Ontrack"}, 9292ee32bfSkjell { 0x55, "EZ-Drive ", "EZ-Drive (disk manager)"}, 9392ee32bfSkjell { 0x56, "Golden Bow ", "Golden Bow (disk manager)"}, 9492ee32bfSkjell { 0x5C, "Priam ", "Priam Edisk (disk manager)"}, 9592ee32bfSkjell { 0x61, "SpeedStor ", "SpeedStor"}, 964b464610Sderaadt { 0x63, "ISC, HURD, *", "ISC, System V/386, GNU HURD or Mach"}, 974b464610Sderaadt { 0x64, "Netware 2.xx", "Novell Netware 2.xx"}, 984b464610Sderaadt { 0x65, "Netware 3.xx", "Novell Netware 3.xx"}, 9992ee32bfSkjell { 0x66, "Netware 386 ", "Novell 386 Netware"}, 10092ee32bfSkjell { 0x67, "Novell ", "Novell"}, 10192ee32bfSkjell { 0x68, "Novell ", "Novell"}, 10292ee32bfSkjell { 0x69, "Novell ", "Novell"}, 10392ee32bfSkjell { 0x70, "DiskSecure ", "DiskSecure Multi-Boot"}, 1044b464610Sderaadt { 0x75, "PCIX ", "PCIX"}, 1054b464610Sderaadt { 0x80, "Minix (old) ", "Minix 1.1 ... 1.4a"}, 1064b464610Sderaadt { 0x81, "Minix (new) ", "Minix 1.4b ... 1.5.10"}, 1074b464610Sderaadt { 0x82, "Linux swap ", "Linux swap"}, 1084b464610Sderaadt { 0x83, "Linux files*", "Linux filesystem"}, 1094b464610Sderaadt { 0x93, "Amoeba file*", "Amoeba filesystem"}, 1104b464610Sderaadt { 0x94, "Amoeba BBT ", "Amoeba bad block table"}, 11192ee32bfSkjell { 0x84, "OS/2 hidden ", "OS/2 hidden C: drive"}, 11292ee32bfSkjell { 0x85, "Linux ext. ", "Linux extended"}, 11392ee32bfSkjell { 0x86, "NT FAT VS ", "NT FAT volume set"}, 11492ee32bfSkjell { 0x87, "NTFS VS ", "NTFS volume set or HPFS mirrored"}, 11592ee32bfSkjell { 0x93, "Amoeba FS ", "Amoeba filesystem"}, 11692ee32bfSkjell { 0x94, "Amoeba BBT ", "Amoeba bad block table"}, 11792ee32bfSkjell { 0x99, "Mylex ", "Mylex EISA SCSI"}, 11892ee32bfSkjell { 0x9F, "BSDI ", "BSDI BSD/OS"}, 1193addffc7Sian { 0xA0, "NotebookSave", "Phoenix NoteBIOS save-to-disk"}, 12058fe3b3aSderaadt { 0xA5, "FreeBSD ", "FreeBSD"}, 1214b464610Sderaadt { 0xA6, "OpenBSD ", "OpenBSD"}, 1224b464610Sderaadt { 0xA7, "NEXTSTEP ", "NEXTSTEP"}, 123*6bf2f4b9Smiod { 0xA8, "MacOS X ", "MacOS X main partition"}, 12458fe3b3aSderaadt { 0xA9, "NetBSD ", "NetBSD"}, 125*6bf2f4b9Smiod { 0xAB, "MacOS X boot", "MacOS X boot partition"}, 1264b464610Sderaadt { 0xB7, "BSDI filesy*", "BSDI BSD/386 filesystem"}, 1274b464610Sderaadt { 0xB8, "BSDI swap ", "BSDI BSD/386 swap"}, 12892ee32bfSkjell { 0xC0, "CTOS ", "CTOS"}, 12992ee32bfSkjell { 0xC1, "DRDOSs FAT12", "DRDOS/sec (FAT-12)"}, 13092ee32bfSkjell { 0xC4, "DRDOSs < 32M", "DRDOS/sec (FAT-16, < 32M)"}, 13192ee32bfSkjell { 0xC6, "DRDOSs >=32M", "DRDOS/sec (FAT-16, >= 32M)"}, 13292ee32bfSkjell { 0xC7, "HPFS Disbled", "Syrinx (Cyrnix?) or HPFS disabled"}, 1334b464610Sderaadt { 0xDB, "CPM/C.DOS/C*", "Concurrent CPM or C.DOS or CTOS"}, 13492ee32bfSkjell { 0xE1, "SpeedStor ", "DOS access or SpeedStor 12-bit FAT extended partition"}, 13592ee32bfSkjell { 0xE3, "SpeedStor ", "DOS R/O or SpeedStor or Storage Dimensions"}, 13692ee32bfSkjell { 0xE4, "SpeedStor ", "SpeedStor 16-bit FAT extended partition < 1024 cyl."}, 137092b495fSderaadt { 0xEB, "BeOS/i386 ", "BeOS for Intel"}, 13892ee32bfSkjell { 0xF1, "SpeedStor ", "SpeedStor or Storage Dimensions"}, 1394b464610Sderaadt { 0xF2, "DOS 3.3+ Sec", "DOS 3.3+ Secondary"}, 14092ee32bfSkjell { 0xF4, "SpeedStor ", "SpeedStor >1024 cyl. or LANstep or IBM PS/2 IML"}, 14192ee32bfSkjell { 0xFF, "Xenix BBT ", "Xenix Bad Block Table"}, 142a1705421Sweingart }; 143a1705421Sweingart 1444b464610Sderaadt void 1454b464610Sderaadt PRT_printall() 1464b464610Sderaadt { 147d20bdfc6Skrw int i, idrows; 148d20bdfc6Skrw 149d20bdfc6Skrw idrows = ((sizeof(part_types)/sizeof(struct part_type))+3)/4; 1504b464610Sderaadt 151c2ad5584Sderaadt printf("Choose from the following Partition id values:\n"); 152d20bdfc6Skrw for (i = 0; i < idrows; i++) { 153d20bdfc6Skrw printf("%02X %s %02X %s %02X %s" 154d20bdfc6Skrw , part_types[i ].type, part_types[i ].sname 155d20bdfc6Skrw , part_types[i+idrows ].type, part_types[i+idrows ].sname 156d20bdfc6Skrw , part_types[i+idrows*2].type, part_types[i+idrows*2].sname 157d20bdfc6Skrw ); 158d20bdfc6Skrw if ((i+idrows*3) < (sizeof(part_types)/sizeof(struct part_type))) { 159d20bdfc6Skrw printf(" %02X %s\n" 160d20bdfc6Skrw , part_types[i+idrows*3].type, part_types[i+idrows*3].sname ); 1614b464610Sderaadt } 162d20bdfc6Skrw else 1634b464610Sderaadt printf( "\n" ); 1644b464610Sderaadt } 165d20bdfc6Skrw } 166a1705421Sweingart 1676c2b1c19Smickey const char * 168a1705421Sweingart PRT_ascii_id(id) 169a1705421Sweingart int id; 170a1705421Sweingart { 171a1705421Sweingart static char unknown[] = "<Unknown ID>"; 172a1705421Sweingart int i; 173a1705421Sweingart 174a1705421Sweingart for (i = 0; i < sizeof(part_types)/sizeof(struct part_type); i++) { 175a1705421Sweingart if (part_types[i].type == id) 1764b464610Sderaadt return (part_types[i].sname); 177a1705421Sweingart } 178a1705421Sweingart 179a1705421Sweingart return (unknown); 180a1705421Sweingart } 181a1705421Sweingart 182a1705421Sweingart void 1830d5049c6Smickey PRT_parse(disk, prt, offset, reloff, partn, pn) 1844ed7cd7eSrahnds disk_t *disk; 185a1705421Sweingart void *prt; 186ca2e86e1Sprovos off_t offset; 187ca2e86e1Sprovos off_t reloff; 188a1705421Sweingart prt_t *partn; 1890d5049c6Smickey int pn; 190a1705421Sweingart { 191a1705421Sweingart unsigned char *p = prt; 192ca2e86e1Sprovos off_t off; 193a1705421Sweingart 194a1705421Sweingart partn->flag = *p++; 195a1705421Sweingart partn->shead = *p++; 196ca2e86e1Sprovos 197a1705421Sweingart partn->ssect = (*p) & 0x3F; 198a1705421Sweingart partn->scyl = ((*p << 2) & 0xFF00) | (*(p+1)); 199a1705421Sweingart p += 2; 200a1705421Sweingart 201a1705421Sweingart partn->id = *p++; 202a1705421Sweingart partn->ehead = *p++; 203a1705421Sweingart partn->esect = (*p) & 0x3F; 204a1705421Sweingart partn->ecyl = ((*p << 2) & 0xFF00) | (*(p+1)); 205a1705421Sweingart p += 2; 206a1705421Sweingart 207c3e3230dSderaadt if ((partn->id == DOSPTYP_EXTEND) || (partn->id == DOSPTYP_EXTENDL)) 208c3e3230dSderaadt off = reloff; 209c3e3230dSderaadt else 210c3e3230dSderaadt off = offset; 211ca2e86e1Sprovos 212ca2e86e1Sprovos partn->bs = getlong(p) + off; 213a1705421Sweingart partn->ns = getlong(p+4); 2144ed7cd7eSrahnds 2150d5049c6Smickey PRT_fix_CHS(disk, partn, pn); 2164ed7cd7eSrahnds } 217a1705421Sweingart 2184ed7cd7eSrahnds int 2194ed7cd7eSrahnds PRT_check_chs(partn) 2204ed7cd7eSrahnds prt_t *partn; 2214ed7cd7eSrahnds { 2224ed7cd7eSrahnds if ( (partn->shead > 255) || 2234ed7cd7eSrahnds (partn->ssect >63) || 2244ed7cd7eSrahnds (partn->scyl > 1023) || 2254ed7cd7eSrahnds (partn->ehead >255) || 2264ed7cd7eSrahnds (partn->esect >63) || 2274ed7cd7eSrahnds (partn->ecyl > 1023) ) 2284ed7cd7eSrahnds { 2294ed7cd7eSrahnds return 0; 2304ed7cd7eSrahnds } 2314ed7cd7eSrahnds return 1; 2324ed7cd7eSrahnds } 233a1705421Sweingart void 234ca2e86e1Sprovos PRT_make(partn, offset, reloff, prt) 235a1705421Sweingart prt_t *partn; 236ca2e86e1Sprovos off_t offset; 237ca2e86e1Sprovos off_t reloff; 238a1705421Sweingart void *prt; 239a1705421Sweingart { 240a1705421Sweingart unsigned char *p = prt; 241c3e3230dSderaadt prt_t tmp; 242c3e3230dSderaadt off_t off; 243c3e3230dSderaadt 244c3e3230dSderaadt tmp.shead = partn->shead; 245c3e3230dSderaadt tmp.ssect = partn->ssect; 246eb4cb19dSkjell tmp.scyl = (partn->scyl > 1023)? 1023: partn->scyl; 247c3e3230dSderaadt tmp.ehead = partn->ehead; 248c3e3230dSderaadt tmp.esect = partn->ssect; 249eb4cb19dSkjell tmp.ecyl = (partn->ecyl > 1023)? 1023: partn->ecyl; 250c3e3230dSderaadt if (!PRT_check_chs(partn) && PRT_check_chs(&tmp)) { 251c3e3230dSderaadt partn->shead = tmp.shead; 252c3e3230dSderaadt partn->ssect = tmp.ssect; 253c3e3230dSderaadt partn->scyl = tmp.scyl; 254c3e3230dSderaadt partn->ehead = tmp.ehead; 255c3e3230dSderaadt partn->esect = tmp.esect; 256c3e3230dSderaadt partn->ecyl = tmp.ecyl; 257c3e3230dSderaadt printf("Cylinder values are modified to fit in CHS.\n"); 258c3e3230dSderaadt } 259c3e3230dSderaadt if ((partn->id == DOSPTYP_EXTEND) || (partn->id == DOSPTYP_EXTENDL)) 260c3e3230dSderaadt off = reloff; 261c3e3230dSderaadt else 262c3e3230dSderaadt off = offset; 263a1705421Sweingart 2644ed7cd7eSrahnds if (PRT_check_chs(partn)) { 265a1705421Sweingart *p++ = partn->flag & 0xFF; 2664ed7cd7eSrahnds 267a1705421Sweingart *p++ = partn->shead & 0xFF; 268a1705421Sweingart *p++ = (partn->ssect & 0x3F) | ((partn->scyl & 0x300) >> 2); 269a1705421Sweingart *p++ = partn->scyl & 0xFF; 270a1705421Sweingart 271a1705421Sweingart *p++ = partn->id & 0xFF; 272a1705421Sweingart 273a1705421Sweingart *p++ = partn->ehead & 0xFF; 274a1705421Sweingart *p++ = (partn->esect & 0x3F) | ((partn->ecyl & 0x300) >> 2); 275a1705421Sweingart *p++ = partn->ecyl & 0xFF; 2764ed7cd7eSrahnds } else { 2774ed7cd7eSrahnds /* should this really keep flag, id and set others to 0xff? */ 2784ed7cd7eSrahnds *p++ = partn->flag & 0xFF; 2794ed7cd7eSrahnds *p++ = 0xFF; 2804ed7cd7eSrahnds *p++ = 0xFF; 2814ed7cd7eSrahnds *p++ = 0xFF; 2824ed7cd7eSrahnds *p++ = partn->id & 0xFF; 2834ed7cd7eSrahnds *p++ = 0xFF; 2844ed7cd7eSrahnds *p++ = 0xFF; 2854ed7cd7eSrahnds *p++ = 0xFF; 2864ed7cd7eSrahnds printf("Warning CHS values out of bounds only saving LBA values\n"); 2874ed7cd7eSrahnds } 288a1705421Sweingart 289ca2e86e1Sprovos putlong(p, partn->bs - off); 290a1705421Sweingart putlong(p+4, partn->ns); 291a1705421Sweingart } 292a1705421Sweingart 293a1705421Sweingart void 294a1705421Sweingart PRT_print(num, partn) 295a1705421Sweingart int num; 296a1705421Sweingart prt_t *partn; 297a1705421Sweingart { 298a1705421Sweingart 299a1705421Sweingart if (partn == NULL) { 300a1705421Sweingart printf(" Starting Ending\n"); 301a1705421Sweingart printf(" #: id cyl hd sec - cyl hd sec [ start - size]\n"); 3026c2b1c19Smickey printf("------------------------------------------------------------------------\n"); 303a1705421Sweingart } else { 3046c2b1c19Smickey printf("%c%1d: %.2X %4d %3d %3d - %4d %3d %3d [%10d - %10d] %s\n", 305a1705421Sweingart (partn->flag == 0x80)?'*':' ', 306a1705421Sweingart num, partn->id, 307a1705421Sweingart partn->scyl, partn->shead, partn->ssect, 308a1705421Sweingart partn->ecyl, partn->ehead, partn->esect, 309a1705421Sweingart partn->bs, partn->ns, 310a1705421Sweingart PRT_ascii_id(partn->id)); 311a1705421Sweingart } 312a1705421Sweingart } 313a1705421Sweingart 314a1705421Sweingart void 3150d5049c6Smickey PRT_fix_BN(disk, part, pn) 316a1705421Sweingart disk_t *disk; 317a1705421Sweingart prt_t *part; 3180d5049c6Smickey int pn; 319a1705421Sweingart { 320a1705421Sweingart int spt, tpc, spc; 321a1705421Sweingart int start = 0; 322a1705421Sweingart int end = 0; 323a1705421Sweingart 324eb4cb19dSkjell /* Zero out entry if not used */ 325eb4cb19dSkjell if (part->id == DOSPTYP_UNUSED ) { 326eb4cb19dSkjell memset(part, 0, sizeof(*part)); 327eb4cb19dSkjell return; 328eb4cb19dSkjell } 329eb4cb19dSkjell 330a1705421Sweingart /* Disk metrics */ 3314b464610Sderaadt spt = disk->real->sectors; 3324b464610Sderaadt tpc = disk->real->heads; 333a1705421Sweingart spc = spt * tpc; 334a1705421Sweingart 335a1705421Sweingart start += part->scyl * spc; 336a1705421Sweingart start += part->shead * spt; 337a1705421Sweingart start += part->ssect - 1; 338a1705421Sweingart 339a1705421Sweingart end += part->ecyl * spc; 340a1705421Sweingart end += part->ehead * spt; 341a1705421Sweingart end += part->esect - 1; 342a1705421Sweingart 343a1705421Sweingart /* XXX - Should handle this... */ 344a1705421Sweingart if (start > end) 3450d5049c6Smickey warn("Start of partition #%d after end!", pn); 346a1705421Sweingart 347a1705421Sweingart part->bs = start; 348a1705421Sweingart part->ns = (end - start) + 1; 349a1705421Sweingart } 350a1705421Sweingart 351a1705421Sweingart void 3520d5049c6Smickey PRT_fix_CHS(disk, part, pn) 353a1705421Sweingart disk_t *disk; 354a1705421Sweingart prt_t *part; 3550d5049c6Smickey int pn; 356a1705421Sweingart { 357a1705421Sweingart int spt, tpc, spc; 358a1705421Sweingart int start, end, size; 359a1705421Sweingart int cyl, head, sect; 360a1705421Sweingart 361eb4cb19dSkjell /* Zero out entry if not used */ 362eb4cb19dSkjell if (part->id == DOSPTYP_UNUSED ) { 363eb4cb19dSkjell memset(part, 0, sizeof(*part)); 364eb4cb19dSkjell return; 365eb4cb19dSkjell } 366eb4cb19dSkjell 367a1705421Sweingart /* Disk metrics */ 3684b464610Sderaadt spt = disk->real->sectors; 3694b464610Sderaadt tpc = disk->real->heads; 370a1705421Sweingart spc = spt * tpc; 371a1705421Sweingart 372a1705421Sweingart start = part->bs; 373a1705421Sweingart size = part->ns; 374a1705421Sweingart end = (start + size) - 1; 375a1705421Sweingart 376a1705421Sweingart /* Figure out starting CHS values */ 377a1705421Sweingart cyl = (start / spc); start -= (cyl * spc); 378a1705421Sweingart head = (start / spt); start -= (head * spt); 379a1705421Sweingart sect = (start + 1); 380a1705421Sweingart 381c3e3230dSderaadt if (cyl > 1023) { 382c3e3230dSderaadt cyl = 1023; 3830d5049c6Smickey printf("Only LBA values are valid in starting cylinder for partition #%d.\n", pn); 384c3e3230dSderaadt } 385a1705421Sweingart part->scyl = cyl; 386a1705421Sweingart part->shead = head; 387a1705421Sweingart part->ssect = sect; 388a1705421Sweingart 389a1705421Sweingart /* Figure out ending CHS values */ 390a1705421Sweingart cyl = (end / spc); end -= (cyl * spc); 391a1705421Sweingart head = (end / spt); end -= (head * spt); 392a1705421Sweingart sect = (end + 1); 393a1705421Sweingart 394c3e3230dSderaadt if (cyl > 1023) { 395c3e3230dSderaadt cyl = 1023; 3960d5049c6Smickey printf("Only LBA values are valid in ending cylinder for partition #%d.\n", pn); 397c3e3230dSderaadt } 398a1705421Sweingart part->ecyl = cyl; 399a1705421Sweingart part->ehead = head; 400a1705421Sweingart part->esect = sect; 401a1705421Sweingart } 402a1705421Sweingart 403