Home | History | Annotate | Line # | Download | only in acorn32
md.c revision 1.5.2.1
      1  1.5.2.1    bouyer /*	$NetBSD: md.c,v 1.5.2.1 2020/10/15 19:36:51 bouyer Exp $ */
      2      1.1  dholland 
      3      1.1  dholland /*
      4      1.1  dholland  * Copyright 1997 Piermont Information Systems Inc.
      5      1.1  dholland  * All rights reserved.
      6      1.1  dholland  *
      7      1.1  dholland  * Based on code written by Philip A. Nelson for Piermont Information
      8      1.1  dholland  * Systems Inc.
      9      1.1  dholland  *
     10      1.1  dholland  * Redistribution and use in source and binary forms, with or without
     11      1.1  dholland  * modification, are permitted provided that the following conditions
     12      1.1  dholland  * are met:
     13      1.1  dholland  * 1. Redistributions of source code must retain the above copyright
     14      1.1  dholland  *    notice, this list of conditions and the following disclaimer.
     15      1.1  dholland  * 2. Redistributions in binary form must reproduce the above copyright
     16      1.1  dholland  *    notice, this list of conditions and the following disclaimer in the
     17      1.1  dholland  *    documentation and/or other materials provided with the distribution.
     18      1.1  dholland  * 3. The name of Piermont Information Systems Inc. may not be used to endorse
     19      1.1  dholland  *    or promote products derived from this software without specific prior
     20      1.1  dholland  *    written permission.
     21      1.1  dholland  *
     22      1.1  dholland  * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
     23      1.1  dholland  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24      1.1  dholland  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25      1.1  dholland  * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
     26      1.1  dholland  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     27      1.1  dholland  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     28      1.1  dholland  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     29      1.1  dholland  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     30      1.1  dholland  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     31      1.1  dholland  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     32      1.1  dholland  * THE POSSIBILITY OF SUCH DAMAGE.
     33      1.1  dholland  */
     34      1.1  dholland 
     35      1.3     skrll /* md.c -- arm32 machine specific routines */
     36      1.1  dholland 
     37      1.1  dholland #include <stdio.h>
     38      1.1  dholland #include <curses.h>
     39      1.1  dholland #include <unistd.h>
     40      1.1  dholland #include <fcntl.h>
     41      1.1  dholland #include <util.h>
     42      1.1  dholland #include <sys/types.h>
     43      1.1  dholland #include <sys/disklabel_acorn.h>
     44      1.1  dholland #include <sys/ioctl.h>
     45      1.1  dholland #include <sys/param.h>
     46      1.1  dholland 
     47      1.1  dholland #include "defs.h"
     48      1.1  dholland #include "md.h"
     49      1.1  dholland #include "msg_defs.h"
     50      1.1  dholland #include "menu_defs.h"
     51      1.1  dholland 
     52      1.1  dholland static int filecore_checksum(u_char *);
     53      1.1  dholland 
     54      1.1  dholland void
     55      1.1  dholland md_init(void)
     56      1.1  dholland {
     57      1.1  dholland }
     58      1.1  dholland 
     59      1.1  dholland void
     60      1.1  dholland md_init_set_status(int flags)
     61      1.1  dholland {
     62      1.1  dholland 	(void)flags;
     63      1.1  dholland }
     64      1.1  dholland 
     65      1.4    martin bool
     66      1.4    martin md_get_info(struct install_partition_desc *install)
     67      1.1  dholland {
     68      1.1  dholland 	struct disklabel disklabel;
     69      1.1  dholland 	int fd;
     70      1.1  dholland 	char dev_name[100];
     71      1.1  dholland 	static unsigned char bb[DEV_BSIZE];
     72      1.1  dholland 	struct filecore_bootblock *fcbb = (struct filecore_bootblock *)bb;
     73      1.1  dholland 	int offset = 0;
     74      1.1  dholland 
     75      1.2    martin 	snprintf(dev_name, 100, "/dev/r%s%c", pm->diskdev, 'a' + getrawpartition());
     76      1.1  dholland 
     77      1.1  dholland 	fd = open(dev_name, O_RDONLY, 0);
     78      1.1  dholland 	if (fd < 0) {
     79      1.1  dholland 		endwin();
     80      1.1  dholland 		fprintf(stderr, "Can't open %s\n", dev_name);
     81      1.1  dholland 		exit(1);
     82      1.1  dholland 	}
     83      1.1  dholland 	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
     84      1.1  dholland 		endwin();
     85      1.1  dholland 		fprintf(stderr, "Can't read disklabel on %s.\n", dev_name);
     86      1.1  dholland 		close(fd);
     87      1.1  dholland 		exit(1);
     88      1.1  dholland 	}
     89      1.1  dholland 
     90      1.1  dholland 	if (lseek(fd, (off_t)FILECORE_BOOT_SECTOR * DEV_BSIZE, SEEK_SET) < 0
     91      1.1  dholland 	    || read(fd, bb, sizeof(bb)) - sizeof(bb) != 0) {
     92      1.1  dholland 		endwin();
     93      1.1  dholland 		fprintf(stderr, "%s", msg_string(MSG_badreadbb));
     94      1.1  dholland 		close(fd);
     95      1.1  dholland 		exit(1);
     96      1.1  dholland 	}
     97      1.1  dholland 
     98      1.1  dholland 	/* Check if table is valid. */
     99      1.1  dholland 	if (filecore_checksum(bb) == fcbb->checksum) {
    100      1.1  dholland 		/*
    101      1.1  dholland 		 * Check for NetBSD/arm32 (RiscBSD) partition marker.
    102      1.1  dholland 		 * If found the NetBSD disklabel location is easy.
    103      1.1  dholland 		 */
    104      1.1  dholland 
    105      1.1  dholland 		offset = (fcbb->partition_cyl_low +
    106      1.1  dholland 		    (fcbb->partition_cyl_high << 8)) *
    107      1.1  dholland 		    fcbb->heads * fcbb->secspertrack;
    108      1.1  dholland 
    109      1.1  dholland 		if (fcbb->partition_type == PARTITION_FORMAT_RISCBSD)
    110      1.1  dholland 			;
    111      1.1  dholland 		else if (fcbb->partition_type == PARTITION_FORMAT_RISCIX) {
    112      1.1  dholland 			/*
    113      1.1  dholland      			 * Ok we need to read the RISCiX partition table and
    114      1.1  dholland 			 * search for a partition named RiscBSD, NetBSD or
    115      1.1  dholland 			 * Empty:
    116      1.1  dholland 			 */
    117      1.1  dholland 
    118      1.1  dholland 			struct riscix_partition_table *riscix_part =
    119      1.1  dholland 			    (struct riscix_partition_table *)bb;
    120      1.1  dholland 			struct riscix_partition *part;
    121      1.1  dholland 			int loop;
    122      1.1  dholland 
    123      1.1  dholland 			if (lseek(fd, (off_t)offset * DEV_BSIZE, SEEK_SET) < 0
    124      1.1  dholland 			    || read(fd, bb, sizeof(bb)) - sizeof(bb) != 0) {
    125      1.1  dholland 				endwin();
    126      1.1  dholland 				fprintf(stderr, "%s",
    127      1.1  dholland 				    msg_string(MSG_badreadriscix));
    128      1.1  dholland 				close(fd);
    129      1.1  dholland 				exit(1);
    130      1.1  dholland 			}
    131      1.1  dholland 
    132      1.1  dholland 			/* Break out as soon as we find a suitable partition */
    133      1.1  dholland 			for (loop = 0; loop < NRISCIX_PARTITIONS; ++loop) {
    134      1.1  dholland 				part = &riscix_part->partitions[loop];
    135      1.1  dholland 				if (strcmp((char *)part->rp_name, "RiscBSD") == 0
    136      1.1  dholland 				    || strcmp((char *)part->rp_name, "NetBSD") == 0
    137      1.1  dholland 				    || strcmp((char *)part->rp_name, "Empty:") == 0) {
    138      1.1  dholland 					offset = part->rp_start;
    139      1.1  dholland 					break;
    140      1.1  dholland 				}
    141      1.1  dholland 			}
    142      1.1  dholland 			if (loop == NRISCIX_PARTITIONS) {
    143      1.1  dholland 				/*
    144      1.1  dholland 				 * Valid filecore boot block, RISCiX partition
    145      1.1  dholland 				 * table but no NetBSD partition. We should
    146      1.1  dholland 				 * leave this disc alone.
    147      1.1  dholland 				 */
    148      1.1  dholland 				endwin();
    149      1.1  dholland 				fprintf(stderr, "%s",
    150      1.1  dholland 				    msg_string(MSG_notnetbsdriscix));
    151      1.1  dholland 				close(fd);
    152      1.1  dholland 				exit(1);
    153      1.1  dholland 			}
    154      1.1  dholland 		} else {
    155      1.1  dholland 			/*
    156      1.1  dholland 			 * Valid filecore boot block and no non-ADFS partition.
    157      1.1  dholland 			 * This means that the whole disc is allocated for ADFS
    158      1.1  dholland 			 * so do not trash ! If the user really wants to put a
    159      1.1  dholland 			 * NetBSD disklabel on the disc then they should remove
    160      1.1  dholland 			 * the filecore boot block first with dd.
    161      1.1  dholland 			 */
    162      1.1  dholland 			endwin();
    163      1.1  dholland 			fprintf(stderr, "%s", msg_string(MSG_notnetbsd));
    164      1.1  dholland 			close(fd);
    165      1.1  dholland 			exit(1);
    166      1.1  dholland 		}
    167      1.1  dholland 	}
    168      1.1  dholland 	close(fd);
    169      1.1  dholland 
    170      1.2    martin 	pm->dlcyl = disklabel.d_ncylinders;
    171      1.2    martin 	pm->dlhead = disklabel.d_ntracks;
    172      1.2    martin 	pm->dlsec = disklabel.d_nsectors;
    173      1.2    martin 	pm->sectorsize = disklabel.d_secsize;
    174      1.2    martin 	pm->dlcylsize = disklabel.d_secpercyl;
    175      1.1  dholland 
    176      1.1  dholland 	/*
    177      1.2    martin 	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
    178      1.1  dholland 	 * and secperunit,  just in case the disk is already labelled.
    179      1.1  dholland 	 * (If our new label's RAW_PART size ends up smaller than the
    180      1.1  dholland 	 * in-core RAW_PART size  value, updating the label will fail.)
    181      1.1  dholland 	 */
    182      1.2    martin 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
    183      1.2    martin 	if (disklabel.d_secperunit > pm->dlsize)
    184      1.2    martin 		pm->dlsize = disklabel.d_secperunit;
    185      1.1  dholland 
    186      1.2    martin 	pm->ptstart = offset;
    187      1.1  dholland /*	endwin();
    188      1.2    martin 	printf("pm->dlcyl=%d\n", pm->dlcyl);
    189      1.2    martin 	printf("pm->dlhead=%d\n", pm->dlhead);
    190      1.2    martin 	printf("pm->dlsec=%d\n", pm->dlsec);
    191      1.2    martin 	printf("secsz=%d\n", pm->sectorsize);
    192      1.2    martin 	printf("cylsz=%d\n", pm->dlcylsize);
    193      1.2    martin 	printf("dlsz=%d\n", pm->dlsize);
    194      1.2    martin 	printf("pstart=%d\n", pm->ptstart);
    195      1.1  dholland 	printf("pstart=%d\n", partsize);
    196      1.1  dholland 	printf("secpun=%d\n", disklabel.d_secperunit);
    197      1.1  dholland 	backtowin();*/
    198      1.1  dholland 
    199      1.4    martin 	return true;
    200      1.1  dholland }
    201      1.1  dholland 
    202      1.1  dholland /*
    203      1.1  dholland  * md back-end code for menu-driven BSD disklabel editor.
    204      1.1  dholland  */
    205  1.5.2.1    bouyer int
    206      1.4    martin md_make_bsd_partitions(struct install_partition_desc *install)
    207      1.1  dholland {
    208      1.4    martin 	return make_bsd_partitions(install);
    209      1.1  dholland }
    210      1.1  dholland 
    211      1.1  dholland /*
    212      1.1  dholland  * any additional partition validation
    213      1.1  dholland  */
    214      1.4    martin bool
    215      1.4    martin md_check_partitions(struct install_partition_desc *install)
    216      1.1  dholland {
    217      1.1  dholland 	return 1;
    218      1.1  dholland }
    219      1.1  dholland 
    220      1.1  dholland /*
    221      1.1  dholland  * hook called before writing new disklabel.
    222      1.1  dholland  */
    223      1.4    martin bool
    224      1.4    martin md_pre_disklabel(struct install_partition_desc *install,
    225      1.4    martin    struct disk_partitions *part)
    226      1.1  dholland {
    227      1.1  dholland 	return 0;
    228      1.1  dholland }
    229      1.1  dholland 
    230      1.1  dholland /*
    231      1.1  dholland  * hook called after writing disklabel to new target disk.
    232      1.1  dholland  */
    233      1.4    martin bool
    234      1.4    martin md_post_disklabel(struct install_partition_desc *install,
    235      1.4    martin    struct disk_partitions *part)
    236      1.1  dholland {
    237      1.4    martin 	return true;
    238      1.1  dholland }
    239      1.1  dholland 
    240      1.1  dholland /*
    241      1.1  dholland  * hook called after upgrade() or install() has finished setting
    242      1.1  dholland  * up the target disk but immediately before the user is given the
    243      1.1  dholland  * ``disks are now set up'' message.
    244      1.1  dholland  */
    245      1.1  dholland int
    246      1.4    martin md_post_newfs(struct install_partition_desc *install)
    247      1.1  dholland {
    248      1.1  dholland 	return 0;
    249      1.1  dholland }
    250      1.1  dholland 
    251      1.1  dholland int
    252      1.4    martin md_post_extract(struct install_partition_desc *install)
    253      1.1  dholland {
    254      1.1  dholland 	return 0;
    255      1.1  dholland }
    256      1.1  dholland 
    257      1.1  dholland void
    258      1.4    martin md_cleanup_install(struct install_partition_desc *install)
    259      1.1  dholland {
    260      1.1  dholland #ifndef DEBUG
    261      1.1  dholland 	enable_rc_conf();
    262      1.1  dholland #endif
    263      1.1  dholland }
    264      1.1  dholland 
    265      1.1  dholland int
    266      1.4    martin md_pre_update(struct install_partition_desc *install)
    267      1.1  dholland {
    268      1.1  dholland 	return 1;
    269      1.1  dholland }
    270      1.1  dholland 
    271      1.1  dholland /* Upgrade support */
    272      1.1  dholland int
    273      1.4    martin md_update(struct install_partition_desc *install)
    274      1.1  dholland {
    275      1.4    martin 	md_post_newfs(install);
    276      1.1  dholland 	return 1;
    277      1.1  dholland }
    278      1.1  dholland 
    279      1.1  dholland /*
    280      1.1  dholland  * static int filecore_checksum(u_char *bootblock)
    281      1.1  dholland  *
    282      1.1  dholland  * Calculates the filecore boot block checksum. This is used to validate
    283      1.1  dholland  * a filecore boot block on the disk.  If a boot block is validated then
    284      1.1  dholland  * it is used to locate the partition table. If the boot block is not
    285      1.1  dholland  * validated, it is assumed that the whole disk is NetBSD.
    286      1.1  dholland  *
    287      1.1  dholland  * The basic algorithm is:
    288      1.1  dholland  *
    289      1.1  dholland  *	for (each byte in block, excluding checksum) {
    290      1.1  dholland  *		sum += byte;
    291      1.1  dholland  *		if (sum > 255)
    292      1.1  dholland  *			sum -= 255;
    293      1.1  dholland  *	}
    294      1.1  dholland  *
    295      1.1  dholland  * That's equivalent to summing all of the bytes in the block
    296      1.1  dholland  * (excluding the checksum byte, of course), then calculating the
    297      1.1  dholland  * checksum as "cksum = sum - ((sum - 1) / 255) * 255)".  That
    298      1.1  dholland  * expression may or may not yield a faster checksum function,
    299      1.1  dholland  * but it's easier to reason about.
    300      1.1  dholland  *
    301      1.1  dholland  * Note that if you have a block filled with bytes of a single
    302      1.1  dholland  * value "X" (regardless of that value!) and calculate the cksum
    303      1.1  dholland  * of the block (excluding the checksum byte), you will _always_
    304      1.1  dholland  * end up with a checksum of X.  (Do the math; that can be derived
    305      1.1  dholland  * from the checksum calculation function!)  That means that
    306      1.1  dholland  * blocks which contain bytes which all have the same value will
    307      1.1  dholland  * always checksum properly.  That's a _very_ unlikely occurence
    308      1.1  dholland  * (probably impossible, actually) for a valid filecore boot block,
    309      1.1  dholland  * so we treat such blocks as invalid.
    310      1.1  dholland  */
    311      1.1  dholland 
    312      1.1  dholland static int
    313      1.1  dholland filecore_checksum(u_char *bootblock)
    314      1.1  dholland {
    315      1.1  dholland 	u_char byte0, accum_diff;
    316      1.1  dholland 	u_int sum;
    317      1.1  dholland 	int i;
    318      1.1  dholland 
    319      1.1  dholland 	sum = 0;
    320      1.1  dholland 	accum_diff = 0;
    321      1.1  dholland 	byte0 = bootblock[0];
    322      1.1  dholland 
    323      1.1  dholland 	/*
    324      1.1  dholland 	 * Sum the contents of the block, keeping track of whether
    325      1.1  dholland 	 * or not all bytes are the same.  If 'accum_diff' ends up
    326      1.1  dholland 	 * being zero, all of the bytes are, in fact, the same.
    327      1.1  dholland 	 */
    328      1.1  dholland 	for (i = 0; i < 511; ++i) {
    329      1.1  dholland 		sum += bootblock[i];
    330      1.1  dholland 		accum_diff |= bootblock[i] ^ byte0;
    331      1.1  dholland 	}
    332      1.1  dholland 
    333      1.1  dholland 	/*
    334      1.1  dholland 	 * Check to see if the checksum byte is the same as the
    335      1.1  dholland 	 * rest of the bytes, too.  (Note that if all of the bytes
    336      1.1  dholland 	 * are the same except the checksum, a checksum compare
    337      1.1  dholland 	 * won't succeed, but that's not our problem.)
    338      1.1  dholland 	 */
    339      1.1  dholland 	accum_diff |= bootblock[i] ^ byte0;
    340      1.1  dholland 
    341      1.1  dholland 	/* All bytes in block are the same; call it invalid. */
    342      1.1  dholland 	if (accum_diff == 0)
    343      1.1  dholland 		return (-1);
    344      1.1  dholland 
    345      1.1  dholland 	return (sum - ((sum - 1) / 255) * 255);
    346      1.1  dholland }
    347      1.1  dholland 
    348      1.1  dholland int
    349      1.5    martin md_pre_mount(struct install_partition_desc *install, size_t ndx)
    350      1.1  dholland {
    351      1.1  dholland 	return 0;
    352      1.1  dholland }
    353      1.4    martin 
    354      1.4    martin #ifdef HAVE_GPT
    355      1.4    martin /*
    356      1.4    martin  * New GPT partitions have been written, update bootloader or remember
    357      1.4    martin  * data untill needed in md_post_newfs
    358      1.4    martin  */
    359      1.4    martin bool
    360      1.4    martin md_gpt_post_write(struct disk_partitions *parts, part_id root_id,
    361      1.4    martin     bool root_is_new, part_id efi_id, bool efi_is_new)
    362      1.4    martin {
    363      1.4    martin 
    364      1.4    martin 	return true;
    365      1.4    martin }
    366      1.4    martin #endif
    367      1.4    martin 
    368      1.4    martin bool
    369      1.4    martin md_parts_use_wholedisk(struct disk_partitions *parts)
    370      1.4    martin {
    371      1.4    martin 	return parts_use_wholedisk(parts, 0, NULL);
    372      1.4    martin }
    373