aboutsummaryrefslogtreecommitdiffstats
path: root/extlinux
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-06-01 18:18:19 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-06-01 18:18:19 -0700
commit46ed7c28730aa551a6f36d7c0c4fb08012070cc9 (patch)
tree0dae7b648d361d670a6920aa6904e3b421ec889c /extlinux
parent1de6cd492b87c9fbd70bb6e9f9e72b336a81d3a0 (diff)
downloadsyslinux-elf-46ed7c28730aa551a6f36d7c0c4fb08012070cc9.tar.gz
syslinux-elf-46ed7c28730aa551a6f36d7c0c4fb08012070cc9.tar.xz
syslinux-elf-46ed7c28730aa551a6f36d7c0c4fb08012070cc9.zip
RAID mode installer support for extlinux
Hook up RAID mode in the extlinux installer.
Diffstat (limited to 'extlinux')
-rw-r--r--extlinux/extlinux.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/extlinux/extlinux.c b/extlinux/extlinux.c
index 5ed548fc..d75505a7 100644
--- a/extlinux/extlinux.c
+++ b/extlinux/extlinux.c
@@ -58,9 +58,11 @@ const char *program;
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)
@@ -72,6 +74,7 @@ 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"
@@ -86,19 +89,18 @@ static void __attribute__((noreturn)) usage(int rv)
}
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. */
@@ -185,6 +187,11 @@ static inline uint32_t get_32(const unsigned char *p)
#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__)
@@ -476,6 +483,14 @@ patch_file_and_bootblock(int fd, int dirfd, int devfd)
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);
@@ -781,6 +796,9 @@ main(int argc, char *argv[])
exit(EX_USAGE);
}
break;
+ case 'r':
+ opt.raid_mode = 1;
+ break;
case 'i':
update_only = 0;
break;
@@ -805,8 +823,8 @@ main(int argc, char *argv[])
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;
}