2005-04-16 15:20:36 -07:00
/* 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>
2007-07-31 00:38:11 -07:00
# include <stdlib.h>
2005-04-16 15:20:36 -07:00
# 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
2007-06-01 00:46:36 -07:00
int main ( int argc , char * * argv )
2005-04-16 15:20:36 -07:00
{
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 " ) ;
2007-07-31 00:38:11 -07:00
fprintf ( stderr , " expected %zd, got %d \n " , sizeof ( bootblock ) , nread ) ;
2005-04-16 15:20:36 -07:00
exit ( 0 ) ;
}
/* Read in the bootblock from disk. */
nread = read ( dev , & bootblock_from_disk , sizeof ( bootblock ) ) ;
if ( nread ! = sizeof ( bootblock ) ) {
perror ( " bootblock read " ) ;
2007-07-31 00:38:11 -07:00
fprintf ( stderr , " expected %zd, got %d \n " , sizeof ( bootblock ) , nread ) ;
2005-04-16 15:20:36 -07:00
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 ) ;
}