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 33char *bootldr; 34 35char *blkstore; 36char *ldrstore; 37size_t blksize; 38size_t ldrsize; 39 40void 41md_init(void) 42{ 43 stages = 2; 44 stage1 = "/usr/mdec/bootblk"; 45 stage2 = "/usr/mdec/ofwboot"; 46 47 bootldr = "/ofwboot"; 48} 49 50void 51md_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 92void 93md_prepareboot(int devfd, char *dev) 94{ 95} 96 97void 98md_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