struct my_options {
unsigned int sectors;
unsigned int heads;
+ int raid_mode;
} opt = {
.sectors = 0,
.heads = 0,
+ .raid_mode = 0,
};
static void __attribute__((noreturn)) usage(int rv)
" --zip -z Force zipdrive geometry (-H 64 -S 32)\n"
" --sectors=# -S Force the number of sectors per track\n"
" --heads=# -H Force number of heads\n"
+ " --raid -r Fall back to the next device on boot failure\n"
"\n"
" Note: geometry is determined at boot time for devices which\n"
" are considered hard disks by the BIOS. Unfortunately, this is\n"
}
static const struct option long_options[] = {
- { "install", 0, NULL, 'i' },
- { "update", 0, NULL, 'U' },
- { "zipdrive", 0, NULL, 'z' },
- { "sectors", 1, NULL, 'S' },
- { "heads", 1, NULL, 'H' },
- { "version", 0, NULL, 'v' },
- { "help", 0, NULL, 'h' },
+ { "install", 0, NULL, 'i' },
+ { "update", 0, NULL, 'U' },
+ { "zipdrive", 0, NULL, 'z' },
+ { "sectors", 1, NULL, 'S' },
+ { "heads", 1, NULL, 'H' },
+ { "raid-mode", 0, NULL, 'r' },
+ { "version", 0, NULL, 'v' },
+ { "help", 0, NULL, 'h' },
{ 0, 0, 0, 0 }
};
-static const char short_options[] = "iUuzS:H:vh";
-
-
+static const char short_options[] = "iUuzS:H:rvh";
#if defined(__linux__) && !defined(BLKGETSIZE64)
/* This takes a u64, but the size field says size_t. Someone screwed big. */
#endif
}
+static inline void set_8(unsigned char *p, uint8_t v)
+{
+ *(uint8_t *)p = v;
+}
+
static inline void set_16(unsigned char *p, uint16_t v)
{
#if defined(__i386__) || defined(__x86_64__)
set_16(boot_block+bsHeads, geo.heads);
set_32(boot_block+bsHiddenSecs, geo.start);
+ /* If we're in RAID mode then patch the appropriate instruction;
+ either way write the proper boot signature */
+ i = get_16(boot_block+0x1FE);
+ if (opt.raid_mode)
+ set_16(boot_block+i, 0x18CD); /* INT 18h */
+
+ set_16(boot_block+0x1FE, 0xAA55);
+
/* Construct the boot file */
dprintf("directory inode = %lu\n", (unsigned long) dirst.st_ino);
exit(EX_USAGE);
}
break;
+ case 'r':
+ opt.raid_mode = 1;
+ break;
case 'i':
update_only = 0;
break;
usage(EX_USAGE);
if ( update_only == -1 ) {
- fprintf(stderr, "%s: warning: a future version will require --install or --update\n",
- program);
+ fprintf(stderr, "%s: warning: a future version will require "
+ "--install or --update\n", program);
update_only = 0;
}