From: deraadt Date: Tue, 9 Jan 1996 09:13:10 +0000 (+0000) Subject: from leo: X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=40ad4475dc8d60b1973bcbcb7d2346a8d87c2775;p=openbsd from leo: Atari partion table checker. Checks the validity of AHDI and/or NetBSD/Atari partition tables. (Waldi Ravens) --- diff --git a/sys/arch/atari/stand/tostools/aptck/Makefile b/sys/arch/atari/stand/tostools/aptck/Makefile new file mode 100644 index 00000000000..baf781fa59f --- /dev/null +++ b/sys/arch/atari/stand/tostools/aptck/Makefile @@ -0,0 +1,17 @@ +# $NetBSD: Makefile,v 1.1.1.1 1996/01/07 21:54:16 leo Exp $ + +PROG = aptck.ttp + +OBJS = aptck.o biosrw.o diskio.o disklabel.o +HEADERS = aptck.h disklabel.h + +LIBS = -lxhdi +CLEAN = aptck.c + +include ../Makefile.inc + +aptck.c: aptck.in biosrw.s diskio.c disklabel.c + ${AWK} -f ./setversion $^ > aptck.c + +${PROG}: ${OBJS} ${LDADD} + ${CC} ${LDFLAGS} -o $@ ${OBJS} ${LDADD} ${LIBS} diff --git a/sys/arch/atari/stand/tostools/aptck/aptck.h b/sys/arch/atari/stand/tostools/aptck/aptck.h new file mode 100644 index 00000000000..64f37b49a05 --- /dev/null +++ b/sys/arch/atari/stand/tostools/aptck/aptck.h @@ -0,0 +1,105 @@ +/* $NetBSD: aptck.h,v 1.1.1.1 1996/01/07 21:54:15 leo Exp $ */ + +/* + * Copyright (c) 1995 Waldi Ravens. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Waldi Ravens. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APTCK_H +#define APTCK_H + +#define MINOR(bus, target, lun) (lun) +#define MAJOR(bus, target, lun) (((bus) << 3) + (target)) + +#define LUN(major, minor) (minor) +#define TARGET(major, minor) ((major) & 0x0007) +#define BUS(major, minor) (((major) >> 3) & 0x1FFF) +#define BIOSDEV(major, minor) (((minor) == 0) ? ((major) + 2) : 0) + +typedef signed char int8_t; +typedef unsigned char u_int8_t; +typedef signed short int16_t; +typedef unsigned short u_int16_t; +typedef signed long int32_t; +typedef unsigned long u_int32_t; + +typedef enum { + ACSI = 0, + SCSI = 1, + IDE = 2 +} bus_t; + +typedef struct { + char id[4]; + u_int start; + u_int end; + u_int rsec; + u_int rent; +} part_t; + +typedef struct { + u_int major; /* XHDI major number */ + u_int minor; /* XHDI minor number */ + char * sname; /* short name (s00) */ + char * fname; /* full name (scsi target 0 lun 0)*/ + char * product; /* product name */ + u_long bsize; /* block size in bytes */ + u_long msize; /* medium size in blocks */ + u_int bblock; /* NetBSD boot block */ + u_int lblofs; /* label offset in boot block */ + u_int hdsize; /* medium size from root sector */ + u_int bslst; /* start of bad sector list */ + u_int bslend; /* end of bad sector list */ + u_int nroots; /* # of auxilary root sectors */ + u_int *roots; /* list of auxilary roots */ + u_int nparts; /* number of regular partitions */ + part_t *parts; /* list of partition descriptors */ +} disk_t; + + +/* + * biosrw.s + */ +EXTERN int bios_read PROTO((void *, u_int, u_int, u_int)); +EXTERN int bios_write PROTO((void *, u_int, u_int, u_int)); +EXTERN void bios_critic PROTO((void)); + +/* + * diskio.c + */ +EXTERN disk_t * disk_open PROTO((char *)); +EXTERN void disk_close PROTO((disk_t *)); +EXTERN void * disk_read PROTO((disk_t *, u_int, u_int)); +EXTERN int disk_write PROTO((disk_t *, u_int, u_int, void *)); + +/* + * disklabel.c + */ +EXTERN int readdisklabel PROTO((disk_t *)); + +#endif /* APTCK_H */ diff --git a/sys/arch/atari/stand/tostools/aptck/aptck.in b/sys/arch/atari/stand/tostools/aptck/aptck.in new file mode 100644 index 00000000000..a16c3d31428 --- /dev/null +++ b/sys/arch/atari/stand/tostools/aptck/aptck.in @@ -0,0 +1,123 @@ +/* $NetBSD: aptck.in,v 1.1.1.1 1996/01/07 21:54:17 leo Exp $ */ + +/* + * Copyright (c) 1995 Waldi Ravens. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Waldi Ravens. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "libtos.h" +#include "aptck.h" + +int main PROTO((int, char **)); + +static void version PROTO((void)) NORETURN; +static void usage PROTO((void)) NORETURN; + +static void +version() +{ + eprintf("%s\n", "$Revision: 1.1 $"); + xexit(EXIT_SUCCESS); +} + +static void +usage() +{ + eprintf("Usage: aptck [OPTIONS] DISK..\n" + "where OPTIONS are:\n" + "\t-V display version information and exit\n" + "\t-h display this help and exit\n" + "\t-o FILE send output to FILE instead of stdout\n" + "\t-w wait for key press before exiting\n\n" + "DISK is the concatenation of BUS, TARGET and LUN.\n" + "BUS is one of `i' (IDE), `a' (ACSI) or `s' (SCSI).\n" + "TARGET and LUN are one decimal digit each. LUN must\n" + "not be specified for IDE devices and is optional for\n" + "ACSI/SCSI devices (if omitted, LUN defaults to 0).\n\n" + "Examples: a0 refers to ACSI target 0 lun 0\n" + " s21 refers to SCSI target 2 lun 1\n" + ); + xexit(EXIT_SUCCESS); +} + +int +main(argc, argv) + int argc; + char **argv; +{ + extern int optind; + extern char *optarg; + + disk_t *dd; + int rv, c; + + init_toslib(*argv); + + while ((c = getopt(argc, argv, "Vho:w")) != -1) { + switch (c) { + case 'o': + redirect_output(optarg); + break; + case 'w': + set_wait_for_key(); + break; + case 'V': + version(); + /* NOT REACHED */ + case 'h': + default: + usage(); + /* NOT REACHED */ + } + } + argv += optind; + + if (!*argv) { + error(-1, "missing DISK argument"); + usage(); + /* NOT REACHED */ + } + + c = isatty(STDOUT_FILENO); + rv = EXIT_SUCCESS; + while (*argv) { + dd = disk_open(*argv++); + if (dd) { + if (readdisklabel(dd)) + rv = EXIT_FAILURE; + disk_close(dd); + if (c) + press_any_key(); + } + else rv = EXIT_FAILURE; + } + return(rv); +} diff --git a/sys/arch/atari/stand/tostools/aptck/biosrw.s b/sys/arch/atari/stand/tostools/aptck/biosrw.s new file mode 100644 index 00000000000..288fe835717 --- /dev/null +++ b/sys/arch/atari/stand/tostools/aptck/biosrw.s @@ -0,0 +1,82 @@ +/* $NetBSD: biosrw.s,v 1.1.1.1 1996/01/07 21:54:15 leo Exp $ */ + +/* + * Copyright (c) 1995 Waldi Ravens. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Waldi Ravens. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* int bios_read(buffer, offset, count, dev) */ + + .globl _bios_read + .text + .even + +_bios_read: + movml d1-d2/a1-a2,sp@- + movl sp@(24),sp@- | offset + movw sp@(38),sp@- | device + movw #-1,sp@- + movw sp@(38),sp@- | count + movl sp@(30),sp@- | buffer + movw #8,sp@- | read, physical mode + movw #4,sp@- + trap #13 | Rwabs() + lea sp@(18),sp + movml sp@+,d1-d2/a1-a2 + rts + +/* int bios_write(buffer, offset, count, dev) */ + + .globl _bios_write + .text + .even + +_bios_write: + movml d1-d2/a1-a2,sp@- + movl sp@(20),sp@- | offset + movw sp@(34),sp@- | device + movw #-1,sp@- + movw sp@(34),sp@- | count + movl sp@(26),sp@- | buffer + movw #9,sp@- | write, physical mode + movw #4,sp@- + trap #13 | Rwabs() + lea sp@(18),sp + movml sp@+,d1-d2/a1-a2 + rts + +/* int bios_critic(error) */ + + .globl _bios_critic + .text + .even + +_bios_critic: + movw sp@(4),d0 + extl d0 + rts diff --git a/sys/arch/atari/stand/tostools/aptck/diskio.c b/sys/arch/atari/stand/tostools/aptck/diskio.c new file mode 100644 index 00000000000..db7397c8825 --- /dev/null +++ b/sys/arch/atari/stand/tostools/aptck/diskio.c @@ -0,0 +1,338 @@ +/* $NetBSD: diskio.c,v 1.1.1.1 1996/01/07 21:54:16 leo Exp $ */ + +/* + * Copyright (c) 1995 Waldi Ravens. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Waldi Ravens. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "libtos.h" +#include "aptck.h" +#include "disklabel.h" +#include + +struct pun_info { + u_int16_t puns; + u_int8_t pun[16]; + u_int32_t part_start[16]; + u_int32_t P_cookie; + u_int32_t *P_cookptr; + u_int16_t P_version; + u_int16_t P_max_sector; + u_int32_t reserved[16]; +}; + +static char * strbd PROTO((char *, ...)); +static int setmami PROTO((disk_t *, char *)); +static int setnames PROTO((disk_t *)); +static int setsizes PROTO((disk_t *)); +static int ahdi_compatible PROTO((void)); + +disk_t * +disk_open(name) + char *name; +{ + disk_t *dd; + + dd = xmalloc(sizeof *dd); + memset(dd, 0, sizeof *dd); + + if (setmami(dd, name) || setnames(dd) || setsizes(dd)) { + disk_close(dd); + return(NULL); + } + return(dd); +} + +void +disk_close(dd) + disk_t *dd; +{ + if (dd) { + free(dd->product); + free(dd->sname); + free(dd->fname); + free(dd->roots); + free(dd->parts); + free(dd); + } +} + +void * +disk_read(dd, start, count) + disk_t *dd; + u_int start, + count; +{ + char *buffer; + int bdev; + long e; + + buffer = xmalloc(count * dd->bsize); + + e = XHReadWrite(dd->major, dd->minor, 0, start, count, buffer); + if (!e) + return(buffer); + if (e == -32 || (e == -1 && XHGetVersion() == -1)) { + if (!ahdi_compatible()) + fatal(-1, "AHDI 3.0 compatible harddisk driver required"); + bdev = BIOSDEV(dd->major, dd->minor); + if (bdev && !bios_read(buffer, start, count, bdev)) + return(buffer); + } + + free(buffer); + return(NULL); +} + +int +disk_write(dd, start, count, buffer) + disk_t *dd; + u_int start, + count; + void *buffer; +{ + int bdev; + long e; + + e = XHReadWrite(dd->major, dd->minor, 1, start, count, buffer); + if (e == -32 || (e == -1 && XHGetVersion() == -1)) { + if (!ahdi_compatible()) + fatal(-1, "AHDI 3.0 compatible harddisk driver required"); + bdev = BIOSDEV(dd->major, dd->minor); + if (bdev) + e = bios_write(buffer, start, count, bdev); + } + + return((int)e); +} + +static int +ahdi_compatible() +{ + static int ahdi_compat; + + if (!ahdi_compat) { + long oldsp = Super(0L); + struct pun_info *punp = *((struct pun_info **)0x0516); + Super(oldsp); + if (punp && punp->P_cookie == 0x41484449 + && punp->P_cookptr == &punp->P_cookie + && punp->P_version >= 0x0300) + ahdi_compat = 1; + } + return(ahdi_compat); +} + +static int +setmami(dd, name) + disk_t *dd; + char *name; +{ + char *p = name; + u_int target, lun; + bus_t bus; + + if (*p == 'i') { + bus = IDE; + if (*++p < '0' || *p > '1') { + if (*p) + error(-1, "%s: invalid IDE target `%c'", name, *p); + else + error(-1, "%s: missing IDE target", name); + return(-1); + } + target = *p++ - '0'; + lun = 0; + } else { + char *b; + + if (*p == 'a') { + bus = ACSI; + b = "ACSI"; + } else if (*p == 's') { + bus = SCSI; + b = "SCSI"; + } else { + error(-1, "%s: invalid DISK argument", name); + return(-1); + } + if (*++p < '0' || *p > '7') { + if (*p) + error(-1, "%s: invalid %s target `%c'", name, b, *p); + else + error(-1, "%s: missing %s target", name, b); + return(-1); + } + target = *p++ - '0'; + + if (*p < '0' || *p > '7') { + if (*p) { + error(-1, "%s: invalid %s lun `%c'", name, b, *p); + return(-1); + } + lun = 0; + } else + lun = *p++ - '0'; + } + if (*p) { + error(-1, "%s: invalid DISK argument", name); + return(-1); + } + dd->major = MAJOR(bus, target, lun); + dd->minor = MINOR(bus, target, lun); + return(0); +} + +static int +setnames(dd) + disk_t *dd; +{ + char sn[16], us[16], ls[16], *bs; + int b, u, l; + + b = BUS(dd->major, dd->minor); + u = TARGET(dd->major, dd->minor); + l = LUN(dd->major, dd->minor); + + switch (b) { + case IDE: bs = "IDE"; + break; + case ACSI: bs = "ACSI"; + break; + case SCSI: bs = "SCSI"; + break; + default: error(-1, "invalid bus no. %d", b); + return(-1); + } + + if (u < 0 || u > 7 || (b == IDE && u > 1)) { + error(-1, "invalid %s target `%d'", bs, u); + return(-1); + } + sprintf(us, " target %d", u); + + if (l < 0 || l > 7 || (b == IDE && l > 0)) { + error(-1, "invalid %s lun `%d'", bs, l); + return(-1); + } + if (b == IDE) { + sprintf(sn, "i%d", u); + ls[0] = '\0'; + } else { + sprintf(sn, "%c%d%d", tolower(*bs), u, l); + sprintf(ls, " lun %d", l); + } + + dd->fname = strbd(bs, us, ls, NULL); + dd->sname = strbd(sn, NULL); + return(0); +} + +static int +setsizes(dd) + disk_t *dd; +{ + if (XHGetVersion() != -1) { + char *p, prod[1024]; + + if (XHInqTarget2(dd->major, dd->minor, &dd->bsize, NULL, prod, sizeof(prod))) { + if (XHInqTarget(dd->major, dd->minor, &dd->bsize, NULL, prod)) { + error(-1, "%s: device not configured", dd->sname); + return(-1); + } + } + p = strrchr(prod, '\0'); + while (isspace(*--p)) + *p = '\0'; + dd->product = strbd(prod, NULL); + if (!XHGetCapacity(dd->major, dd->minor, &dd->msize, &dd->bsize)) + return(0); + } else { + dd->product = strbd("unknown", NULL); + dd->bsize = AHDI_BSIZE; /* XXX */ + } + + /* Trial&error search for last sector on medium */ + { + u_int u, l, m; + void *p, (*oldvec)(); + + /* turn off etv_critic handler */ + oldvec = Setexc(257, bios_critic); + + u = (u_int)-2; l = 0; + while (u != l) { + m = l + ((u - l + 1) / 2); + p = disk_read(dd, m, 1); + free(p); + if (p == NULL) + u = m - 1; + else + l = m; + } + + /* turn on etv_critic handler */ + (void)Setexc(257, oldvec); + + if (l) { + dd->msize = l + 1; + return(0); + } + error(-1, "%s: device not configured", dd->sname); + return(-1); + } +} + +char * +strbd(string1) + char *string1; +{ + char *p, *result; + size_t length = 1; + va_list ap; + + va_start(ap, string1); + for (p = string1; p; p = va_arg(ap, char *)) + length += strlen(p); + va_end(ap); + + *(result = xmalloc(length)) = '\0'; + + va_start(ap, string1); + for (p = string1; p; p = va_arg(ap, char *)) + strcat(result, p); + va_end(ap); + + return(result); +} diff --git a/sys/arch/atari/stand/tostools/aptck/disklabel.c b/sys/arch/atari/stand/tostools/aptck/disklabel.c new file mode 100644 index 00000000000..e30b49b192b --- /dev/null +++ b/sys/arch/atari/stand/tostools/aptck/disklabel.c @@ -0,0 +1,343 @@ +/* $NetBSD: disklabel.c,v 1.1.1.1 1996/01/07 21:54:16 leo Exp $ */ + +/* + * Copyright (c) 1995 Waldi Ravens. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Waldi Ravens. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "libtos.h" +#include "aptck.h" +#include "disklabel.h" + +static int dkcksum PROTO((struct disklabel *)); +static int bsd_label PROTO((disk_t *, u_int)); +static int ahdi_label PROTO((disk_t *)); +static int ahdi_display PROTO((disk_t *)); +static u_int ahdi_getparts PROTO((disk_t *, u_int, u_int)); + +int +readdisklabel(dd) + disk_t *dd; +{ + int e; + + printf("Device : %s (%s) [%s]\n", dd->sname, dd->fname, dd->product); + printf("Medium size: %lu sectors\n", (u_long)dd->msize); + printf("Sector size: %lu bytes\n\n", (u_long)dd->bsize); + + e = bsd_label(dd, LABELSECTOR); + if (e < 0) { + printf("Device I/O error (hardware problem?)\n\n"); + return(-1); + } + if (!e) { + printf("NetBSD/Atari format, boot block: " + "sector %u labeloffset %u\n\n", + dd->bblock, dd->lblofs); + return(0); + } + + e = ahdi_label(dd); + if (e < 0) { + printf("Device I/O error (hardware problem?)\n\n"); + return(-1); + } + if (!e) { + printf("AHDI format, NetBSD boot block: "); + if (dd->bblock != NO_BOOT_BLOCK) + printf("sector %u labeloffset %u\n\n", + dd->bblock, dd->lblofs); + else printf("none\n\n"); + return(0); + } + + printf("Unknown label format.\n\n"); + return(-1); +} + +static int +bsd_label(dd, offset) + disk_t *dd; + u_int offset; +{ + u_char *bblk; + u_int nsec; + int rv; + + nsec = (BBSIZE + (dd->bsize - 1)) / dd->bsize; + bblk = disk_read(dd, offset, nsec); + if (bblk) { + u_short *end, *p; + + end = (u_short *)&bblk[BBSIZE - sizeof(struct disklabel)]; + rv = 1; + for (p = (u_short *)bblk; p < end; ++p) { + struct disklabel *dl = (struct disklabel *)p; + if (dl->d_magic == DISKMAGIC && dl->d_magic2 == DISKMAGIC + && dl->d_npartitions <= MAXPARTITIONS && !dkcksum(dl)) { + dd->lblofs = (u_char *)p - bblk; + dd->bblock = offset; + rv = 0; + break; + } + } + free(bblk); + } + else rv = -1; + + return(rv); +} + +static int +dkcksum(dl) + struct disklabel *dl; +{ + u_short *start, *end, sum = 0; + + start = (u_short *)dl; + end = (u_short *)&dl->d_partitions[dl->d_npartitions]; + while (start < end) + sum ^= *start++; + return(sum); +} + +int +ahdi_label(dd) + disk_t *dd; +{ + u_int i; + int e; + + /* + * The AHDI format requires a specific block size. + */ + if (dd->bsize != AHDI_BSIZE) + return(1); + + /* + * Fetch the AHDI partition descriptors. + */ + i = ahdi_getparts(dd, AHDI_BBLOCK, AHDI_BBLOCK); + if (i) { + if (i < dd->msize) + return(-1); /* disk read error */ + else return(1); /* reading past end of medium */ + } + + /* + * Display and perform sanity checks. + */ + i = ahdi_display(dd); + if (i) + return(i); + + /* + * Search for a NetBSD disk label + */ + dd->bblock = NO_BOOT_BLOCK; + for (i = 0; i < dd->nparts; ++i) { + part_t *pd = &dd->parts[i]; + u_int id = *((u_int32_t *)&pd->id) >> 8; + if (id == AHDI_PID_NBD || id == AHDI_PID_RAW) { + u_int offs = pd->start; + if ((e = bsd_label(dd, offs)) < 0) { + return(e); /* I/O error */ + } + if (!e) { + dd->bblock = offs; /* got it */ + return(0); + } + if (id == AHDI_PID_NBD && dd->bblock == NO_BOOT_BLOCK) + dd->bblock = offs; + } + } + return(0); +} + +static int +root_cmp(x1, x2) + const void *x1, *x2; +{ + const u_int *r1 = x1, + *r2 = x2; + + if (*r1 < *r2) + return(-1); + if (*r1 > *r2) + return(1); + return(0); +} + +static int +part_cmp(x1, x2) + const void *x1, *x2; +{ + const part_t *p1 = x1, + *p2 = x2; + + if (p1->start < p2->start) + return(-1); + if (p1->start > p2->start) + return(1); + if (p1->end < p2->end) + return(-1); + if (p1->end > p2->end) + return(1); + if (p1->rsec < p2->rsec) + return(-1); + if (p1->rsec > p2->rsec) + return(1); + if (p1->rent < p2->rent) + return(-1); + if (p1->rent > p2->rent) + return(1); + return(0); +} + +static int +ahdi_display(dd) + disk_t *dd; +{ + int i, j, rv = 0; + + printf("Start of bad sector list : %u\n", dd->bslst); + if (dd->bslst == 0) { + printf("* Illegal value (zero) *\n"); rv = 1; + } + printf("End of bad sector list : %u\n", dd->bslend); + if (dd->bslend == 0) { + printf("* Illegal value (zero) *\n"); rv = 1; + } + printf("Medium size (in root sec): %u\n", dd->hdsize); + if (dd->hdsize == 0) { + printf("* Illegal value (zero) *\n"); rv = 1; + } + + qsort(dd->roots, dd->nroots, sizeof *dd->roots, root_cmp); + qsort(dd->parts, dd->nparts, sizeof *dd->parts, part_cmp); + printf("\n root desc id start end MBs\n"); + + for (i = 0; i < dd->nparts; ++i) { + part_t *p1 = &dd->parts[i]; + u_int megs = p1->end - p1->start + 1, + blpm = (1024 * 1024) / dd->bsize; + megs = (megs + (blpm >> 1)) / blpm; + printf("%8u %4u %s %8u %8u (%3u)\n", + p1->rsec, p1->rent, p1->id, + p1->start, p1->end, megs); + for (j = 0; j < dd->nroots; ++j) { + u_int aux = dd->roots[j]; + if (aux >= p1->start && aux <= p1->end) { + printf("FATAL: auxilary root at %u\n", aux); rv = 1; + } + } + for (j = i; j--;) { + part_t *p2 = &dd->parts[j]; + if (p1->start >= p2->start && p1->start <= p2->end) { + printf("FATAL: clash with %u/%u\n", p2->rsec, p2->rent); rv = 1; + } + if (p2->start >= p1->start && p2->start <= p1->end) { + printf("FATAL: clash with %u/%u\n", p2->rsec, p2->rent); rv = 1; + } + } + if (p1->start >= dd->bslst && p1->start <= dd->bslend) { + printf("FATAL: partition overlaps with bad sector list\n"); rv = 1; + } + if (dd->bslst >= p1->start && dd->bslst <= p1->end) { + printf("FATAL: partition overlaps with bad sector list\n"); rv = 1; + } + } + + printf("\nTotal number of auxilary roots: %u\n", dd->nroots); + printf("Total number of partitions : %u\n", dd->nparts); + if (dd->nparts == 0) { + printf("* Weird # of partitions (zero) *\n"); rv = 1; + } + if (dd->nparts > AHDI_MAXPARTS) { + printf("* Too many AHDI partitions for NetBSD *\n"); + printf(" Increase MAXAUXROOTS in machine/disklabel.h,\n"); + printf(" then recompile the NetBSD kernel.\n"); + rv = -1; + } + return(rv); +} + +static u_int +ahdi_getparts(dd, rsec, esec) + disk_t *dd; + u_int rsec, + esec; +{ + struct ahdi_part *part, *end; + struct ahdi_root *root; + u_int rv; + + root = disk_read(dd, rsec, 1); + if (!root) { + rv = rsec + (rsec == 0); + goto done; + } + + if (rsec == AHDI_BBLOCK) + end = &root->ar_parts[AHDI_MAXRPD]; + else end = &root->ar_parts[AHDI_MAXARPD]; + for (part = root->ar_parts; part < end; ++part) { + u_int id = *((u_int32_t *)&part->ap_flg); + if (!(id & 0x01000000)) + continue; + if ((id &= 0x00ffffff) == AHDI_PID_XGM) { + u_int offs = part->ap_offs + esec; + u_int i = ++dd->nroots; + dd->roots = xrealloc(dd->roots, i * sizeof *dd->roots); + dd->roots[--i] = offs; + rv = ahdi_getparts(dd, offs, esec == AHDI_BBLOCK ? offs : esec); + if (rv) + goto done; + } else { + part_t *p; + u_int i = ++dd->nparts; + dd->parts = xrealloc(dd->parts, i * sizeof *dd->parts); + p = &dd->parts[--i]; + *((u_int32_t *)&p->id) = id << 8; + p->start = part->ap_offs + rsec; + p->end = p->start + part->ap_size - 1; + p->rsec = rsec; + p->rent = part - root->ar_parts; + } + } + dd->hdsize = root->ar_hdsize; + dd->bslst = root->ar_bslst; + dd->bslend = root->ar_bslst + root->ar_bslsize - 1; + rv = 0; +done: + free(root); + return(rv); +} diff --git a/sys/arch/atari/stand/tostools/aptck/disklabel.h b/sys/arch/atari/stand/tostools/aptck/disklabel.h new file mode 100644 index 00000000000..6b3c004180e --- /dev/null +++ b/sys/arch/atari/stand/tostools/aptck/disklabel.h @@ -0,0 +1,203 @@ +/* $NetBSD: disklabel.h,v 1.1.1.1 1996/01/07 21:54:16 leo Exp $ */ + +/* + * Copyright (c) 1995 Leo Weppelman. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Leo Weppelman. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DISKLABEL_H +#define DISKLABEL_H + +/* + * On a volume, exclusively used by NetBSD, the boot block starts at + * sector 0. To allow shared use of a volume between two or more OS's + * the vendor specific AHDI format is supported. In this case the boot + * block is located at the start of an AHDI partition. In any case the + * size of the boot block is 8KB, the disk label is at offset 7KB. + */ +#define LABELSECTOR 0 /* `natural' start of boot block */ +#define LABELOFFSET (7 * 1024) /* offset of disk label in bytes, + relative to start of boot block */ +#define BBSIZE (8 * 1024) /* size of boot block in bytes */ +#define MAXPARTITIONS 16 /* max. # of NetBSD partitions */ +#define RAW_PART 2 /* xx?c is raw partition */ + +#define NO_BOOT_BLOCK ((u_int) -1) +#define MAXAUXROOTS 60 /* max. # of auxilary root sectors */ + +/***************************************************************************/ + +#define AHDI_BSIZE 512 /* AHDI blocksize */ +#define AHDI_BBLOCK 0 /* AHDI bootblock (root sector) */ +#define AHDI_MAXROOTS (MAXAUXROOTS) /* max. # of AHDI rootsectors */ +#define AHDI_MAXPARTS (AHDI_MAXROOTS+3) /* max. # of AHDI partitions */ + +/* + * Various `well known' AHDI partition identifiers. + */ +#define AHDI_MKPID(x,y,z) ( ((u_int32_t)(x) << 16) \ + | ((u_int32_t)(y) << 8) \ + | ((u_int32_t)(z)) \ + ) +#define AHDI_PID_XGM AHDI_MKPID('X','G','M') +#define AHDI_PID_GEM AHDI_MKPID('G','E','M') +#define AHDI_PID_BGM AHDI_MKPID('B','G','M') +#define AHDI_PID_RAW AHDI_MKPID('R','A','W') +#define AHDI_PID_SWP AHDI_MKPID('S','W','P') +#define AHDI_PID_NBD AHDI_MKPID('N','B','D') +#define AHDI_PID_NBR AHDI_MKPID('N','B','R') +#define AHDI_PID_NBS AHDI_MKPID('N','B','S') +#define AHDI_PID_NBU AHDI_MKPID('N','B','U') + +/* + * Format of AHDI boot block. + */ +#define AHDI_MAXRPD 4 /* max. # of partition descriptors */ + /* in the AHDI bootblock (aka root)*/ +#define AHDI_MAXARPD 2 /* max. # of partition descriptors */ + /* in an AHDI auxilary root sector */ + +struct ahdi_part { + u_int8_t ap_flg; /* bit 0 is in-use flag */ + u_int8_t ap_id[3]; /* id: GEM, BGM, XGM, UNX, MIX */ + u_int32_t ap_offs; /* block where partition starts */ + u_int32_t ap_size; /* partition size in blocks */ +#define ap_end ap_size /* in the in-core copy, store end instead of size */ +}; + +struct ahdi_root { + u_int8_t ar_fill[0x1c2];/* filler, can be boot code */ + u_int32_t ar_hdsize; /* size of entire volume in blocks */ + struct ahdi_part ar_parts[AHDI_MAXRPD]; /* root partition table */ + u_int32_t ar_bslst; /* start of bad-sector list */ + u_int32_t ar_bslsize; /* # of blocks in bad-sector list */ + u_int16_t ar_cksum; +}; + +/***************************************************************************/ + +#define DISKMAGIC ((u_int32_t)0x82564557) /* The disk magic number */ + +struct disklabel { + u_int32_t d_magic; /* the magic number */ + u_int16_t d_type; /* drive type */ + u_int16_t d_subtype; /* controller/d_type specific */ + char d_typename[16]; /* 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. + */ + union { + char un_d_packname[16]; /* pack identifier */ + struct { + char *un_d_boot0; /* primary bootstrap name */ + char *un_d_boot1; /* secondary bootstrap name */ + } un_b; + } d_un; +#define d_packname d_un.un_d_packname +#define d_boot0 d_un.un_b.un_d_boot0 +#define d_boot1 d_un.un_b.un_d_boot1 + + /* disk geometry: */ + u_int32_t d_secsize; /* # of bytes per sector */ + u_int32_t d_nsectors; /* # of data sectors per track */ + u_int32_t d_ntracks; /* # of tracks per cylinder */ + u_int32_t d_ncylinders; /* # of data cylinders per unit */ + u_int32_t d_secpercyl; /* # of data sectors per cylinder */ + u_int32_t d_secperunit; /* # 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. + */ + u_int16_t d_sparespertrack; /* # of spare sectors per track */ + u_int16_t d_sparespercyl; /* # of spare sectors per cylinder */ + /* + * Alternate cylinders include maintenance, replacement, configuration + * description areas, etc. + */ + u_int32_t d_acylinders; /* # 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. + */ + u_int16_t d_rpm; /* rotational speed */ + u_int16_t d_interleave; /* hardware sector interleave */ + u_int16_t d_trackskew; /* sector 0 skew, per track */ + u_int16_t d_cylskew; /* sector 0 skew, per cylinder */ + u_int32_t d_headswitch; /* head switch time, usec */ + u_int32_t d_trkseek; /* track-to-track seek, usec */ + u_int32_t d_flags; /* generic flags */ +#define NDDATA 5 + u_int32_t d_drivedata[NDDATA]; /* drive-type specific information */ +#define NSPARE 5 + u_int32_t d_spare[NSPARE]; /* reserved for future use */ + u_int32_t d_magic2; /* the magic number (again) */ + u_int16_t d_checksum; /* xor of data incl. partitions */ + + /* filesystem and partition information: */ + u_int16_t d_npartitions; /* number of partitions in following */ + u_int32_t d_bbsize; /* size of boot area at sn0, bytes */ + u_int32_t d_sbsize; /* max size of fs superblock, bytes */ + struct partition { /* the partition table */ + u_int32_t p_size; /* number of sectors in partition */ + u_int32_t p_offset; /* starting sector */ + u_int32_t p_fsize; /* filesystem basic fragment size */ + u_int8_t p_fstype; /* filesystem type, see below */ + u_int8_t p_frag; /* filesystem fragments per block */ + union { + u_int16_t cpg; /* UFS: FS cylinders per group */ + u_int16_t sgs; /* LFS: FS segment shift */ + } __partition_u1; +#define p_cpg __partition_u1.cpg +#define p_sgs __partition_u1.sgs + } d_partitions[MAXPARTITIONS]; /* actually may be more */ +}; + +#endif /* DISKLABEL_H */ diff --git a/sys/arch/atari/stand/tostools/aptck/setversion b/sys/arch/atari/stand/tostools/aptck/setversion new file mode 100644 index 00000000000..acfcc8c082c --- /dev/null +++ b/sys/arch/atari/stand/tostools/aptck/setversion @@ -0,0 +1,39 @@ +#!/usr/bin/awk -f +# +# $NetBSD: setversion,v 1.1.1.1 1996/01/07 21:54:17 leo Exp $ +# +function revcmp(r1, r2, n1, n2, a1, a2, n, i) { + n1 = split(r1, a1, "\.") + n2 = split(r2, a2, "\.") + n = (n1 < n2) ? n1 : n2 + + for (i = 1; i <= n; ++i) { + if (a1[i] != a2[i]) + return(a1[i] - a2[i]) + } + if (n1 != n2) + return(n1 - n2) + return(0) +} + +BEGIN { + destfile = ARGV[1] + rev = "0.0" +} + +{ + if (revcmp($4, rev) > 0) + rev = $4 + next file +} + +END { + while ((e = getline 0) { + if (/"\$Revision.*\$"/) + sub("\\\$Revision.*\\\$", "Revision " rev) + print + } + if (e) + exit(1) + exit(0) +}