1 /* $NetBSD: md.c,v 1.55 2009/09/19 14:57:29 abs Exp $ */
4 * Copyright 1997 Piermont Information Systems Inc.
7 * Based on code written by Philip A. Nelson for Piermont Information
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed for the NetBSD Project by
21 * Piermont Information Systems Inc.
22 * 4. The name of Piermont Information Systems Inc. may not be used to endorse
23 * or promote products derived from this software without specific prior
26 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36 * THE POSSIBILITY OF SUCH DAMAGE.
39 /* md.c -- mac68k machine specific routines */
45 #include <sys/ioctl.h>
46 #include <sys/utsname.h>
47 #include <machine/int_fmtio.h>
52 #include "menu_defs.h"
54 static int stricmp(const char *c1
, const char *c2
);
55 static void setpartition(struct apple_part_map_entry
*, char *, int);
56 static int getFreeLabelEntry(char *);
57 static char *getFstype(struct apple_part_map_entry
*, int, char *);
58 static char *getUse(struct apple_part_map_entry
*, int, char *);
59 static char *getName(struct apple_part_map_entry
*, int, char *);
60 static int findStdType(int, char *, int, int *, int);
61 static int check_for_errors(void);
62 static int edit_diskmap(void);
63 #ifdef MD_DEBUG_SORT_MERGE
64 static int md_debug_dump(char *);
69 MAP_TYPE map_types
[] = {
70 {MAP_RESERVED
, APPLE_PART_TYPE_DRIVER
},
71 {MAP_RESERVED
, APPLE_PART_TYPE_DRIVER43
},
72 {MAP_RESERVED
, APPLE_PART_TYPE_DRIVERATA
},
73 {MAP_RESERVED
, APPLE_PART_TYPE_FWB_COMPONENT
},
74 {MAP_MACOS
, APPLE_PART_TYPE_MAC
},
75 {MAP_NETBSD
, APPLE_PART_TYPE_NETBSD
},
76 {MAP_RESERVED
, APPLE_PART_TYPE_PARTMAP
},
77 {MAP_OTHER
, APPLE_PART_TYPE_SCRATCH
},
78 {MAP_NETBSD
, APPLE_PART_TYPE_UNIX
},
82 MAP map
= {0, 0, 0, 0, 0, 0, 0, 0, {0}, NULL
};
84 struct apple_part_map_entry new_map
[] =
86 { APPLE_PART_MAP_ENTRY_MAGIC
, 0xa5a5, 6, 1, NEW_MAP_SIZE
& 0x7e,
87 "Apple", "Apple_Partition_Map", 0, NEW_MAP_SIZE
, 0x37,
88 0, 0, 0, 0, 0, 0, 0, {0}, {0}, {0}},
89 { APPLE_PART_MAP_ENTRY_MAGIC
, 0, 6, 64, 32,
90 "Macintosh", "Apple_Driver", 0, 0, 0x37,
91 0, 0, 0, 0, 0, 0, 0, {0}, {0}, {0}},
92 { APPLE_PART_MAP_ENTRY_MAGIC
, 0, 6, 96, 64,
93 "Macintosh", "Apple_Driver43", 0, 0, 0x37,
94 0, 0, 0, 0, 0, 0, 0, {0}, {0}, {0}},
95 { APPLE_PART_MAP_ENTRY_MAGIC
, 0, 6, 160, 64,
96 "Macintosh", "Apple_Driver_ATA", 0, 0, 0x37,
97 0, 0, 0, 0, 0, 0, 0, {0}, {0}, {0}},
98 { APPLE_PART_MAP_ENTRY_MAGIC
, 0, 6, 224, 4096,
99 "untitled", "Apple_HFS", 0, 0, 0x37,
100 0, 0, 0, 0, 0, 0, 0, {0}, {0}, {0}},
101 { APPLE_PART_MAP_ENTRY_MAGIC
, 0, 6,4320, 0,
102 "untitled", "Apple_Free", 0, 0, 0x37,
103 0, 0, 0, 0, 0, 0, 0, {0}, {0}, {0}}
112 md_init_set_status(int minimal
)
114 struct utsname instsys
;
119 * Get the name of the Install Kernel we are running under and
120 * enable the installation of the corresponding GENERIC kernel.
122 * Note: In md.h the two kernels are disabled. If they are
123 * enabled there the logic here needs to be switched.
126 if (strstr(instsys
.version
, "(INSTALLSBC)"))
128 * Running the SBC Installation Kernel, so enable GENERICSBC
130 set_kernel_set(SET_KERNEL_2
);
133 * Running the GENERIC Installation Kernel, so enable GENERIC
135 set_kernel_set(SET_KERNEL_1
);
141 struct disklabel disklabel
;
144 struct apple_part_map_entry block
;
146 snprintf(dev_name
, sizeof(dev_name
), "/dev/r%s%c",
147 diskdev
, 'a' + getrawpartition());
150 * Open the disk as a raw device
152 fd
= open(dev_name
, O_RDONLY
, 0);
155 fprintf (stderr
, "Can't open %s\n", dev_name
);
159 * Try to get the default disklabel info for the device
161 if (ioctl(fd
, DIOCGDINFO
, &disklabel
) == -1) {
163 fprintf (stderr
, "Can't read disklabel on %s\n", dev_name
);
168 * Get the disk parameters from the disk driver. It should have
169 * obained them by querying the disk itself.
171 blk_size
= disklabel
.d_secsize
;
172 dlcyl
= disklabel
.d_ncylinders
;
173 dlhead
= disklabel
.d_ntracks
;
174 dlsec
= disklabel
.d_nsectors
;
176 * Just in case, initialize the structures we'll need if we
177 * need to completely initialize the disk.
179 dlsize
= disklabel
.d_secperunit
;
180 for (i
=0;i
<NEW_MAP_SIZE
;i
++) {
182 new_map
[i
].pmPyPartStart
= new_map
[i
-1].pmPyPartStart
+
183 new_map
[i
-1].pmPartBlkCnt
;
184 new_map
[i
].pmDataCnt
= new_map
[i
].pmPartBlkCnt
;
185 if (new_map
[i
].pmPartBlkCnt
== 0) {
186 new_map
[i
].pmPartBlkCnt
= dlsize
;
187 new_map
[i
].pmDataCnt
= dlsize
;
190 dlsize
-= new_map
[i
].pmPartBlkCnt
;
192 dlsize
= disklabel
.d_secperunit
;
194 msg_display(MSG_dldebug
, blk_size
, dlcyl
, dlhead
, dlsec
, dlsize
);
195 process_menu(MENU_ok
, NULL
);
199 * Verify the disk has been initialized for MacOS use by checking
200 * to see if the disk have a Boot Block
202 if (lseek(fd
, (off_t
)0 * blk_size
, SEEK_SET
) < 0 ||
203 read(fd
, &block
, sizeof(block
)) - sizeof(block
) != 0 ||
204 block
.pmSig
!= 0x4552) {
205 process_menu(MENU_nodiskmap
, NULL
);
209 * Scan for the Partition Map entry that describes the Partition
210 * Map itself. We need to know the number of blocks allocated
211 * to it and the number currently in use.
213 for (i
=0;i
<MAXMAXPARTITIONS
;i
++) {
214 lseek(fd
, (off_t
)(i
+1) * blk_size
, SEEK_SET
);
215 read(fd
, &block
, sizeof(block
));
216 if (stricmp("Apple_partition_map", (char *)block
.pmPartType
) == 0) {
217 map
.size
= block
.pmPartBlkCnt
;
218 map
.in_use_cnt
= block
.pmMapBlkCnt
;
219 map
.blk
= (struct apple_part_map_entry
*)malloc(map
.size
* blk_size
);
223 lseek(fd
, (off_t
)1 * blk_size
, SEEK_SET
);
224 read(fd
, map
.blk
, map
.size
* blk_size
);
228 * Setup the disktype so /etc/disktab gets proper info
230 if (strncmp(diskdev
, "sd", 2) == 0) {
236 return edit_diskmap();
240 * md back-end code for menu-driven BSD disklabel editor.
243 md_make_bsd_partitions(void)
250 * Scan for any problems and report them before continuing.
251 * The user can abort installation and we'll take them back
252 * to the main menu; continue ignoring the warnings, or
253 * ask to reedit the Disk Partition Map.
256 if (check_for_errors()) {
257 process_menu (MENU_sanity
, NULL
);
267 /* Build standard partitions */
268 memset(&bsdlabel
, 0, sizeof bsdlabel
);
271 * The mac68k port has a predefined partition for "c" which
272 * is the size of the disk, everything else is unused.
274 bsdlabel
[RAW_PART
].pi_size
= dlsize
;
276 * Now, scan through the Disk Partition Map and transfer the
277 * information into the incore disklabel.
279 for (i
=0;i
<map
.usable_cnt
;i
++) {
281 bzb
= (EBZB
*)&map
.blk
[j
].pmBootArgs
[0];
282 if (bzb
->flags
.part
) {
283 pl
= bzb
->flags
.part
- 'a';
284 switch (whichType(&map
.blk
[j
])) {
286 bsdlabel
[pl
].pi_fstype
= FS_HFS
;
287 strcpy (bsdlabel
[pl
].pi_mount
, (char *)bzb
->mount_point
);
291 bsdlabel
[pl
].pi_fstype
= FS_BSDFFS
;
292 strcpy (bsdlabel
[pl
].pi_mount
, (char *)bzb
->mount_point
);
293 bsdlabel
[pl
].pi_flags
|= PIF_NEWFS
| PIF_MOUNT
;
296 bsdlabel
[pl
].pi_fstype
= FS_SWAP
;
299 bsdlabel
[pl
].pi_fstype
= FS_OTHER
;
300 strcpy (bsdlabel
[pl
].pi_mount
, (char *)bzb
->mount_point
);
304 if (bsdlabel
[pl
].pi_fstype
!= FS_UNUSED
) {
305 bsdlabel
[pl
].pi_size
= map
.blk
[j
].pmPartBlkCnt
;
306 bsdlabel
[pl
].pi_offset
= map
.blk
[j
].pmPyPartStart
;
307 if (bsdlabel
[pl
].pi_fstype
!= FS_SWAP
) {
308 bsdlabel
[pl
].pi_frag
= 8;
309 bsdlabel
[pl
].pi_fsize
= 1024;
315 /* Disk name - don't bother asking, just use the physical name*/
316 strcpy (bsddiskname
, diskdev
);
319 f
= fopen ("/tmp/disktab", "w");
321 f
= fopen ("/etc/disktab", "w");
325 (void) fprintf (stderr
, "Could not open /etc/disktab");
328 (void)fprintf (f
, "%s|NetBSD installation generated:\\\n", bsddiskname
);
329 (void)fprintf (f
, "\t:dt=%s:ty=winchester:\\\n", disktype
);
330 (void)fprintf (f
, "\t:nc#%d:nt#%d:ns#%d:\\\n", dlcyl
, dlhead
, dlsec
);
331 (void)fprintf (f
, "\t:sc#%d:su#%" PRIu32
":\\\n", dlhead
*dlsec
, (uint32_t)dlsize
);
332 (void)fprintf (f
, "\t:se#%d:%s\\\n", blk_size
, doessf
);
333 for (i
=0; i
<8; i
++) {
334 if (bsdlabel
[i
].pi_fstype
== FS_HFS
)
335 (void)fprintf (f
, "\t:p%c#%d:o%c#%d:t%c=macos:",
336 'a'+i
, bsdlabel
[i
].pi_size
,
337 'a'+i
, bsdlabel
[i
].pi_offset
,
340 (void)fprintf (f
, "\t:p%c#%d:o%c#%d:t%c=%s:",
341 'a'+i
, bsdlabel
[i
].pi_size
,
342 'a'+i
, bsdlabel
[i
].pi_offset
,
343 'a'+i
, fstypenames
[bsdlabel
[i
].pi_fstype
]);
344 if (bsdlabel
[i
].pi_fstype
== FS_BSDFFS
)
345 (void)fprintf (f
, "b%c#%d:f%c#%d",
346 'a'+i
, bsdlabel
[i
].pi_fsize
* bsdlabel
[i
].pi_frag
,
347 'a'+i
, bsdlabel
[i
].pi_fsize
);
349 (void)fprintf (f
, "\\\n");
351 (void)fprintf (f
, "\n");
355 /* Everything looks OK. */
360 * any additional partition validation
363 md_check_partitions(void)
369 * hook called before writing new disklabel.
372 md_pre_disklabel(void)
377 Block0 new_block0
= {APPLE_DRVR_MAP_MAGIC
, 512,
378 0, 0, 0, 0, 0, 0, 0, 0, {0}};
381 * Danger Will Robinson! We're about to turn that nice MacOS disk
382 * into an expensive doorstop...
384 printf ("%s", msg_string (MSG_dodiskmap
));
386 snprintf (dev_name
, sizeof(dev_name
), "/dev/r%sc", diskdev
);
388 * Open the disk as a raw device
390 if ((fd
= open(dev_name
, O_WRONLY
, 0)) < 0) {
392 fprintf(stderr
, "Can't open %s to rewrite the Disk Map\n", dev_name
);
396 * First check the pmSigPad field of the first block in the incore
397 * Partition Map. It should be zero, but if it's 0xa5a5 that means
398 * we need to write out Block0 too.
400 if (map
.blk
[0].pmSigPad
== 0xa5a5) {
401 if (lseek (fd
, (off_t
)0 * blk_size
, SEEK_SET
) < 0) {
403 fprintf (stderr
, "Can't position to write Block0\n");
407 new_block0
.sbBlkCount
= dlsize
; /* Set disk size */
408 if (write (fd
, &new_block0
, blk_size
) != blk_size
) {
410 fprintf (stderr
, "I/O error writing Block0\n");
414 map
.blk
[0].pmSigPad
= 0;
416 if (lseek (fd
, (off_t
)1 * blk_size
, SEEK_SET
) < 0) {
418 fprintf (stderr
, "Can't position disk to rewrite Disk Map\n");
422 if (write (fd
, map
.blk
, map
.size
* blk_size
) != (map
.size
* blk_size
)) {
424 fprintf(stderr
, "I/O error writing Disk Map\n");
430 * Well, if we get here the dirty deed has been done.
432 * Now we need to force the incore disk table to get updated. This
433 * should be done by disklabel -- which is normally called right after
434 * we return -- but may be commented out for the mac68k port. We'll
435 * instead update the incore table by forcing a dummy write here. This
436 * relies on a change in the mac68k-specific writedisklabel() routine.
437 * If that change doesn't exist nothing bad happens here. If disklabel
438 * properly updates the ondisk and incore labels everything still
439 * works. Only if we fail here and if disklabel fails are we in
440 * in a state where we've updated the disk but not the incore and
441 * a reboot is necessary.
443 * First, we grab a copy of the incore label as it existed before
444 * we did anything to it. Then we invoke the "write label" ioctl to
445 * rewrite it to disk. As a result, the ondisk partition map is
446 * re-read and the incore label is reconstructed from it. If
447 * disklabel() is then called to update again, either that fails
448 * because the mac68k port doesn't support native disklabels, or it
449 * succeeds and writes out a new ondisk copy.
451 ioctl(fd
, DIOCGDINFO
, &lp
); /* Get the current disk label */
452 ioctl(fd
, DIOCWDINFO
, &lp
); /* Write it out again */
459 * hook called after writing disklabel to new target disk.
462 md_post_disklabel(void)
464 struct disklabel updated_label
;
466 char dev_name
[100], buf
[80];
467 const char *fst
[] = {"free", "swap", " v6 ", " v7 ", "sysv", "v71k",
468 " v8 ", "ffs ", "dos ", "lfs ", "othr", "hpfs",
469 "9660", "boot", "ados", "hfs ", "fcor", "ex2f",
470 "ntfs", "raid", "ccd "};
472 snprintf(dev_name
, sizeof(dev_name
), "/dev/r%sc", diskdev
);
474 * Open the disk as a raw device
476 if ((fd
= open(dev_name
, O_RDONLY
, 0)) < 0)
479 * Get the "new" label to see if we were successful. If we aren't
480 * we'll return an error to keep from destroying the user's disk.
482 ioctl(fd
, DIOCGDINFO
, &updated_label
);
485 * Make sure the in-core label matches the on-disk one
488 for (i
=0;i
<MAXPARTITIONS
;i
++) {
489 if (i
> updated_label
.d_npartitions
)
491 if (bsdlabel
[i
].pi_size
!= updated_label
.d_partitions
[i
].p_size
)
493 if (bsdlabel
[i
].pi_size
) {
494 if (bsdlabel
[i
].pi_offset
!= updated_label
.d_partitions
[i
].p_offset
)
496 if (bsdlabel
[i
].pi_fstype
!= updated_label
.d_partitions
[i
].p_fstype
)
503 * If the labels don't match, tell the user why
507 msg_display(MSG_label_error
);
508 msg_table_add(MSG_dump_line
,
509 " in-core: offset size type on-disk: offset size type");
510 for (i
=0;i
<MAXPARTITIONS
;i
++) {
511 sprintf(buf
, " %c:%13.8x%10.8x%5s%16.8x%10.8x%5s", i
+'a',
512 bsdlabel
[i
].pi_offset
, bsdlabel
[i
].pi_size
,
513 fst
[bsdlabel
[i
].pi_fstype
],
514 updated_label
.d_partitions
[i
].p_offset
,
515 updated_label
.d_partitions
[i
].p_size
,
516 fst
[updated_label
.d_partitions
[i
].p_fstype
]);
517 msg_table_add(MSG_dump_line
, buf
);
519 process_menu(MENU_ok2
, NULL
);
525 * hook called after upgrade() or install() has finished setting
526 * up the target disk but immediately before the user is given the
527 * ``disks are now set up'' message.
536 md_post_extract(void)
542 md_cleanup_install(void)
555 /* Upgrade support */
564 * Compare lexigraphically two strings
574 c1
= tolower((unsigned char)*s1
++);
575 c2
= tolower((unsigned char)*s2
++);
576 if (c1
< c2
) return -1;
577 if (c1
> c2
) return 1;
578 if (c1
== 0) return 0;
583 setpartition(part
, in_use
, slot
)
584 struct apple_part_map_entry
*part
;
590 bzb
= (EBZB
*)&part
->pmBootArgs
[0];
593 bzb
->flags
.part
= 'a' + slot
;
597 * Find an entry in a use array that is unused and return it or
598 * -1 if no entry is available
601 getFreeLabelEntry(slots
)
606 for ( i
= 0; i
< MAXPARTITIONS
; i
++) {
607 if (i
!= RAW_PART
&& slots
[i
] == 0)
614 * Figure out what type type of the given partition is and return it.
618 struct apple_part_map_entry
*part
;
620 MAP_TYPE
*map_entry
= (MAP_TYPE
*)&map_types
;
623 int type
, maxsiz
, entry_type
= MAP_OTHER
;
625 bzb
= (EBZB
*)&part
->pmBootArgs
[0];
626 if (part
->pmSig
!= APPLE_PART_MAP_ENTRY_MAGIC
)
628 maxsiz
= sizeof(part
->pmPartType
);
629 if (maxsiz
> (int)sizeof(partyp
))
630 maxsiz
= sizeof(partyp
);
631 strncpy(partyp
, (char *)part
->pmPartType
, maxsiz
);
632 partyp
[maxsiz
-1] = '\0';
635 * Find out how to treat the partition type under NetBSD
637 while (map_entry
->type
!= MAP_EOL
) {
638 if (stricmp(map_entry
->name
, partyp
) == 0) {
639 entry_type
= map_entry
->type
;
646 * Now classify the use for NetBSD
648 if (entry_type
== MAP_RESERVED
)
650 else if (entry_type
== MAP_NETBSD
) {
651 if (bzb
->magic
!= APPLE_BZB_MAGIC
)
653 else if (bzb
->type
== APPLE_BZB_TYPEFS
) {
656 else if (bzb
->flags
.usr
)
660 } else if (bzb
->type
== APPLE_BZB_TYPESWAP
)
664 } else if (entry_type
== MAP_MACOS
)
672 getFstype(part
, len_type
, type
)
673 struct apple_part_map_entry
*part
;
678 switch(whichType(part
)) {
681 strncpy(type
, "4.2BSD", len_type
);
684 strncpy(type
, "swap", len_type
);
687 strncpy(type
, "HFS", len_type
);
697 getUse(part
, len_use
, use
)
698 struct apple_part_map_entry
*part
;
706 bzb
= (EBZB
*)&part
->pmBootArgs
[0];
707 switch(whichType(part
)) {
710 strncpy(use
, "Root&Usr", len_use
);
712 strncpy(use
, "Root", len_use
);
715 strncpy(use
, "Usr", len_use
);
720 strncpy(use
, "MacOS", len_use
);
723 strncpy(partyp
, (char *)part
->pmPartType
, sizeof(partyp
));
724 partyp
[sizeof(partyp
)-1] = '\0';
725 if (stricmp("Apple_Free", partyp
) == 0)
726 strncpy(use
, "Free", len_use
);
727 else if (stricmp("Apple_Scratch", partyp
) == 0)
728 strncpy(use
, "Scratch", len_use
);
729 else if (stricmp("Apple_MFS", partyp
) == 0)
730 strncpy(use
, "MFS", len_use
);
731 else if (stricmp("Apple_PRODOS", partyp
) == 0)
732 strncpy(use
, "PRODOS", len_use
);
734 strncpy(use
, "unknown", len_use
);
742 getName(part
, len_name
, name
)
743 struct apple_part_map_entry
*part
;
750 char dev_name
[100], macosblk
[512];
753 bzb
= (EBZB
*)&part
->pmBootArgs
[0];
754 switch(whichType(part
)) {
758 strncpy(name
, (char *)bzb
->mount_point
, len_name
);
764 * OK, this is stupid but it's damn nice to know!
766 snprintf (dev_name
, sizeof(dev_name
), "/dev/r%sc", diskdev
);
768 * Open the disk as a raw device
770 if ((fd
= open(dev_name
, O_RDONLY
, 0)) >= 0) {
771 seek
= (off_t
)part
->pmPyPartStart
+ (off_t
)2;
772 seek
*= (off_t
)blk_size
;
773 lseek(fd
, seek
, SEEK_SET
);
774 read(fd
, &macosblk
, sizeof(macosblk
));
775 macosblk
[37+32] = '\0';
776 strncpy(name
, (char *)bzb
->mount_point
, len_name
);
777 strncat(name
, " (", len_name
-strlen(name
));
778 strncat(name
, &macosblk
[37], len_name
-strlen(name
));
779 strncat(name
, ")", len_name
-strlen(name
));
789 * Find the first occurance of a Standard Type partition and
790 * mark it for use along with the default mount slot.
793 findStdType(num_parts
, in_use
, type
, count
, alt
)
803 for (i
= 0; i
< num_parts
; i
++) {
804 bzb
= (EBZB
*)&map
.blk
[i
].pmBootArgs
[0];
805 if (whichType(&map
.blk
[i
]) != type
|| bzb
->flags
.used
)
807 if (type
== ROOT_PART
) {
808 if (alt
>= 0 && alt
!= bzb
->cluster
)
810 setpartition(&map
.blk
[i
], in_use
, 0);
811 strcpy ((char *)bzb
->mount_point
, "/");
813 } else if (type
== UFS_PART
) {
814 if (alt
>= 0 && alt
!= bzb
->cluster
)
816 setpartition(&map
.blk
[i
], in_use
, 6);
817 if (bzb
->mount_point
[0] == '\0')
818 strcpy ((char *)bzb
->mount_point
, "/usr");
820 } else if (type
== SWAP_PART
) {
821 setpartition(&map
.blk
[i
], in_use
, 1);
830 * Reset the flags and reserved fields in the selected partition.
831 * This functions isn't called to process any of the reserved partitions
832 * where the boot code for MacOS is stored, so (hopefully) we won't
833 * do more damage that we're trying to avoid. Eventually the NetBSD
834 * Boot Code will need to go into a partition too, but that should go
835 * into a reserved partition as well. I'd suggest using a partition
836 * named something like "NetBSD_Boot" with a pmPartName of "Macintosh".
837 * The Apple Start Manager (in ROM) will then recognize the partition
838 * as the one containing the system bootstrip for the volume.
841 reset_part_flags(part
)
842 struct apple_part_map_entry
*part
;
847 * Clear out the MacOS fields that might be used for booting just
848 * in case we've clobbered the boot code.
850 part
->pmLgDataStart
= 0;
851 part
->pmPartStatus
= 0x77; /* make sure the partition shows up */
852 part
->pmLgBootStart
= 0;
853 part
->pmBootSize
= 0;
854 part
->pmBootLoad
= 0;
855 part
->pmBootLoad2
= 0;
856 part
->pmBootEntry
= 0;
857 part
->pmBootEntry2
= 0;
858 part
->pmBootCksum
= 0;
861 * Clear out all the NetBSD fields too. We only clear out the ones
862 * that should get reset during our processing.
864 bzb
= (EBZB
*)&part
->pmBootArgs
[0];
872 bzb
->flags
.slice
= 0;
879 * 1) Moves all the Partition Map entries to the front of the Map.
880 * This is required because some disk formatters leave holes.
881 * 2) Sorts all entries by ascending start block number.
882 * Needed so the NetBSD algorithm for finding partitions works
883 * consistently from a user perspective.
884 * 3) Collapse multiple adjected "free" entries into a single entry.
885 * 4) Identify the NetBSD mount_points.
890 struct apple_part_map_entry tmp_blk
;
891 char in_use
[MAXPARTITIONS
];
896 * Step 1, squeeze out the holes that some disk formatters leave in
897 * the Map. Also convert any "old" Map entries to the new entry
898 * type. Also clear out our used flag which is used to indicte
899 * we've mapped the partition.
902 for (i
=0;i
<map
.size
-1;i
++) {
903 if (map
.blk
[i
].pmSig
== 0x5453)
904 map
.blk
[i
].pmSig
= APPLE_PART_MAP_ENTRY_MAGIC
;
905 if (map
.blk
[i
].pmSig
!= APPLE_PART_MAP_ENTRY_MAGIC
) {
906 for (j
=i
+1;j
<map
.size
;j
++) {
907 if (map
.blk
[j
].pmSig
== 0x5453)
908 map
.blk
[j
].pmSig
= APPLE_PART_MAP_ENTRY_MAGIC
;
909 if (map
.blk
[j
].pmSig
== APPLE_PART_MAP_ENTRY_MAGIC
) {
910 memcpy (&map
.blk
[i
], &map
.blk
[j
], sizeof(map
.blk
[i
]));
911 map
.blk
[j
].pmSig
= 0;
917 bzb
= (EBZB
*)&map
.blk
[i
].pmBootArgs
[0];
924 * Step 2, sort by ascending starting block number. Since
925 * we've already removed the holes we only need to
926 * deal with the in_use count of blocks.
928 for (i
=0;i
<map
.in_use_cnt
-1;i
++) {
929 for (j
=i
+1;j
<map
.in_use_cnt
;j
++) {
930 if (map
.blk
[i
].pmPyPartStart
> map
.blk
[j
].pmPyPartStart
) {
931 memcpy (&tmp_blk
, &map
.blk
[i
], sizeof(tmp_blk
));
932 memcpy (&map
.blk
[i
], &map
.blk
[j
], sizeof(map
.blk
[i
]));
933 memcpy (&map
.blk
[j
], &tmp_blk
, sizeof(map
.blk
[j
]));
939 * Step 3, merge adjacent free space
941 for (i
=0;i
<map
.in_use_cnt
-1;i
++) {
942 if (stricmp("Apple_Free", (char *)map
.blk
[i
].pmPartType
) == 0 &&
943 stricmp("Apple_Free", (char *)map
.blk
[i
+1].pmPartType
) == 0) {
944 map
.blk
[i
].pmPartBlkCnt
+= map
.blk
[i
+1].pmPartBlkCnt
;
945 map
.blk
[i
].pmDataCnt
+= map
.blk
[i
+1].pmDataCnt
;
946 map
.blk
[i
+1].pmSig
= 0;
947 for (j
=i
+1;j
<map
.in_use_cnt
-1;j
++) {
948 memcpy (&map
.blk
[j
], &map
.blk
[j
+1], sizeof(map
.blk
[j
]));
949 map
.blk
[j
+1].pmSig
= 0;
956 * Step 4, try to identify the mount points for the partitions
957 * and adjust the pmMapBlkCnt in each Map entry. Set
958 * up the display array for the non-reserved partitions,
959 * and count the number of NetBSD usable partitions
967 * Clear out record of partition slots already in use
969 memset(&in_use
, 0, sizeof(in_use
));
970 for (i
=0,j
=0;i
<map
.in_use_cnt
;i
++) {
971 map
.blk
[i
].pmSig
= APPLE_PART_MAP_ENTRY_MAGIC
;
972 map
.blk
[i
].pmMapBlkCnt
= map
.in_use_cnt
;
974 * Since MAXPARTITIONS == 8 for mac68k, and we do not display
975 * the c partition, we only need 7 partition slots on the screen.
976 * If/when MAXPARTITIONS is changed, the "Edit Disk Partition Map"
977 * needs to be a scrollable view of the partition table.
979 if (whichType(&map
.blk
[i
]) && (j
< MAXPARTITIONS
- 1)) {
985 * Fill in standard partitions. Look for a Cluster "0" first and use
986 * it, otherwise take any Cluster value.
988 if (findStdType(map
.in_use_cnt
, in_use
, ROOT_PART
, &map
.root_cnt
, 0))
989 findStdType(map
.in_use_cnt
, in_use
, ROOT_PART
, &map
.root_cnt
, -1);
990 if (findStdType(map
.in_use_cnt
, in_use
, UFS_PART
, &map
.usr_cnt
, 0))
991 findStdType(map
.in_use_cnt
, in_use
, UFS_PART
, &map
.usr_cnt
, -1);
992 if (findStdType(map
.in_use_cnt
, in_use
, SWAP_PART
, &map
.swap_cnt
, 0))
993 findStdType(map
.in_use_cnt
, in_use
, SWAP_PART
, &map
.swap_cnt
, -1);
995 #ifdef MD_DEBUG_SORT_MERGE
996 md_debug_dump("After marking Standard Types");
999 * Now fill in the remaining partitions counting them by type and
1000 * assigning them the slot the where the kernel should map them.
1001 * This will be where they are displayed in the Edit Map.
1003 for (i
=0; i
< map
.in_use_cnt
; i
++) {
1004 bzb
= (EBZB
*)&map
.blk
[i
].pmBootArgs
[0];
1005 if (bzb
->flags
.used
== 0) {
1006 if ((j
= getFreeLabelEntry(in_use
)) < 0)
1008 switch (whichType(&map
.blk
[i
])) {
1011 setpartition(&map
.blk
[i
], in_use
, j
);
1015 setpartition(&map
.blk
[i
], in_use
, j
);
1019 setpartition(&map
.blk
[i
], in_use
, j
);
1023 setpartition(&map
.blk
[i
], in_use
, j
);
1026 setpartition(&map
.blk
[i
], in_use
, j
);
1032 #ifdef MD_DEBUG_SORT_MERGE
1033 md_debug_dump("After sort merge");
1039 disp_selected_part(sel
)
1043 char fstyp
[16], use
[16], name
[32];
1046 msg_table_add(MSG_part_header
);
1047 for (i
=0;i
<map
.usable_cnt
;i
++) {
1048 if (i
== sel
) msg_standout();
1050 getFstype(&map
.blk
[j
], sizeof(fstyp
), fstyp
);
1051 getUse(&map
.blk
[j
], sizeof(use
), use
);
1052 getName(&map
.blk
[j
], sizeof(name
), name
);
1053 bzb
= (EBZB
*)&map
.blk
[j
].pmBootArgs
[0];
1054 msg_table_add(MSG_part_row
, diskdev
,
1055 bzb
->flags
.part
, map
.blk
[j
].pmPyPartStart
,
1056 map
.blk
[j
].pmPartBlkCnt
, fstyp
, use
, name
);
1057 if (i
== sel
) msg_standend();
1063 * check for any anomalies on the requested setup
1071 errs
= (!map
.root_cnt
) || (map
.root_cnt
> 1) || (!map
.swap_cnt
) ||
1074 for (i
=0;i
<map
.usable_cnt
;i
++) {
1076 if (map
.blk
[j
].pmPyPartStart
> dlsize
)
1078 if ((map
.blk
[j
].pmPyPartStart
+ map
.blk
[j
].pmPartBlkCnt
) > dlsize
+ 1)
1085 * check for and report anomalies on the requested setup
1094 if (!map
.root_cnt
) {
1095 msg_display_add(MSG_disksetup_no_root
);
1098 if (map
.root_cnt
> 1) {
1099 msg_display_add(MSG_disksetup_multiple_roots
);
1102 if (!map
.swap_cnt
) {
1103 msg_display_add(MSG_disksetup_no_swap
);
1106 if (map
.swap_cnt
> 1) {
1107 msg_display_add(MSG_disksetup_multiple_swaps
);
1110 for (i
=0;i
<map
.usable_cnt
;i
++) {
1112 if (map
.blk
[j
].pmPyPartStart
> dlsize
) {
1113 bzb
= (EBZB
*)&map
.blk
[j
].pmBootArgs
[0];
1114 msg_display_add(MSG_disksetup_part_beginning
,
1115 diskdev
, bzb
->flags
.part
);
1118 if ((map
.blk
[j
].pmPyPartStart
+ map
.blk
[j
].pmPartBlkCnt
) > dlsize
) {
1119 bzb
= (EBZB
*)&map
.blk
[j
].pmBootArgs
[0];
1120 msg_display_add(MSG_disksetup_part_size
,
1121 diskdev
, bzb
->flags
.part
);
1126 msg_display_add(MSG_disksetup_noerrors
);
1136 msg_display (MSG_fullpart
, diskdev
);
1137 process_menu (MENU_fullpart
, NULL
);
1142 /* If blowing away the whole disk, let user know if there
1143 * are any active disk partitions */
1145 if (map
.usable_cnt
> (map
.root_cnt
+map
.swap_cnt
+map
.usr_cnt
)) {
1146 msg_display (MSG_ovrwrite
);
1147 process_menu (MENU_noyes
, NULL
);
1154 * mark all non-reserved partitions as "free"
1155 * then sort and merge the map into something sensible
1157 for (i
=0;i
<map
.size
;i
++)
1158 if (whichType(&map
.blk
[i
]))
1159 strcpy ((char *)map
.blk
[i
].pmPartType
, "Apple_Free");
1162 process_menu (MENU_editparttable
, NULL
);
1166 #ifdef MD_DEBUG_SORT_MERGE
1168 md_debug_dump(title
)
1172 char fstyp
[16], use
[16], name
[64];
1177 sprintf(buf
, "Apple Disk Partition Map: %s", title
);
1178 msg_table_add(MSG_dump_line
, buf
);
1179 msg_table_add(MSG_dump_line
,
1180 "slot base fstype use name");
1181 for (i
=0;i
<map
.in_use_cnt
;i
++) {
1182 j
= whichType(&map
.blk
[i
]);
1183 getFstype(&map
.blk
[i
], sizeof(fstyp
), fstyp
);
1184 getUse(&map
.blk
[i
], sizeof(use
), use
);
1185 getName(&map
.blk
[i
], sizeof(name
), name
);
1186 bzb
= (EBZB
*) &map
.blk
[i
].pmBootArgs
[0];
1187 type
= bzb
->flags
.part
;
1188 if (type
< 'a' || type
> 'h') type
= '?';
1189 if (j
== 0) strcpy (name
, "reserved for Apple");
1190 sprintf(buf
, " %02d:%c %08x %8s %10s %s", i
+1, type
,
1191 map
.blk
[i
].pmPyPartStart
, fstyp
, use
, name
);
1192 msg_table_add(MSG_dump_line
, buf
);
1194 process_menu(MENU_okabort
, NULL
);
1198 #endif /* MD_DEBUG_SORT_MERGE */