1 /* Based on original installboot from MINIX 3.
3 * installboot 3.0 - Make a device bootable Author: Kees J. Bot
6 #if HAVE_NBTOOL_CONFIG_H
7 #include "nbtool_config.h"
19 #include "installboot.h"
21 #define BOOTBLOCK 0 /* Of course */
22 #define BOOT_BLOCK_SIZE 1024
23 #define SIGNATURE 0xAA55 /* Boot block signature. */
24 #define SIGPOS 510 /* Where to put signature word. */
25 #define PARTPOS 446 /* Offset to the partition table in a master
30 static int rawfd
; /* File descriptor to open device. */
31 static const char *rawdev
; /* Name of device. */
34 static void report(const char *label
)
35 /* installboot: label: No such file or directory */
37 fprintf(stderr
, "installboot: %s: %s\n", label
, strerror(errno
));
40 static __dead
void fatal(const char *label
)
46 static void bread(FILE *f
, char *name
, void *buf
, size_t len
)
47 /* Read len bytes. Don't dare return without them. */
49 if (len
> 0 && fread(buf
, len
, 1, f
) != 1) {
50 if (ferror(f
)) fatal(name
);
51 fprintf(stderr
, "installboot: Unexpected EOF on %s\n", name
);
56 static void readblock(off_t blk
, char *buf
, int block_size
)
57 /* For rawfs, so that it can read blocks. */
61 if (lseek(rawfd
, blk
* block_size
, SEEK_SET
) < 0
62 || (n
= read(rawfd
, buf
, block_size
)) < 0
66 fprintf(stderr
, "installboot: Unexpected EOF on %s\n", rawdev
);
71 static void writeblock(off_t blk
, const char *buf
, int block_size
)
72 /* Add a function to write blocks for local use. */
74 if (lseek(rawfd
, blk
* block_size
, SEEK_SET
) < 0
75 || write(rawfd
, buf
, block_size
) < 0
80 /* A temp stub until fdisk is ported to MINIX */
81 void install_master(const char *device
, char *masterboot
, char **guide
)
82 /* Booting a hard disk is a two stage process: The master bootstrap in sector
83 * 0 loads the bootstrap from sector 0 of the active partition which in turn
84 * starts the operating system. This code installs such a master bootstrap
85 * on a hard disk. If guide[0] is non-null then the master bootstrap is
86 * guided into booting a certain device.
91 static char buf
[BOOT_BLOCK_SIZE
];
94 if ((rawfd
= open(rawdev
= device
, O_RDWR
)) < 0) fatal(device
);
96 /* Open the master boot code. */
97 if ((masf
= fopen(masterboot
, "r")) == NULL
) fatal(masterboot
);
101 /* Read the master boot block, patch it, write. */
102 readblock(BOOTBLOCK
, buf
, BOOT_BLOCK_SIZE
);
104 memset(buf
, 0, PARTPOS
);
105 (void) bread(masf
, masterboot
, buf
, size
);
107 /* Install signature. */
108 buf
[SIGPOS
+0]= (SIGNATURE
>> 0) & 0xFF;
109 buf
[SIGPOS
+1]= (SIGNATURE
>> 8) & 0xFF;
111 writeblock(BOOTBLOCK
, buf
, BOOT_BLOCK_SIZE
);
114 int isoption(const char *option
, const char *test
)
115 /* Check if the option argument is equals "test". Also accept -i as short
116 * for -image, and the special case -x for -extract.
119 if (strcmp(option
, test
) == 0) return 1;
120 if (option
[0] != '-' && strlen(option
) != 2) return 0;
121 if (option
[1] == test
[1]) return 1;
122 if (option
[1] == 'x' && test
[1] == 'e') return 1;