[BACK]Return to md.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.sbin / sysinst / arch / i386

Annotation of src/usr.sbin/sysinst/arch/i386/md.c, Revision 1.10

1.10    ! martin      1: /*     $NetBSD: md.c,v 1.9 2018/06/03 13:16:30 martin Exp $ */
1.1       dholland    2:
                      3: /*
                      4:  * Copyright 1997 Piermont Information Systems Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Based on code written by Philip A. Nelson for Piermont Information
                      8:  * Systems Inc.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     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. The name of Piermont Information Systems Inc. may not be used to endorse
                     19:  *    or promote products derived from this software without specific prior
                     20:  *    written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
                     23:  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
                     26:  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     27:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     28:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     29:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     30:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     31:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
                     32:  * THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
                     35: /* md.c -- i386 machine specific routines - also used by amd64 */
                     36:
                     37: #include <sys/param.h>
                     38: #include <sys/sysctl.h>
                     39: #include <sys/exec.h>
                     40: #include <sys/utsname.h>
                     41: #include <sys/types.h>
                     42: #include <sys/stat.h>
                     43: #include <machine/cpu.h>
                     44: #include <stdio.h>
                     45: #include <stddef.h>
                     46: #include <util.h>
                     47: #include <dirent.h>
                     48: #include <termios.h>
                     49:
                     50: #include "defs.h"
                     51: #include "md.h"
                     52: #include "endian.h"
                     53: #include "msg_defs.h"
                     54: #include "menu_defs.h"
                     55:
                     56: #ifdef NO_LBA_READS            /* for testing */
                     57: #undef BIFLAG_EXTINT13
                     58: #define BIFLAG_EXTINT13        0
                     59: #endif
                     60:
                     61: static struct biosdisk_info *biosdisk = NULL;
                     62:
                     63: /* prototypes */
                     64:
                     65: static int get_bios_info(char *);
                     66: static int mbr_root_above_chs(void);
                     67: static void md_upgrade_mbrtype(void);
                     68: static int md_read_bootcode(const char *, struct mbr_sector *);
                     69: static unsigned int get_bootmodel(void);
                     70:
                     71: void
                     72: md_init(void)
                     73: {
                     74: }
                     75:
                     76: void
                     77: md_init_set_status(int flags)
                     78: {
                     79:        (void)flags;
                     80:
                     81:        /* Default to install same type of kernel as we are running */
                     82:        set_kernel_set(get_bootmodel());
                     83: }
                     84:
                     85: int
                     86: md_get_info(void)
                     87: {
                     88:        mbr_info_t *ext;
                     89:        struct mbr_partition *p;
                     90:        const char *bootcode;
                     91:        int i;
                     92:        int names, fl, ofl;
                     93: #define        ACTIVE_FOUND    0x0100
                     94: #define        NETBSD_ACTIVE   0x0200
                     95: #define        NETBSD_NAMED    0x0400
                     96: #define        ACTIVE_NAMED    0x0800
                     97:
1.2       martin     98:        if (pm->no_mbr)
1.1       dholland   99:                return 1;
                    100:
1.2       martin    101:        if (read_mbr(pm->diskdev, &mbr) < 0)
1.1       dholland  102:                memset(&mbr.mbr, 0, sizeof mbr.mbr - 2);
1.2       martin    103:        get_bios_info(pm->diskdev);
1.1       dholland  104:
                    105: edit:
                    106:        if (edit_mbr(&mbr) == 0)
                    107:                return 0;
                    108:
                    109:        root_limit = 0;
                    110:        if (biosdisk != NULL && (biosdisk->bi_flags & BIFLAG_EXTINT13) == 0) {
                    111:                if (mbr_root_above_chs()) {
                    112:                        msg_display(MSG_partabovechs);
1.6       martin    113:                        if (!ask_noyes(NULL))
1.1       dholland  114:                                goto edit;
                    115:                        /* The user is shooting themselves in the foot here...*/
                    116:                } else
                    117:                        root_limit = bcyl * bhead * bsec;
                    118:        }
                    119:
                    120:        /*
1.2       martin    121:         * Ensure the install partition (at sector pm->ptstart) and the active
1.1       dholland  122:         * partition are bootable.
                    123:         * Determine whether the bootselect code is needed.
                    124:         * Note that MBR_BS_NEWMBR is always set, so we ignore it!
                    125:         */
                    126:        fl = 0;
                    127:        names = 0;
                    128:        for (ext = &mbr; ext != NULL; ext = ext->extended) {
                    129:                p = ext->mbr.mbr_parts;
                    130:                for (i = 0; i < MBR_PART_COUNT; p++, i++) {
                    131:                        if (p->mbrp_flag == MBR_PFLAG_ACTIVE) {
                    132:                                fl |= ACTIVE_FOUND;
1.2       martin    133:                            if (ext->sector + p->mbrp_start == pm->ptstart)
1.1       dholland  134:                                fl |= NETBSD_ACTIVE;
                    135:                        }
                    136:                        if (ext->mbrb.mbrbs_nametab[i][0] == 0) {
                    137:                                /* No bootmenu label... */
                    138:                                if (ext->sector == 0)
                    139:                                        continue;
1.2       martin    140:                                if (ext->sector + p->mbrp_start == pm->ptstart)
1.1       dholland  141:                                        /*
                    142:                                         * Have installed into an extended ptn
                    143:                                         * force name & bootsel...
                    144:                                         */
                    145:                                        names++;
                    146:                                continue;
                    147:                        }
                    148:                        /* Partition has a bootmenu label... */
                    149:                        if (ext->sector != 0)
                    150:                                fl |= MBR_BS_EXTLBA;
1.2       martin    151:                        if (ext->sector + p->mbrp_start == pm->ptstart)
1.1       dholland  152:                                fl |= NETBSD_NAMED;
                    153:                        else if (p->mbrp_flag == MBR_PFLAG_ACTIVE)
                    154:                                fl |= ACTIVE_NAMED;
                    155:                        else
                    156:                                names++;
                    157:                }
                    158:        }
                    159:        if (!(fl & ACTIVE_FOUND))
                    160:                fl |= NETBSD_ACTIVE;
                    161:        if (fl & NETBSD_NAMED && fl & NETBSD_ACTIVE)
                    162:                fl |= ACTIVE_NAMED;
                    163:
                    164:        if ((names > 0 || !(fl & NETBSD_ACTIVE)) &&
                    165:            (!(fl & NETBSD_NAMED) || !(fl & ACTIVE_NAMED))) {
                    166:                /*
                    167:                 * There appear to be multiple bootable partitions, but they
                    168:                 * don't all have bootmenu texts.
                    169:                 */
                    170:                msg_display(MSG_missing_bootmenu_text);
1.6       martin    171:                if (ask_yesno(NULL))
1.1       dholland  172:                        goto edit;
                    173:        }
                    174:
                    175:        if ((fl & MBR_BS_EXTLBA) &&
                    176:            (biosdisk == NULL || !(biosdisk->bi_flags & BIFLAG_EXTINT13))) {
                    177:                /* Need unsupported LBA reads to read boot sectors */
                    178:                msg_display(MSG_no_extended_bootmenu);
1.6       martin    179:                if (!ask_noyes(NULL))
1.1       dholland  180:                        goto edit;
                    181:        }
                    182:
                    183:        /* Sort out the name of the mbr code we need */
                    184:        if (names > 0 || fl & (NETBSD_NAMED | ACTIVE_NAMED)) {
                    185:                /* Need bootselect code */
                    186:                fl |= MBR_BS_ACTIVE;
                    187:                bootcode = fl & MBR_BS_EXTLBA ? _PATH_BOOTEXT : _PATH_BOOTSEL;
                    188:        } else
                    189:                bootcode = _PATH_MBR;
                    190:
                    191:        fl &=  MBR_BS_ACTIVE | MBR_BS_EXTLBA;
                    192:
                    193:        /* Look at what is installed */
                    194:        ofl = mbr.mbrb.mbrbs_flags;
                    195:        if (ofl == 0) {
                    196:                /* Check there is some bootcode at all... */
                    197:                if (mbr.mbr.mbr_magic != htole16(MBR_MAGIC) ||
                    198:                    mbr.mbr.mbr_jmpboot[0] == 0 ||
                    199:                    mbr_root_above_chs())
                    200:                        /* Existing won't do, force update */
                    201:                        fl |= MBR_BS_NEWMBR;
                    202:        }
                    203:        ofl = mbr.oflags & (MBR_BS_ACTIVE | MBR_BS_EXTLBA);
                    204:
                    205:        if (fl & ~ofl || (fl == 0 && ofl & MBR_BS_ACTIVE)) {
                    206:                /* Existing boot code isn't the right one... */
                    207:                if (fl & MBR_BS_ACTIVE)
                    208:                        msg_display(MSG_installbootsel);
                    209:                else
                    210:                        msg_display(MSG_installmbr);
                    211:        } else
                    212:                /* Existing code would (probably) be ok */
                    213:                msg_display(MSG_updatembr);
                    214:
1.6       martin    215:        if (!ask_yesno(NULL))
1.1       dholland  216:                /* User doesn't want to update mbr code */
                    217:                return 1;
                    218:
                    219:        if (md_read_bootcode(bootcode, &mbr.mbr) == 0)
                    220:                /* update suceeded - to memory copy */
                    221:                return 1;
                    222:
                    223:        /* This shouldn't happen since the files are in the floppy fs... */
                    224:        msg_display("Can't find %s", bootcode);
1.6       martin    225:        ask_yesno(NULL);
1.1       dholland  226:
                    227:        return 1;
                    228: }
                    229:
                    230: /*
                    231:  * md back-end code for menu-driven BSD disklabel editor.
                    232:  */
                    233: int
                    234: md_make_bsd_partitions(void)
                    235: {
                    236:        return make_bsd_partitions();
                    237: }
                    238:
                    239: /*
                    240:  * any additional partition validation
                    241:  */
                    242: int
                    243: md_check_partitions(void)
                    244: {
                    245:        int rval;
                    246:        char *bootxx;
                    247:
                    248:        /* check we have boot code for the root partition type */
                    249:        bootxx = bootxx_name();
                    250:        rval = access(bootxx, R_OK);
                    251:        free(bootxx);
                    252:        if (rval == 0)
                    253:                return 1;
1.8       joerg     254:        process_menu(MENU_ok, __UNCONST(MSG_No_Bootcode));
1.1       dholland  255:        return 0;
                    256: }
                    257:
                    258: /*
                    259:  * hook called before writing new disklabel.
                    260:  */
                    261: int
                    262: md_pre_disklabel(void)
                    263: {
1.2       martin    264:        if (pm->no_mbr)
1.1       dholland  265:                return 0;
                    266:
                    267:        msg_display(MSG_dofdisk);
                    268:
                    269:        /* write edited MBR onto disk. */
1.2       martin    270:        if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
1.1       dholland  271:                msg_display(MSG_wmbrfail);
                    272:                process_menu(MENU_ok, NULL);
                    273:                return 1;
                    274:        }
                    275:        return 0;
                    276: }
                    277:
                    278: /*
                    279:  * hook called after writing disklabel to new target disk.
                    280:  */
                    281: int
                    282: md_post_disklabel(void)
                    283: {
                    284:        return 0;
                    285: }
                    286:
                    287: /*
                    288:  * hook called after upgrade() or install() has finished setting
                    289:  * up the target disk but immediately before the user is given the
                    290:  * ``disks are now set up'' message.
                    291:  */
                    292: int
                    293: md_post_newfs(void)
                    294: {
                    295:        int ret;
                    296:        size_t len;
1.3       riz       297:        char boot_options[1024];
1.1       dholland  298:        char *bootxx_filename;
                    299:        /*
1.3       riz       300:         * XXX - this code retains a lot of cruft from when we went
                    301:         * to great pains to exclude installboot from the ramdisk
                    302:         * for size reasons and should be rewritten.
1.1       dholland  303:         */
1.3       riz       304:        static const char *consoles[]={
                    305:                "pc", /* CONSDEV_PC */
                    306:                "com0", /* CONSDEV_COM0 */
                    307:                "com1", /* CONSDEV_COM1 */
                    308:                "com2", /* CONSDEV_COM2 */
                    309:                "com3", /* CONSDEV_COM3 */
                    310:                "com0kbd", /* CONSDEV_COM0KBD */
                    311:                "com1kbd", /* CONSDEV_COM1KBD */
                    312:                "com2kbd", /* CONSDEV_COM2KBD */
                    313:                "com3kbd" /* CONSDEV_COM3KBD */ };
1.1       dholland  314:        static struct x86_boot_params boottype =
                    315:                {sizeof boottype, 0, 5, 0, 9600, { '\0' }, "", 0};
                    316:        static int conmib[] = {CTL_MACHDEP, CPU_CONSDEV};
                    317:        struct termios t;
                    318:        dev_t condev;
                    319:
1.10    ! martin    320:        /*
        !           321:         * Get console device, should either be ttyE0 or tty0n.
        !           322:         * Too hard to double check, so just 'know' the device numbers.
        !           323:         */
        !           324:        len = sizeof condev;
        !           325:        if (sysctl(conmib, __arraycount(conmib), &condev, &len, NULL, 0) != -1
        !           326:            && (condev & ~3) == 0x800) {
        !           327:                /* Motherboard serial port */
        !           328:                boottype.bp_consdev = (condev & 3) + 1;
        !           329:                /* Defaulting the baud rate to that of stdin should suffice */
        !           330:                if (tcgetattr(0, &t) != -1)
        !           331:                        boottype.bp_conspeed = t.c_ispeed;
        !           332:
1.9       martin    333:        if (pm == NULL || !pm->no_part) {
                    334:                /*
                    335:                 * Get console device, should either be ttyE0 or tty0n.
                    336:                 * Too hard to double check, so just 'know' the device numbers.
                    337:                 */
                    338:                len = sizeof condev;
                    339:                if (sysctl(conmib, nelem(conmib), &condev, &len, NULL, 0) != -1
                    340:                    && (condev & ~3) == 0x800) {
                    341:                        /* Motherboard serial port */
                    342:                        boottype.bp_consdev = (condev & 3) + 1;
                    343:                        /* Defaulting the baud rate to that of stdin should suffice */
                    344:                        if (tcgetattr(0, &t) != -1)
                    345:                                boottype.bp_conspeed = t.c_ispeed;
                    346:                }
                    347:
                    348:                process_menu(MENU_getboottype, &boottype);
                    349:                msg_display(MSG_dobootblks, pm->diskdev);
                    350:                if (boottype.bp_consdev == ~0u)
                    351:                        /* Use existing bootblocks */
                    352:                        return 0;
1.1       dholland  353:        }
                    354:
                    355:        ret = cp_to_target("/usr/mdec/boot", "/boot");
                    356:        if (ret)
                    357:                return ret;
1.9       martin    358:        if (pm && pm->no_part)
                    359:                return 0;
1.1       dholland  360:
1.9       martin    361:         bootxx_filename = bootxx_name();
                    362:         if (bootxx_filename != NULL) {
1.3       riz       363:                snprintf(boot_options, sizeof boot_options,
                    364:                    "console=%s,speed=%u", consoles[boottype.bp_consdev],
                    365:                    boottype.bp_conspeed);
                    366:                if (pm->isspecial) {
1.7       gson      367:                        ret = run_program(RUN_DISPLAY,
1.3       riz       368:                            "/usr/sbin/installboot -o %s /dev/r%s %s",
                    369:                            boot_options, pm->diskdev, bootxx_filename);
                    370:                } else {
1.7       gson      371:                        ret = run_program(RUN_DISPLAY,
1.3       riz       372:                            "/usr/sbin/installboot -o %s /dev/r%s%c %s",
                    373:                            boot_options, pm->diskdev, 'a' + pm->rootpart,
                    374:                            bootxx_filename);
                    375:                }
                    376:                 free(bootxx_filename);
                    377:         } else
                    378:                 ret = -1;
                    379:
                    380:         if (ret != 0)
                    381:                 process_menu(MENU_ok,
1.8       joerg     382:                     __UNCONST("Warning: disk is probably not bootable"));
1.1       dholland  383:
                    384:        return ret;
                    385: }
                    386:
                    387: int
                    388: md_post_extract(void)
                    389: {
                    390:        return 0;
                    391: }
                    392:
                    393: void
                    394: md_cleanup_install(void)
                    395: {
                    396: #ifndef DEBUG
                    397:        enable_rc_conf();
                    398:        add_rc_conf("wscons=YES\n");
                    399:
                    400: # if defined(__i386__) && defined(SET_KERNEL_TINY)
                    401:        /*
                    402:         * For GENERIC_TINY, do not enable any extra screens or wsmux.
                    403:         * Otherwise, run getty on 4 VTs.
                    404:         */
                    405:        if (get_kernel_set() == SET_KERNEL_TINY)
                    406:                run_program(RUN_CHROOT,
                    407:                             "sed -an -e '/^screen/s/^/#/;/^mux/s/^/#/;"
                    408:                            "H;$!d;g;w /etc/wscons.conf' /etc/wscons.conf");
                    409:        else
                    410: # endif
                    411:                run_program(RUN_CHROOT,
                    412:                            "sed -an -e '/^ttyE[1-9]/s/off/on/;"
                    413:                            "H;$!d;g;w /etc/ttys' /etc/ttys");
                    414:
                    415: #endif
                    416: }
                    417:
                    418: int
                    419: md_pre_update(void)
                    420: {
                    421:        return 1;
                    422: }
                    423:
                    424: /* Upgrade support */
                    425: int
                    426: md_update(void)
                    427: {
                    428:        md_post_newfs();
                    429:        md_upgrade_mbrtype();
                    430:        return 1;
                    431: }
                    432:
                    433: int
                    434: md_check_mbr(mbr_info_t *mbri)
                    435: {
                    436:        return 2;
                    437: }
                    438:
                    439: int
                    440: md_mbr_use_wholedisk(mbr_info_t *mbri)
                    441: {
                    442:        return mbr_use_wholedisk(mbri);
                    443: }
                    444:
                    445: static int
                    446: get_bios_info(char *dev)
                    447: {
                    448:        static struct disklist *disklist = NULL;
                    449:        static int mib[2] = {CTL_MACHDEP, CPU_DISKINFO};
                    450:        int i;
                    451:        size_t len;
                    452:        struct biosdisk_info *bip;
                    453:        struct nativedisk_info *nip = NULL, *nat;
                    454:        int cyl, head;
                    455:        daddr_t sec;
                    456:
                    457:        if (disklist == NULL) {
                    458:                if (sysctl(mib, 2, NULL, &len, NULL, 0) < 0)
                    459:                        goto nogeom;
                    460:                disklist = malloc(len);
                    461:                if (disklist == NULL) {
                    462:                        fprintf(stderr, "Out of memory\n");
                    463:                        return -1;
                    464:                }
                    465:                sysctl(mib, 2, disklist, &len, NULL, 0);
                    466:        }
                    467:
                    468:        for (i = 0; i < disklist->dl_nnativedisks; i++) {
                    469:                nat = &disklist->dl_nativedisks[i];
                    470:                if (!strcmp(dev, nat->ni_devname)) {
                    471:                        nip = nat;
                    472:                        break;
                    473:                }
                    474:        }
                    475:        if (nip == NULL || nip->ni_nmatches == 0) {
                    476: nogeom:
                    477:                if (nip != NULL)
1.2       martin    478:                        msg_display(MSG_nobiosgeom, pm->dlcyl, pm->dlhead, pm->dlsec);
1.1       dholland  479:                if (guess_biosgeom_from_mbr(&mbr, &cyl, &head, &sec) >= 0
                    480:                    && nip != NULL)
                    481:                        msg_display_add(MSG_biosguess, cyl, head, sec);
                    482:                biosdisk = NULL;
                    483:        } else {
                    484:                guess_biosgeom_from_mbr(&mbr, &cyl, &head, &sec);
                    485:                if (nip->ni_nmatches == 1) {
                    486:                        bip = &disklist->dl_biosdisks[nip->ni_biosmatches[0]];
                    487:                        msg_display(MSG_onebiosmatch);
                    488:                        msg_table_add(MSG_onebiosmatch_header);
                    489:                        msg_table_add(MSG_onebiosmatch_row, bip->bi_dev,
                    490:                            bip->bi_cyl, bip->bi_head, bip->bi_sec,
                    491:                            (unsigned)bip->bi_lbasecs,
                    492:                            (unsigned)(bip->bi_lbasecs / (1000000000 / 512)));
                    493:                        msg_display_add(MSG_biosgeom_advise);
                    494:                        biosdisk = bip;
                    495:                        process_menu(MENU_biosonematch, &biosdisk);
                    496:                } else {
                    497:                        msg_display(MSG_biosmultmatch);
                    498:                        msg_table_add(MSG_biosmultmatch_header);
                    499:                        for (i = 0; i < nip->ni_nmatches; i++) {
                    500:                                bip = &disklist->dl_biosdisks[
                    501:                                                        nip->ni_biosmatches[i]];
                    502:                                msg_table_add(MSG_biosmultmatch_row, i,
                    503:                                    bip->bi_dev, bip->bi_cyl, bip->bi_head,
                    504:                                    bip->bi_sec, (unsigned)bip->bi_lbasecs,
                    505:                                    (unsigned)bip->bi_lbasecs/(1000000000/512));
                    506:                        }
                    507:                        process_menu(MENU_biosmultmatch, &i);
                    508:                        if (i == -1)
                    509:                                biosdisk = NULL;
                    510:                        else
                    511:                                biosdisk = &disklist->dl_biosdisks[
                    512:                                                        nip->ni_biosmatches[i]];
                    513:                }
                    514:        }
                    515:        if (biosdisk == NULL) {
                    516:                if (nip != NULL) {
                    517:                        set_bios_geom(cyl, head, sec);
                    518:                } else {
                    519:                        bcyl = cyl;
                    520:                        bhead = head;
                    521:                        bsec = sec;
                    522:                }
                    523:        } else {
                    524:                bcyl = biosdisk->bi_cyl;
                    525:                bhead = biosdisk->bi_head;
                    526:                bsec = biosdisk->bi_sec;
                    527:        }
                    528:        return 0;
                    529: }
                    530:
                    531: static int
                    532: mbr_root_above_chs(void)
                    533: {
1.2       martin    534:        return pm->ptstart + DEFROOTSIZE * (MEG / 512) >= bcyl * bhead * bsec;
1.1       dholland  535: }
                    536:
                    537: static void
                    538: md_upgrade_mbrtype(void)
                    539: {
                    540:        struct mbr_partition *mbrp;
                    541:        int i, netbsdpart = -1, oldbsdpart = -1, oldbsdcount = 0;
                    542:
1.2       martin    543:        if (pm->no_mbr)
1.1       dholland  544:                return;
                    545:
1.2       martin    546:        if (read_mbr(pm->diskdev, &mbr) < 0)
1.1       dholland  547:                return;
                    548:
                    549:        mbrp = &mbr.mbr.mbr_parts[0];
                    550:
                    551:        for (i = 0; i < MBR_PART_COUNT; i++) {
                    552:                if (mbrp[i].mbrp_type == MBR_PTYPE_386BSD) {
                    553:                        oldbsdpart = i;
                    554:                        oldbsdcount++;
                    555:                } else if (mbrp[i].mbrp_type == MBR_PTYPE_NETBSD)
                    556:                        netbsdpart = i;
                    557:        }
                    558:
                    559:        if (netbsdpart == -1 && oldbsdcount == 1) {
                    560:                mbrp[oldbsdpart].mbrp_type = MBR_PTYPE_NETBSD;
1.2       martin    561:                write_mbr(pm->diskdev, &mbr, 0);
1.1       dholland  562:        }
                    563: }
                    564:
                    565: /*
                    566:  * Read MBR code from a file.
                    567:  * The existing partition table and bootselect configuration is kept.
                    568:  */
                    569: static int
                    570: md_read_bootcode(const char *path, struct mbr_sector *mbrs)
                    571: {
                    572:        int fd;
                    573:        struct stat st;
                    574:        size_t len;
                    575:        struct mbr_sector new_mbr;
                    576:        uint32_t dsn;
                    577:
                    578:        fd = open(path, O_RDONLY);
                    579:        if (fd < 0)
                    580:                return -1;
                    581:
                    582:        if (fstat(fd, &st) < 0 || st.st_size != sizeof *mbrs) {
                    583:                close(fd);
                    584:                return -1;
                    585:        }
                    586:
                    587:        if (read(fd, &new_mbr, sizeof new_mbr) != sizeof new_mbr) {
                    588:                close(fd);
                    589:                return -1;
                    590:        }
                    591:        close(fd);
                    592:
                    593:        if (new_mbr.mbr_bootsel_magic != htole16(MBR_BS_MAGIC))
                    594:                return -1;
                    595:
                    596:        if (mbrs->mbr_bootsel_magic == htole16(MBR_BS_MAGIC)) {
                    597:                len = offsetof(struct mbr_sector, mbr_bootsel);
                    598:        } else
                    599:                len = offsetof(struct mbr_sector, mbr_parts);
                    600:
                    601:        /* Preserve the 'drive serial number' - especially for Vista */
                    602:        dsn = mbrs->mbr_dsn;
                    603:        memcpy(mbrs, &new_mbr, len);
                    604:        mbrs->mbr_dsn = dsn;
                    605:
                    606:        /* Keep flags from object file - indicate the properties */
                    607:        mbrs->mbr_bootsel.mbrbs_flags = new_mbr.mbr_bootsel.mbrbs_flags;
                    608:        mbrs->mbr_magic = htole16(MBR_MAGIC);
                    609:
                    610:        return 0;
                    611: }
                    612:
                    613: static unsigned int
                    614: get_bootmodel(void)
                    615: {
                    616: #if defined(__i386__)
                    617:        struct utsname ut;
                    618: #ifdef DEBUG
                    619:        char *envstr;
                    620:
                    621:        envstr = getenv("BOOTMODEL");
                    622:        if (envstr != NULL)
                    623:                return atoi(envstr);
                    624: #endif
                    625:
                    626:        if (uname(&ut) < 0)
                    627:                ut.version[0] = 0;
                    628:
                    629: #if defined(SET_KERNEL_TINY)
                    630:        if (strstr(ut.version, "TINY") != NULL)
                    631:                return SET_KERNEL_TINY;
                    632: #endif
                    633: #if defined(SET_KERNEL_PS2)
                    634:        if (strstr(ut.version, "PS2") != NULL)
                    635:                return SET_KERNEL_PS2;
                    636: #endif
                    637: #endif
                    638:        return SET_KERNEL_GENERIC;
                    639: }
                    640:
                    641:
                    642: int
                    643: md_pre_mount()
                    644: {
                    645:        return 0;
                    646: }

CVSweb <webmaster@jp.NetBSD.org>