153 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* 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);
 | |
| }
 | |
| 
 | |
| 
 |