1 /* $OpenBSD: sparc64_installboot.c,v 1.11 2022/09/05 11:12:20 kn Exp $ */ 2 3 /* 4 * Copyright (c) 2012, 2013 Joel Sing <jsing@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> /* DEV_BSIZE */ 20 #include <sys/stat.h> 21 22 #include <err.h> 23 #include <fcntl.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <unistd.h> 28 29 #include <ufs/ffs/fs.h> 30 31 #include "installboot.h" 32 33 char *bootldr; 34 35 char *blkstore; 36 char *ldrstore; 37 size_t blksize; 38 size_t ldrsize; 39 40 void 41 md_init(void) 42 { 43 stages = 2; 44 stage1 = "/usr/mdec/bootblk"; 45 stage2 = "/usr/mdec/ofwboot"; 46 47 bootldr = "/ofwboot"; 48 } 49 50 void 51 md_loadboot(void) 52 { 53 struct stat sb; 54 size_t blocks; 55 int fd; 56 57 /* Load first-stage boot block. */ 58 if ((fd = open(stage1, O_RDONLY)) == -1) 59 err(1, "open"); 60 if (fstat(fd, &sb) == -1) 61 err(1, "fstat"); 62 blocks = howmany((size_t)sb.st_size, DEV_BSIZE); 63 blksize = blocks * DEV_BSIZE; 64 if (verbose) 65 fprintf(stderr, "boot block is %zu bytes " 66 "(%zu blocks @ %u bytes = %zu bytes)\n", 67 (ssize_t)sb.st_size, blocks, DEV_BSIZE, blksize); 68 if (blksize > SBSIZE - DEV_BSIZE) 69 errx(1, "boot blocks too big (%zu > %d)", 70 blksize, SBSIZE - DEV_BSIZE); 71 blkstore = calloc(1, blksize); 72 if (blkstore == NULL) 73 err(1, "calloc"); 74 if (read(fd, blkstore, sb.st_size) != (ssize_t)sb.st_size) 75 err(1, "read"); 76 close(fd); 77 78 /* Load second-stage boot loader. */ 79 if ((fd = open(stage2, O_RDONLY)) == -1) 80 err(1, "open"); 81 if (fstat(fd, &sb) == -1) 82 err(1, "stat"); 83 ldrsize = sb.st_size; 84 ldrstore = malloc(ldrsize); 85 if (ldrstore == NULL) 86 err(1, "malloc"); 87 if (read(fd, ldrstore, ldrsize) != (ssize_t)sb.st_size) 88 err(1, "read"); 89 close(fd); 90 } 91 92 void 93 md_prepareboot(int devfd, char *dev) 94 { 95 } 96 97 void 98 md_installboot(int devfd, char *dev) 99 { 100 static int prefixed = 0; 101 102 /* XXX - is this necessary? */ 103 sync(); 104 105 /* 106 * sr_install_bootblk() calls md_installboot() for every softraid chunk 107 * but the path must be prefixed only once. 108 */ 109 if (!prefixed++) 110 bootldr = fileprefix(root, bootldr); 111 if (bootldr == NULL) 112 exit(1); 113 if (verbose) 114 fprintf(stderr, "%s %s to %s\n", 115 (nowrite ? "would copy" : "copying"), stage2, bootldr); 116 if (!nowrite) 117 if (filecopy(stage2, bootldr) == -1) 118 exit(1); 119 120 /* Write bootblock into the superblock. */ 121 if (verbose) 122 fprintf(stderr, "%s boot block to disk %s\n", 123 (nowrite ? "would write" : "writing"), dev); 124 if (nowrite) 125 return; 126 if (pwrite(devfd, blkstore, blksize, DEV_BSIZE) != (ssize_t)blksize) 127 err(1, "pwrite"); 128 } 129