18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* This utility makes a bootblock suitable for the SRM console/miniloader */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci/* Usage: 58c2ecf20Sopenharmony_ci * mkbb <device> <lxboot> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Where <device> is the name of the device to install the bootblock on, 88c2ecf20Sopenharmony_ci * and <lxboot> is the name of a bootblock to merge in. This bootblock 98c2ecf20Sopenharmony_ci * contains the offset and size of the bootloader. It must be exactly 108c2ecf20Sopenharmony_ci * 512 bytes long. 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <fcntl.h> 148c2ecf20Sopenharmony_ci#include <unistd.h> 158c2ecf20Sopenharmony_ci#include <stdlib.h> 168c2ecf20Sopenharmony_ci#include <stdio.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci/* Minimal definition of disklabel, so we don't have to include 198c2ecf20Sopenharmony_ci * asm/disklabel.h (confuses make) 208c2ecf20Sopenharmony_ci */ 218c2ecf20Sopenharmony_ci#ifndef MAXPARTITIONS 228c2ecf20Sopenharmony_ci#define MAXPARTITIONS 8 /* max. # of partitions */ 238c2ecf20Sopenharmony_ci#endif 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#ifndef u8 268c2ecf20Sopenharmony_ci#define u8 unsigned char 278c2ecf20Sopenharmony_ci#endif 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#ifndef u16 308c2ecf20Sopenharmony_ci#define u16 unsigned short 318c2ecf20Sopenharmony_ci#endif 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#ifndef u32 348c2ecf20Sopenharmony_ci#define u32 unsigned int 358c2ecf20Sopenharmony_ci#endif 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistruct disklabel { 388c2ecf20Sopenharmony_ci u32 d_magic; /* must be DISKLABELMAGIC */ 398c2ecf20Sopenharmony_ci u16 d_type, d_subtype; 408c2ecf20Sopenharmony_ci u8 d_typename[16]; 418c2ecf20Sopenharmony_ci u8 d_packname[16]; 428c2ecf20Sopenharmony_ci u32 d_secsize; 438c2ecf20Sopenharmony_ci u32 d_nsectors; 448c2ecf20Sopenharmony_ci u32 d_ntracks; 458c2ecf20Sopenharmony_ci u32 d_ncylinders; 468c2ecf20Sopenharmony_ci u32 d_secpercyl; 478c2ecf20Sopenharmony_ci u32 d_secprtunit; 488c2ecf20Sopenharmony_ci u16 d_sparespertrack; 498c2ecf20Sopenharmony_ci u16 d_sparespercyl; 508c2ecf20Sopenharmony_ci u32 d_acylinders; 518c2ecf20Sopenharmony_ci u16 d_rpm, d_interleave, d_trackskew, d_cylskew; 528c2ecf20Sopenharmony_ci u32 d_headswitch, d_trkseek, d_flags; 538c2ecf20Sopenharmony_ci u32 d_drivedata[5]; 548c2ecf20Sopenharmony_ci u32 d_spare[5]; 558c2ecf20Sopenharmony_ci u32 d_magic2; /* must be DISKLABELMAGIC */ 568c2ecf20Sopenharmony_ci u16 d_checksum; 578c2ecf20Sopenharmony_ci u16 d_npartitions; 588c2ecf20Sopenharmony_ci u32 d_bbsize, d_sbsize; 598c2ecf20Sopenharmony_ci struct d_partition { 608c2ecf20Sopenharmony_ci u32 p_size; 618c2ecf20Sopenharmony_ci u32 p_offset; 628c2ecf20Sopenharmony_ci u32 p_fsize; 638c2ecf20Sopenharmony_ci u8 p_fstype; 648c2ecf20Sopenharmony_ci u8 p_frag; 658c2ecf20Sopenharmony_ci u16 p_cpg; 668c2ecf20Sopenharmony_ci } d_partitions[MAXPARTITIONS]; 678c2ecf20Sopenharmony_ci}; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_citypedef union __bootblock { 718c2ecf20Sopenharmony_ci struct { 728c2ecf20Sopenharmony_ci char __pad1[64]; 738c2ecf20Sopenharmony_ci struct disklabel __label; 748c2ecf20Sopenharmony_ci } __u1; 758c2ecf20Sopenharmony_ci struct { 768c2ecf20Sopenharmony_ci unsigned long __pad2[63]; 778c2ecf20Sopenharmony_ci unsigned long __checksum; 788c2ecf20Sopenharmony_ci } __u2; 798c2ecf20Sopenharmony_ci char bootblock_bytes[512]; 808c2ecf20Sopenharmony_ci unsigned long bootblock_quadwords[64]; 818c2ecf20Sopenharmony_ci} bootblock; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#define bootblock_label __u1.__label 848c2ecf20Sopenharmony_ci#define bootblock_checksum __u2.__checksum 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ciint main(int argc, char ** argv) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci bootblock bootblock_from_disk; 898c2ecf20Sopenharmony_ci bootblock bootloader_image; 908c2ecf20Sopenharmony_ci int dev, fd; 918c2ecf20Sopenharmony_ci int i; 928c2ecf20Sopenharmony_ci int nread; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci /* Make sure of the arg count */ 958c2ecf20Sopenharmony_ci if(argc != 3) { 968c2ecf20Sopenharmony_ci fprintf(stderr, "Usage: %s device lxboot\n", argv[0]); 978c2ecf20Sopenharmony_ci exit(0); 988c2ecf20Sopenharmony_ci } 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci /* First, open the device and make sure it's accessible */ 1018c2ecf20Sopenharmony_ci dev = open(argv[1], O_RDWR); 1028c2ecf20Sopenharmony_ci if(dev < 0) { 1038c2ecf20Sopenharmony_ci perror(argv[1]); 1048c2ecf20Sopenharmony_ci exit(0); 1058c2ecf20Sopenharmony_ci } 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci /* Now open the lxboot and make sure it's reasonable */ 1088c2ecf20Sopenharmony_ci fd = open(argv[2], O_RDONLY); 1098c2ecf20Sopenharmony_ci if(fd < 0) { 1108c2ecf20Sopenharmony_ci perror(argv[2]); 1118c2ecf20Sopenharmony_ci close(dev); 1128c2ecf20Sopenharmony_ci exit(0); 1138c2ecf20Sopenharmony_ci } 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci /* Read in the lxboot */ 1168c2ecf20Sopenharmony_ci nread = read(fd, &bootloader_image, sizeof(bootblock)); 1178c2ecf20Sopenharmony_ci if(nread != sizeof(bootblock)) { 1188c2ecf20Sopenharmony_ci perror("lxboot read"); 1198c2ecf20Sopenharmony_ci fprintf(stderr, "expected %zd, got %d\n", sizeof(bootblock), nread); 1208c2ecf20Sopenharmony_ci exit(0); 1218c2ecf20Sopenharmony_ci } 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci /* Read in the bootblock from disk. */ 1248c2ecf20Sopenharmony_ci nread = read(dev, &bootblock_from_disk, sizeof(bootblock)); 1258c2ecf20Sopenharmony_ci if(nread != sizeof(bootblock)) { 1268c2ecf20Sopenharmony_ci perror("bootblock read"); 1278c2ecf20Sopenharmony_ci fprintf(stderr, "expected %zd, got %d\n", sizeof(bootblock), nread); 1288c2ecf20Sopenharmony_ci exit(0); 1298c2ecf20Sopenharmony_ci } 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci /* Swap the bootblock's disklabel into the bootloader */ 1328c2ecf20Sopenharmony_ci bootloader_image.bootblock_label = bootblock_from_disk.bootblock_label; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci /* Calculate the bootblock checksum */ 1358c2ecf20Sopenharmony_ci bootloader_image.bootblock_checksum = 0; 1368c2ecf20Sopenharmony_ci for(i = 0; i < 63; i++) { 1378c2ecf20Sopenharmony_ci bootloader_image.bootblock_checksum += 1388c2ecf20Sopenharmony_ci bootloader_image.bootblock_quadwords[i]; 1398c2ecf20Sopenharmony_ci } 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci /* Write the whole thing out! */ 1428c2ecf20Sopenharmony_ci lseek(dev, 0L, SEEK_SET); 1438c2ecf20Sopenharmony_ci if(write(dev, &bootloader_image, sizeof(bootblock)) != sizeof(bootblock)) { 1448c2ecf20Sopenharmony_ci perror("bootblock write"); 1458c2ecf20Sopenharmony_ci exit(0); 1468c2ecf20Sopenharmony_ci } 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci close(fd); 1498c2ecf20Sopenharmony_ci close(dev); 1508c2ecf20Sopenharmony_ci exit(0); 1518c2ecf20Sopenharmony_ci} 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci 154