xref: /kernel/linux/linux-6.6/arch/alpha/boot/tools/mkbb.c (revision 62306a36)
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