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