162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* This utility makes a bootblock suitable for the SRM console/miniloader */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci/* Usage: 562306a36Sopenharmony_ci * mkbb <device> <lxboot> 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Where <device> is the name of the device to install the bootblock on, 862306a36Sopenharmony_ci * and <lxboot> is the name of a bootblock to merge in. This bootblock 962306a36Sopenharmony_ci * contains the offset and size of the bootloader. It must be exactly 1062306a36Sopenharmony_ci * 512 bytes long. 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <fcntl.h> 1462306a36Sopenharmony_ci#include <unistd.h> 1562306a36Sopenharmony_ci#include <stdlib.h> 1662306a36Sopenharmony_ci#include <stdio.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* Minimal definition of disklabel, so we don't have to include 1962306a36Sopenharmony_ci * asm/disklabel.h (confuses make) 2062306a36Sopenharmony_ci */ 2162306a36Sopenharmony_ci#ifndef MAXPARTITIONS 2262306a36Sopenharmony_ci#define MAXPARTITIONS 8 /* max. # of partitions */ 2362306a36Sopenharmony_ci#endif 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#ifndef u8 2662306a36Sopenharmony_ci#define u8 unsigned char 2762306a36Sopenharmony_ci#endif 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#ifndef u16 3062306a36Sopenharmony_ci#define u16 unsigned short 3162306a36Sopenharmony_ci#endif 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#ifndef u32 3462306a36Sopenharmony_ci#define u32 unsigned int 3562306a36Sopenharmony_ci#endif 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistruct disklabel { 3862306a36Sopenharmony_ci u32 d_magic; /* must be DISKLABELMAGIC */ 3962306a36Sopenharmony_ci u16 d_type, d_subtype; 4062306a36Sopenharmony_ci u8 d_typename[16]; 4162306a36Sopenharmony_ci u8 d_packname[16]; 4262306a36Sopenharmony_ci u32 d_secsize; 4362306a36Sopenharmony_ci u32 d_nsectors; 4462306a36Sopenharmony_ci u32 d_ntracks; 4562306a36Sopenharmony_ci u32 d_ncylinders; 4662306a36Sopenharmony_ci u32 d_secpercyl; 4762306a36Sopenharmony_ci u32 d_secprtunit; 4862306a36Sopenharmony_ci u16 d_sparespertrack; 4962306a36Sopenharmony_ci u16 d_sparespercyl; 5062306a36Sopenharmony_ci u32 d_acylinders; 5162306a36Sopenharmony_ci u16 d_rpm, d_interleave, d_trackskew, d_cylskew; 5262306a36Sopenharmony_ci u32 d_headswitch, d_trkseek, d_flags; 5362306a36Sopenharmony_ci u32 d_drivedata[5]; 5462306a36Sopenharmony_ci u32 d_spare[5]; 5562306a36Sopenharmony_ci u32 d_magic2; /* must be DISKLABELMAGIC */ 5662306a36Sopenharmony_ci u16 d_checksum; 5762306a36Sopenharmony_ci u16 d_npartitions; 5862306a36Sopenharmony_ci u32 d_bbsize, d_sbsize; 5962306a36Sopenharmony_ci struct d_partition { 6062306a36Sopenharmony_ci u32 p_size; 6162306a36Sopenharmony_ci u32 p_offset; 6262306a36Sopenharmony_ci u32 p_fsize; 6362306a36Sopenharmony_ci u8 p_fstype; 6462306a36Sopenharmony_ci u8 p_frag; 6562306a36Sopenharmony_ci u16 p_cpg; 6662306a36Sopenharmony_ci } d_partitions[MAXPARTITIONS]; 6762306a36Sopenharmony_ci}; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_citypedef union __bootblock { 7162306a36Sopenharmony_ci struct { 7262306a36Sopenharmony_ci char __pad1[64]; 7362306a36Sopenharmony_ci struct disklabel __label; 7462306a36Sopenharmony_ci } __u1; 7562306a36Sopenharmony_ci struct { 7662306a36Sopenharmony_ci unsigned long __pad2[63]; 7762306a36Sopenharmony_ci unsigned long __checksum; 7862306a36Sopenharmony_ci } __u2; 7962306a36Sopenharmony_ci char bootblock_bytes[512]; 8062306a36Sopenharmony_ci unsigned long bootblock_quadwords[64]; 8162306a36Sopenharmony_ci} bootblock; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci#define bootblock_label __u1.__label 8462306a36Sopenharmony_ci#define bootblock_checksum __u2.__checksum 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ciint main(int argc, char ** argv) 8762306a36Sopenharmony_ci{ 8862306a36Sopenharmony_ci bootblock bootblock_from_disk; 8962306a36Sopenharmony_ci bootblock bootloader_image; 9062306a36Sopenharmony_ci int dev, fd; 9162306a36Sopenharmony_ci int i; 9262306a36Sopenharmony_ci int nread; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci /* Make sure of the arg count */ 9562306a36Sopenharmony_ci if(argc != 3) { 9662306a36Sopenharmony_ci fprintf(stderr, "Usage: %s device lxboot\n", argv[0]); 9762306a36Sopenharmony_ci exit(0); 9862306a36Sopenharmony_ci } 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci /* First, open the device and make sure it's accessible */ 10162306a36Sopenharmony_ci dev = open(argv[1], O_RDWR); 10262306a36Sopenharmony_ci if(dev < 0) { 10362306a36Sopenharmony_ci perror(argv[1]); 10462306a36Sopenharmony_ci exit(0); 10562306a36Sopenharmony_ci } 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci /* Now open the lxboot and make sure it's reasonable */ 10862306a36Sopenharmony_ci fd = open(argv[2], O_RDONLY); 10962306a36Sopenharmony_ci if(fd < 0) { 11062306a36Sopenharmony_ci perror(argv[2]); 11162306a36Sopenharmony_ci close(dev); 11262306a36Sopenharmony_ci exit(0); 11362306a36Sopenharmony_ci } 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci /* Read in the lxboot */ 11662306a36Sopenharmony_ci nread = read(fd, &bootloader_image, sizeof(bootblock)); 11762306a36Sopenharmony_ci if(nread != sizeof(bootblock)) { 11862306a36Sopenharmony_ci perror("lxboot read"); 11962306a36Sopenharmony_ci fprintf(stderr, "expected %zd, got %d\n", sizeof(bootblock), nread); 12062306a36Sopenharmony_ci exit(0); 12162306a36Sopenharmony_ci } 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci /* Read in the bootblock from disk. */ 12462306a36Sopenharmony_ci nread = read(dev, &bootblock_from_disk, sizeof(bootblock)); 12562306a36Sopenharmony_ci if(nread != sizeof(bootblock)) { 12662306a36Sopenharmony_ci perror("bootblock read"); 12762306a36Sopenharmony_ci fprintf(stderr, "expected %zd, got %d\n", sizeof(bootblock), nread); 12862306a36Sopenharmony_ci exit(0); 12962306a36Sopenharmony_ci } 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci /* Swap the bootblock's disklabel into the bootloader */ 13262306a36Sopenharmony_ci bootloader_image.bootblock_label = bootblock_from_disk.bootblock_label; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci /* Calculate the bootblock checksum */ 13562306a36Sopenharmony_ci bootloader_image.bootblock_checksum = 0; 13662306a36Sopenharmony_ci for(i = 0; i < 63; i++) { 13762306a36Sopenharmony_ci bootloader_image.bootblock_checksum += 13862306a36Sopenharmony_ci bootloader_image.bootblock_quadwords[i]; 13962306a36Sopenharmony_ci } 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci /* Write the whole thing out! */ 14262306a36Sopenharmony_ci lseek(dev, 0L, SEEK_SET); 14362306a36Sopenharmony_ci if(write(dev, &bootloader_image, sizeof(bootblock)) != sizeof(bootblock)) { 14462306a36Sopenharmony_ci perror("bootblock write"); 14562306a36Sopenharmony_ci exit(0); 14662306a36Sopenharmony_ci } 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci close(fd); 14962306a36Sopenharmony_ci close(dev); 15062306a36Sopenharmony_ci exit(0); 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci 154