From 5fd83771641d15c418f747bd343ba6738d3875f7 Mon Sep 17 00:00:00 2001 From: Cameron Katri Date: Sun, 9 May 2021 14:20:58 -0400 Subject: Import macOS userland adv_cmds-176 basic_cmds-55 bootstrap_cmds-116.100.1 developer_cmds-66 diskdev_cmds-667.40.1 doc_cmds-53.60.1 file_cmds-321.40.3 mail_cmds-35 misc_cmds-34 network_cmds-606.40.1 patch_cmds-17 remote_cmds-63 shell_cmds-216.60.1 system_cmds-880.60.2 text_cmds-106 --- diskdev_cmds/disklib/dkdisklabel.c | 193 +++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 diskdev_cmds/disklib/dkdisklabel.c (limited to 'diskdev_cmds/disklib/dkdisklabel.c') diff --git a/diskdev_cmds/disklib/dkdisklabel.c b/diskdev_cmds/disklib/dkdisklabel.c new file mode 100644 index 0000000..3fffce5 --- /dev/null +++ b/diskdev_cmds/disklib/dkdisklabel.c @@ -0,0 +1,193 @@ +/* Copyright 1999 Apple Computer, Inc. + * + * Generate a bsd disk label routine. + * Input: open file descriptor to the device node, and + * pointer to a disk label structure to fill in + * Return: errno status + * + * HISTORY + * + * 24 Feb 1999 D. Markarian at Apple + * Created. + */ + +#include /* memset */ +#include /* sys/disklabel.h */ +#include /* NBPG */ + +#include /* DKIOCGETBLOCKSIZE ioctl */ + +#include /* struct disklabel */ + +u_short dkcksum __P((register struct disklabel *lp)); +int dkdisklabelregenerate __P((int fd, struct disklabel * lp, int newblksize)); + +/* + * The following two constants set the default block and fragment sizes. + * Both constants must be a power of 2 and meet the following constraints: + * MINBSIZE <= GENBLKSIZE <= MAXBSIZE + * sectorsize <= GENFRAGSIZE <= GENBLKSIZE + * GENBLKSIZE / GENFRAGSIZE <= 8 + */ +#define GENFRAGSIZE 1024 +#define GENBLKSIZE NBPG /* 4096 */ + +/* + * Cylinder groups may have up to many cylinders. The actual + * number used depends upon how much information can be stored + * on a single cylinder. The default is to use 16 cylinders + * per group. + */ +#define GENCPG 16 + +/* + * Interleave is physical sector interleave, set up by the + * formatter or controller when formatting. When interleaving is + * in use, logically adjacent sectors are not physically + * contiguous, but instead are separated by some number of + * sectors. It is specified as the ratio of physical sectors + * traversed per logical sector. Thus an interleave of 1:1 + * implies contiguous layout, while 2:1 implies that logical + * sector 0 is separated by one sector from logical sector 1. + */ +#define GENINTERLEAVE 1 + +/* + * Rotational speed; # of data sectors per track. + */ +#define GENRPM 3600 +#define GENNSECTORS 32 + +int dkdisklabel(int fd, struct disklabel * lp) +{ + return dkdisklabelregenerate(fd, lp, 0); +} + +int dkdisklabelregenerate(int fd, struct disklabel * lp, int newblksize) +{ + /* + * Generate a bsd-style disk label for the specified device node. + */ + + int blksize; + int error; + int index; + int64_t numblks; + + /* obtain the size of the media (in blocks) */ + if ( (error = ioctl(fd, DKIOCGETBLOCKCOUNT, &numblks)) < 0 ) + return(error); + + /* obtain the block size of the media */ + if ( (error = ioctl(fd, DKIOCGETBLOCKSIZE, &blksize)) < 0 ) + return(error); + + /* adjust the size of the media with newblksize should it be specified */ + if (newblksize) + { + numblks = ((numblks * blksize) / newblksize); + blksize = newblksize; + } + + /* + * clear the disk label structure and then fill in the appropriate fields; + * we comment out lines that are initializations to zero with //, since it + * is redundant work + */ + memset(lp, 0, sizeof(struct disklabel)); + + lp->d_magic = DISKMAGIC; /* the magic number */ +// lp->d_type = 0; /* drive type */ +// lp->d_subtype = 0; /* controller/d_type specific */ +// lp->d_typename[0] = 0; /* type name, e.g. "eagle" */ + /* + * d_packname contains the pack identifier and is returned when + * the disklabel is read off the disk or in-core copy. + * d_boot0 and d_boot1 are the (optional) names of the + * primary (block 0) and secondary (block 1-15) bootstraps + * as found in /usr/mdec. These are returned when using + * getdiskbyname(3) to retrieve the values from /etc/disktab. + */ +// lp->d_packname[0] = 0; /* pack identifier */ + + /* disk geometry: */ + lp->d_secsize = blksize; /* # of bytes per sector */ + lp->d_nsectors = GENNSECTORS; /* # of data sectors per track */ + /* # of tracks per cylinder */ + if (numblks < 8*32*1024) /* <=528.4 MB */ + lp->d_ntracks = 16; + else if (numblks < 16*32*1024) /* <=1.057 GB */ + lp->d_ntracks = 32; + else if (numblks < 32*32*1024) /* <=2.114 GB */ + lp->d_ntracks = 54; + else if (numblks < 64*32*1024) /* <=4.228 GB */ + lp->d_ntracks = 128; + else /* > 4.228 GB */ + lp->d_ntracks = 255; + /* # of data cylinders per unit */ + lp->d_ncylinders = numblks / lp->d_ntracks / lp->d_nsectors; + /* # of data sectors per cylinder */ + lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; + lp->d_secperunit = numblks; /* # of data sectors per unit */ + /* + * Spares (bad sector replacements) below are not counted in + * d_nsectors or d_secpercyl. Spare sectors are assumed to + * be physical sectors which occupy space at the end of each + * track and/or cylinder. + */ +// lp->d_sparespertrack = 0; /* # of spare sectors per track */ +// lp->d_sparespercyl = 0; /* # of data sectors per unit */ + /* + * Alternate cylinders include maintenance, replacement, configuration + * description areas, etc. + */ +// lp->d_acylinders = 0; /* # of alt. cylinders per unit */ + + /* hardware characteristics: */ + /* + * d_interleave, d_trackskew and d_cylskew describe perturbations + * in the media format used to compensate for a slow controller. + * Interleave is physical sector interleave, set up by the + * formatter or controller when formatting. When interleaving is + * in use, logically adjacent sectors are not physically + * contiguous, but instead are separated by some number of + * sectors. It is specified as the ratio of physical sectors + * traversed per logical sector. Thus an interleave of 1:1 + * implies contiguous layout, while 2:1 implies that logical + * sector 0 is separated by one sector from logical sector 1. + * d_trackskew is the offset of sector 0 on track N relative to + * sector 0 on track N-1 on the same cylinder. Finally, d_cylskew + * is the offset of sector 0 on cylinder N relative to sector 0 + * on cylinder N-1. + */ + lp->d_rpm = GENRPM; /* rotational speed */ + lp->d_interleave = GENINTERLEAVE; /* hardware sector interleave */ +// lp->d_trackskew = 0; /* sector 0 skew, per track */ +// lp->d_cylskew = 0; /* sector 0 skew, per cylinder */ +// lp->d_headswitch = 0; /* head switch time, usec */ +// lp->d_trkseek = 0; /* track-to-track seek, usec */ +// lp->d_flags = 0; /* generic flags */ +// lp->d_drivedata[0-4] = 0; /* drive-type specific information */ +// lp->d_spare[0-4] = 0; /* reserved for future use */ + lp->d_magic2 = DISKMAGIC; /* the magic number (again) */ +// lp->d_checksum = 0; /* xor of data incl. partitions */ + + /* filesystem and partition information: */ + lp->d_npartitions = MAXPARTITIONS; /* number of partitions */ + + for (index = 0; index < MAXPARTITIONS; index++) + { + struct partition * pp = &(lp->d_partitions[index]); + pp->p_size = numblks; /* number of sectors */ +// pp->p_offset = 0; /* starting sector */ + pp->p_fsize = MAX(GENFRAGSIZE, blksize); /* fs fragment size */ + pp->p_fstype = FS_BSDFFS; /* fs type */ + pp->p_frag = MIN(8, GENBLKSIZE / pp->p_fsize);/* fs fragments/block */ + pp->p_cpg = GENCPG; /* fs cylinders/group */ + } + + /* compute a checksum on the resulting structure */ + lp->d_checksum = dkcksum(lp); + + return 0; /* success */ +} -- cgit v1.2.3-56-ge451