1 /* $NetBSD: md.c,v 1.16 2020/05/29 10:25:06 jmcneill 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 -- shark machine specific routines */ 36 37 #include <stdio.h> 38 #include <curses.h> 39 #include <unistd.h> 40 #include <fcntl.h> 41 #include <util.h> 42 #include <sys/types.h> 43 #include <sys/ioctl.h> 44 #include <sys/param.h> 45 #include <sys/sysctl.h> 46 47 #include "defs.h" 48 #include "md.h" 49 #include "msg_defs.h" 50 #include "menu_defs.h" 51 52 int boardtype = BOARD_TYPE_NORMAL; 53 54 #define SBSA_MODEL_STR "netbsd,generic-acpi" 55 #define RPI_MODEL_STR "raspberrypi," 56 57 void 58 md_init(void) 59 { 60 static const int mib[2] = {CTL_HW, HW_MODEL}; 61 size_t len; 62 char *cpu_model; 63 64 sysctl(mib, 2, NULL, &len, NULL, 0); 65 cpu_model = malloc(len); 66 sysctl(mib, 2, cpu_model, &len, NULL, 0); 67 68 if (strstr(cpu_model, RPI_MODEL_STR) != NULL) 69 /* this is some kind of Raspberry Pi */ 70 boardtype = BOARD_TYPE_RPI; 71 else if (strstr(cpu_model, SBSA_MODEL_STR) != NULL) 72 /* some SBSA compatible machine */ 73 boardtype = BOARD_TYPE_ACPI; 74 else 75 /* unknown, assume u-boot + dtb */ 76 boardtype = BOARD_TYPE_NORMAL; 77 78 free(cpu_model); 79 } 80 81 void 82 md_init_set_status(int flags) 83 { 84 85 /* 86 * we will extract kernel variants piecewise manually 87 * later, just fetch the kernel set, do not unpack it. 88 */ 89 set_noextract_set(SET_KERNEL_1); 90 } 91 92 bool 93 md_get_info(struct install_partition_desc *install) 94 { 95 96 if (pm->no_mbr || pm->no_part) 97 return true; 98 99 if (pm->parts == NULL) { 100 101 const struct disk_partitioning_scheme *ps = 102 select_part_scheme(pm, NULL, true, NULL); 103 104 if (!ps) 105 return false; 106 107 struct disk_partitions *parts = 108 (*ps->create_new_for_disk)(pm->diskdev, 109 0, pm->dlsize, true, NULL); 110 if (!parts) 111 return false; 112 113 pm->parts = parts; 114 if (ps->size_limit > 0 && pm->dlsize > ps->size_limit) 115 pm->dlsize = ps->size_limit; 116 } 117 118 return edit_outer_parts(pm->parts); 119 } 120 121 /* 122 * md back-end code for menu-driven BSD disklabel editor. 123 */ 124 bool 125 md_make_bsd_partitions(struct install_partition_desc *install) 126 { 127 return make_bsd_partitions(install); 128 } 129 130 /* 131 * any additional partition validation 132 */ 133 bool 134 md_check_partitions(struct install_partition_desc *install) 135 { 136 size_t i; 137 138 for (i = 0; i < install->num; i++) 139 if (install->infos[i].fs_type == FS_MSDOS) 140 return true; 141 142 msg_display(MSG_nomsdospart); 143 process_menu(MENU_ok, NULL); 144 145 return false; 146 } 147 148 /* 149 * hook called before writing new disklabel. 150 */ 151 bool 152 md_pre_disklabel(struct install_partition_desc *install, 153 struct disk_partitions *parts) 154 { 155 156 if (parts->parent == NULL) 157 return true; /* no outer partitions */ 158 159 parts = parts->parent; 160 161 msg_display_subst(MSG_dofdisk, 3, parts->disk, 162 msg_string(parts->pscheme->name), 163 msg_string(parts->pscheme->short_name)); 164 165 /* write edited "MBR" onto disk. */ 166 if (!parts->pscheme->write_to_disk(parts)) { 167 msg_display(MSG_wmbrfail); 168 process_menu(MENU_ok, NULL); 169 return false; 170 } 171 return true; 172 } 173 174 /* 175 * hook called after writing disklabel to new target disk. 176 */ 177 bool 178 md_post_disklabel(struct install_partition_desc *install, 179 struct disk_partitions *parts) 180 { 181 return true; 182 } 183 184 /* 185 * hook called after upgrade() or install() has finished setting 186 * up the target disk but immediately before the user is given the 187 * ``disks are now set up'' message. 188 */ 189 int 190 md_post_newfs(struct install_partition_desc *install) 191 { 192 return 0; 193 } 194 195 int 196 evbarm_extract_finalize(int update) 197 { 198 distinfo *dist; 199 char kernelbin[100]; 200 int (*saved_fetch_fn)(const char *); 201 #ifdef _LP64 202 #define EFIBOOT "/usr/mdec/bootaa64.efi" 203 #else 204 #define EFIBOOT "/usr/mdec/bootarm.efi" 205 #endif 206 207 dist = get_set_distinfo(SET_KERNEL_1); 208 if (dist == NULL) 209 return 0; 210 211 saved_fetch_fn = fetch_fn; 212 extract_file_to(dist, false, "/", "./netbsd", false); 213 fetch_fn = NULL; 214 make_target_dir("/boot/EFI/boot"); 215 if (target_file_exists_p(EFIBOOT)) 216 cp_within_target(EFIBOOT, "/boot/EFI/boot", 0); 217 218 if (boardtype == BOARD_TYPE_ACPI) { 219 fetch_fn = saved_fetch_fn; 220 return 0; 221 } 222 if (boardtype == BOARD_TYPE_NORMAL) { 223 extract_file_to(dist, false, "/boot", "./netbsd.ub", false); 224 fetch_fn = saved_fetch_fn; 225 return 0; 226 } 227 if (boardtype == BOARD_TYPE_RPI) { 228 extract_file_to(dist, false, "/boot", "./netbsd.img", false); 229 fetch_fn = saved_fetch_fn; 230 snprintf(kernelbin, 100, "%s/netbsd.img", targetroot_mnt); 231 if (file_exists_p(kernelbin)) { 232 run_program(RUN_DISPLAY, 233 "/bin/cp %s /targetroot/boot/kernel.img", kernelbin); 234 } else { 235 msg_display(MSG_rpikernelmissing); 236 process_menu(MENU_ok, NULL); 237 return 1; 238 } 239 } 240 fetch_fn = saved_fetch_fn; 241 return 0; 242 } 243 244 int 245 md_post_extract(struct install_partition_desc *install) 246 { 247 248 return 0; 249 } 250 251 void 252 md_cleanup_install(struct install_partition_desc *install) 253 { 254 #ifndef DEBUG 255 enable_rc_conf(); 256 add_rc_conf("sshd=YES\n"); 257 add_rc_conf("dhcpcd=YES\n"); 258 #endif 259 } 260 261 int 262 md_pre_update(struct install_partition_desc *install) 263 { 264 return 1; 265 } 266 267 /* Upgrade support */ 268 int 269 md_update(struct install_partition_desc *install) 270 { 271 md_post_newfs(install); 272 return 1; 273 } 274 275 int 276 md_pre_mount(struct install_partition_desc *install, size_t ndx) 277 { 278 return 0; 279 } 280 281 int 282 md_check_mbr(struct disk_partitions *parts, mbr_info_t *mbri, bool quiet) 283 { 284 mbr_info_t *ext; 285 struct mbr_partition *part; 286 int i, hasboot=0; 287 288 for (ext = mbri; ext; ext = ext->extended) { 289 part = ext->mbr.mbr_parts; 290 for (i=0, hasboot=0; i < MBR_PART_COUNT; part++, i++) { 291 if (part->mbrp_type != MBR_PTYPE_FAT16L && 292 part->mbrp_type != MBR_PTYPE_FAT32L) 293 continue; 294 hasboot = 1; 295 break; 296 } 297 } 298 if (!hasboot) { 299 if (quiet) 300 return 2; 301 msg_display(MSG_nomsdospart); 302 return ask_reedit(parts); 303 } 304 305 return 2; 306 } 307 308 bool 309 md_parts_use_wholedisk(struct disk_partitions *parts) 310 { 311 struct disk_part_info boot_part = { 312 .size = boardtype == BOARD_TYPE_NORMAL ? 313 PART_BOOT_LARGE/512 : PART_BOOT/512, 314 .fs_type = PART_BOOT_TYPE, .fs_sub_type = MBR_PTYPE_FAT16L, 315 }; 316 317 return parts_use_wholedisk(parts, 1, &boot_part); 318 } 319 320 /* returns false if no write-back of parts is required */ 321 bool 322 md_mbr_update_check(struct disk_partitions *parts, mbr_info_t *mbri) 323 { 324 return false; 325 } 326 327 #ifdef HAVE_GPT 328 /* 329 * New GPT partitions have been written, update bootloader or remember 330 * data untill needed in md_post_newfs 331 */ 332 bool 333 md_gpt_post_write(struct disk_partitions *parts, part_id root_id, 334 bool root_is_new, part_id efi_id, bool efi_is_new) 335 { 336 return true; 337 } 338 #endif 339 340 void 341 evbarm_part_defaults(struct pm_devs *my_pm, struct part_usage_info *infos, 342 size_t num_usage_infos) 343 { 344 size_t i; 345 346 if (boardtype != BOARD_TYPE_NORMAL) 347 return; 348 349 for (i = 0; i < num_usage_infos; i++) { 350 if (infos[i].fs_type == PART_BOOT_TYPE && 351 infos[i].mount[0] != 0 && 352 strcmp(infos[i].mount, PART_BOOT_MOUNT) == 0) { 353 infos[i].size = PART_BOOT_LARGE; 354 return; 355 } 356 } 357 } 358 359