Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | // SPDX-License-Identifier: GPL-2.0 /* This utility makes a bootblock suitable for the SRM console/miniloader */ /* Usage: * mkbb <device> <lxboot> * * Where <device> is the name of the device to install the bootblock on, * and <lxboot> is the name of a bootblock to merge in. This bootblock * contains the offset and size of the bootloader. It must be exactly * 512 bytes long. */ #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> /* Minimal definition of disklabel, so we don't have to include * asm/disklabel.h (confuses make) */ #ifndef MAXPARTITIONS #define MAXPARTITIONS 8 /* max. # of partitions */ #endif #ifndef u8 #define u8 unsigned char #endif #ifndef u16 #define u16 unsigned short #endif #ifndef u32 #define u32 unsigned int #endif struct disklabel { u32 d_magic; /* must be DISKLABELMAGIC */ u16 d_type, d_subtype; u8 d_typename[16]; u8 d_packname[16]; u32 d_secsize; u32 d_nsectors; u32 d_ntracks; u32 d_ncylinders; u32 d_secpercyl; u32 d_secprtunit; u16 d_sparespertrack; u16 d_sparespercyl; u32 d_acylinders; u16 d_rpm, d_interleave, d_trackskew, d_cylskew; u32 d_headswitch, d_trkseek, d_flags; u32 d_drivedata[5]; u32 d_spare[5]; u32 d_magic2; /* must be DISKLABELMAGIC */ u16 d_checksum; u16 d_npartitions; u32 d_bbsize, d_sbsize; struct d_partition { u32 p_size; u32 p_offset; u32 p_fsize; u8 p_fstype; u8 p_frag; u16 p_cpg; } d_partitions[MAXPARTITIONS]; }; typedef union __bootblock { struct { char __pad1[64]; struct disklabel __label; } __u1; struct { unsigned long __pad2[63]; unsigned long __checksum; } __u2; char bootblock_bytes[512]; unsigned long bootblock_quadwords[64]; } bootblock; #define bootblock_label __u1.__label #define bootblock_checksum __u2.__checksum int main(int argc, char ** argv) { bootblock bootblock_from_disk; bootblock bootloader_image; int dev, fd; int i; int nread; /* Make sure of the arg count */ if(argc != 3) { fprintf(stderr, "Usage: %s device lxboot\n", argv[0]); exit(0); } /* First, open the device and make sure it's accessible */ dev = open(argv[1], O_RDWR); if(dev < 0) { perror(argv[1]); exit(0); } /* Now open the lxboot and make sure it's reasonable */ fd = open(argv[2], O_RDONLY); if(fd < 0) { perror(argv[2]); close(dev); exit(0); } /* Read in the lxboot */ nread = read(fd, &bootloader_image, sizeof(bootblock)); if(nread != sizeof(bootblock)) { perror("lxboot read"); fprintf(stderr, "expected %zd, got %d\n", sizeof(bootblock), nread); exit(0); } /* Read in the bootblock from disk. */ nread = read(dev, &bootblock_from_disk, sizeof(bootblock)); if(nread != sizeof(bootblock)) { perror("bootblock read"); fprintf(stderr, "expected %zd, got %d\n", sizeof(bootblock), nread); exit(0); } /* Swap the bootblock's disklabel into the bootloader */ bootloader_image.bootblock_label = bootblock_from_disk.bootblock_label; /* Calculate the bootblock checksum */ bootloader_image.bootblock_checksum = 0; for(i = 0; i < 63; i++) { bootloader_image.bootblock_checksum += bootloader_image.bootblock_quadwords[i]; } /* Write the whole thing out! */ lseek(dev, 0L, SEEK_SET); if(write(dev, &bootloader_image, sizeof(bootblock)) != sizeof(bootblock)) { perror("bootblock write"); exit(0); } close(fd); close(dev); exit(0); } |