1 /* $NetBSD: md.c,v 1.2 2014/08/03 16:09:40 martin Exp $ */ 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 -- prep machine specific routines */ 36 37 #include <sys/param.h> 38 #include <sys/sysctl.h> 39 #include <stdio.h> 40 #include <util.h> 41 #include <machine/cpu.h> 42 43 #include "defs.h" 44 #include "md.h" 45 #include "msg_defs.h" 46 #include "menu_defs.h" 47 #include "endian.h" 48 49 int prep_nobootfix = 0, prep_rawdevfix = 0, prep_bootpart = PART_BOOT; 50 51 void 52 md_init(void) 53 { 54 } 55 56 void 57 md_init_set_status(int flags) 58 { 59 (void)flags; 60 } 61 62 int 63 md_get_info(void) 64 { 65 return set_bios_geom_with_mbr_guess(); 66 } 67 68 /* 69 * md back-end code for menu-driven BSD disklabel editor. 70 */ 71 int 72 md_make_bsd_partitions(void) 73 { 74 return make_bsd_partitions(); 75 } 76 77 /* 78 * any additional partition validation 79 */ 80 int 81 md_check_partitions(void) 82 { 83 int part; 84 85 /* we need to find a boot partition, otherwise we can't write our 86 * "bootblock". We make the assumption that the user hasn't done 87 * something stupid, like move it away from the MBR partition. 88 */ 89 for (part = PART_A; part < MAXPARTITIONS; part++) 90 if (pm->bsdlabel[part].pi_fstype == FS_BOOT) { 91 prep_bootpart = part; 92 return 1; 93 } 94 95 msg_display(MSG_prepnobootpart); 96 process_menu(MENU_ok, NULL); 97 return 0; 98 } 99 100 /* 101 * hook called before writing new disklabel. 102 */ 103 int 104 md_pre_disklabel(void) 105 { 106 msg_display(MSG_dofdisk); 107 108 /* write edited MBR onto disk. */ 109 if (write_mbr(pm->diskdev, &mbr, 1) != 0) { 110 msg_display(MSG_wmbrfail); 111 process_menu(MENU_ok, NULL); 112 return 1; 113 } 114 return 0; 115 } 116 117 /* 118 * hook called after writing disklabel to new target disk. 119 */ 120 int 121 md_post_disklabel(void) 122 { 123 return 0; 124 } 125 126 /* 127 * hook called after upgrade() or install() has finished setting 128 * up the target disk but immediately before the user is given the 129 * ``disks are now set up'' message. 130 */ 131 int 132 md_post_newfs(void) 133 { 134 return 0; 135 } 136 137 int 138 md_post_extract(void) 139 { 140 char rawdev[100], bootpart[100], bootloader[100]; 141 142 /* if we can't make it bootable, just punt */ 143 if (prep_nobootfix) 144 return 0; 145 146 process_menu(MENU_prepconsole, NULL); 147 if (yesno == 1) 148 snprintf(bootloader, 100, "/usr/mdec/boot_com0"); 149 else 150 snprintf(bootloader, 100, "/usr/mdec/boot"); 151 152 snprintf(rawdev, 100, "/dev/r%s%c", pm->diskdev, 'a' + getrawpartition()); 153 snprintf(bootpart, 100, "/dev/r%s%c", pm->diskdev, 'a' + prep_bootpart); 154 if (prep_rawdevfix) 155 run_program(RUN_DISPLAY|RUN_CHROOT, 156 "/usr/mdec/mkbootimage -b %s -k /netbsd " 157 "-r %s /.bootimage", bootloader, rawdev); 158 else 159 run_program(RUN_DISPLAY|RUN_CHROOT, 160 "/usr/mdec/mkbootimage -s -b %s -k /netbsd /.bootimage", 161 bootloader); 162 run_program(RUN_DISPLAY|RUN_CHROOT, "/bin/dd if=/.bootimage of=%s " 163 "bs=512 conv=sync", bootpart); 164 165 return 0; 166 } 167 168 void 169 md_cleanup_install(void) 170 { 171 #ifndef DEBUG 172 enable_rc_conf(); 173 #endif 174 run_program(0, "rm -f %s", target_expand("/.bootimage")); 175 } 176 177 int 178 md_pre_update(void) 179 { 180 struct mbr_partition *part; 181 mbr_info_t *ext; 182 int i; 183 184 read_mbr(pm->diskdev, &mbr); 185 /* do a sanity check of the partition table */ 186 for (ext = &mbr; ext; ext = ext->extended) { 187 part = ext->mbr.mbr_parts; 188 for (i = 0; i < MBR_PART_COUNT; part++, i++) { 189 if (part->mbrp_type != MBR_PTYPE_PREP) 190 continue; 191 if (part->mbrp_size < (MIN_PREP_BOOT/512)) { 192 msg_display(MSG_preptoosmall); 193 msg_display_add(MSG_prepnobootpart, 0); 194 process_menu(MENU_yesno, NULL); 195 if (!yesno) 196 return 0; 197 prep_nobootfix = 1; 198 } 199 if (part->mbrp_start == 0) 200 prep_rawdevfix = 1; 201 } 202 } 203 if (md_check_partitions() == 0) 204 prep_nobootfix = 1; 205 return 1; 206 } 207 208 /* Upgrade support */ 209 int 210 md_update(void) 211 { 212 md_post_newfs(); 213 return 1; 214 } 215 216 int 217 md_check_mbr(mbr_info_t *mbri) 218 { 219 mbr_info_t *ext; 220 struct mbr_partition *part; 221 int i; 222 223 for (ext = mbri; ext; ext = ext->extended) { 224 part = ext->mbr.mbr_parts; 225 for (i = 0; i < MBR_PART_COUNT; part++, i++) { 226 if (part->mbrp_type != MBR_PTYPE_PREP) 227 continue; 228 pm->bootstart = part->mbrp_start; 229 pm->bootsize = part->mbrp_size; 230 break; 231 } 232 } 233 if (pm->bootsize < (MIN_PREP_BOOT/512)) { 234 msg_display(MSG_preptoosmall); 235 msg_display_add(MSG_reeditpart, 0); 236 process_menu(MENU_yesno, NULL); 237 if (!yesno) 238 return 0; 239 return 1; 240 } 241 if (pm->bootstart == 0 || pm->bootsize == 0) { 242 msg_display(MSG_nopreppart); 243 msg_display_add(MSG_reeditpart, 0); 244 process_menu(MENU_yesno, NULL); 245 if (!yesno) 246 return 0; 247 return 1; 248 } 249 return 2; 250 } 251 252 int 253 md_mbr_use_wholedisk(mbr_info_t *mbri) 254 { 255 struct mbr_sector *mbrs = &mbri->mbr; 256 mbr_info_t *ext; 257 struct mbr_partition *part; 258 259 part = &mbrs->mbr_parts[0]; 260 /* Set the partition information for full disk usage. */ 261 while ((ext = mbri->extended)) { 262 mbri->extended = ext->extended; 263 free(ext); 264 } 265 memset(part, 0, MBR_PART_COUNT * sizeof *part); 266 #ifdef BOOTSEL 267 memset(&mbri->mbrb, 0, sizeof mbri->mbrb); 268 #endif 269 part[0].mbrp_type = MBR_PTYPE_PREP; 270 part[0].mbrp_size = PREP_BOOT_SIZE/512; 271 part[0].mbrp_start = bsec; 272 part[0].mbrp_flag = MBR_PFLAG_ACTIVE; 273 274 part[1].mbrp_type = MBR_PTYPE_NETBSD; 275 part[1].mbrp_size = pm->dlsize - (bsec + PREP_BOOT_SIZE/512); 276 part[1].mbrp_start = bsec + PREP_BOOT_SIZE/512; 277 part[1].mbrp_flag = 0; 278 279 pm->ptstart = part[1].mbrp_start; 280 pm->ptsize = part[1].mbrp_size; 281 pm->bootstart = part[0].mbrp_start; 282 pm->bootsize = part[0].mbrp_size; 283 return 1; 284 } 285 286 287 int 288 md_pre_mount() 289 { 290 return 0; 291 } 292