Hi, v2 changes: - Fixed ARM's multiline KEXEC_ALL_OPTIONS #define - Removed opterr=0 from main()'s getopts_long() scan, and handle unknown options in main() (as it now knows about all allowed opts). Previously it relied on the file_type->load()er parsing & complaining about unknown options; if the loader didn't parse them, no complaint. Tested on x86, ppc and compile-tested on my new crisv32-axis-linux-gnu crosscompiler :-) Cheers, Matt --- The argument parsing is currently a bit broken as main()'s getopt_long() knows nothing about either the architecture-specific options or, even more specifically, the architecture-and-loader-specific options. This patch introduces new #defines for all architectures, KEXEC_ALL_OPTIONS and KEXEC_ALL_OPT_STR. These contain all possible options for a given build, and the getopt_long() passes in main() and arch_process_options() will now recognise arch- and loader-specific options; these will not be re-ordered in argv[], there is no confusion over which argv[] entry is the kernel filename, and using '--opt=foo' and '--opt foo' both work. All architectures have command line options (and #define OPT_BLAHs) consolidated into their include/arch/option.h files. x86_64 builds parts of i386/ as well, so now both share a single option.h file (with a symlink). Signed-off-by: Matt Evans <matt at ozlabs.org> --- kexec/arch/alpha/include/arch/options.h | 9 +++++ kexec/arch/arm/include/arch/options.h | 29 +++++++++++++++++ kexec/arch/arm/kexec-zImage-arm.c | 3 +- kexec/arch/cris/include/arch/options.h | 32 ++++++++++++++++-- kexec/arch/cris/kexec-elf-cris.c | 4 +- kexec/arch/i386/include/arch/options.h | 51 ++++++++++++++++++++++++++++++ kexec/arch/i386/kexec-beoboot-x86.c | 3 +- kexec/arch/i386/kexec-bzImage.c | 6 +-- kexec/arch/i386/kexec-elf-x86.c | 7 +--- kexec/arch/i386/kexec-multiboot-x86.c | 5 +-- kexec/arch/i386/kexec-x86.c | 4 +- kexec/arch/ia64/include/arch/options.h | 33 ++++++++++++++++++- kexec/arch/ia64/kexec-elf-ia64.c | 7 +--- kexec/arch/mips/include/arch/options.h | 27 +++++++++++++++- kexec/arch/mips/kexec-elf-mips.c | 3 +- kexec/arch/ppc/include/arch/options.h | 34 ++++++++++++++++++++ kexec/arch/ppc/kexec-dol-ppc.c | 4 +- kexec/arch/ppc/kexec-elf-ppc.c | 7 +--- kexec/arch/ppc/kexec-uImage-ppc.c | 6 +-- kexec/arch/ppc64/include/arch/options.h | 37 ++++++++++++++++++++- kexec/arch/ppc64/kexec-elf-ppc64.c | 12 ++++--- kexec/arch/ppc64/kexec-ppc64.c | 12 +++---- kexec/arch/s390/include/arch/options.h | 28 ++++++++++++++++- kexec/arch/s390/kexec-image.c | 4 +-- kexec/arch/sh/include/arch/options.h | 26 +++++++++++++-- kexec/arch/sh/kexec-sh.c | 7 +++- kexec/arch/x86_64/include/arch/options.h | 23 +------------- kexec/arch/x86_64/kexec-elf-x86_64.c | 7 +--- kexec/arch/x86_64/kexec-x86_64.c | 4 +- kexec/kexec.c | 6 ++-- 30 files changed, 341 insertions(+), 99 deletions(-) mode change 100644 => 120000 kexec/arch/x86_64/include/arch/options.h diff --git a/kexec/arch/alpha/include/arch/options.h b/kexec/arch/alpha/include/arch/options.h index 11557a4..a012c8a 100644 --- a/kexec/arch/alpha/include/arch/options.h +++ b/kexec/arch/alpha/include/arch/options.h @@ -3,9 +3,18 @@ #define OPT_ARCH_MAX (OPT_MAX+0) +/* Options relevant to the architecture (excluding loader-specific ones), + * in this case none: + */ #define KEXEC_ARCH_OPTIONS \ KEXEC_OPTIONS \ #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" +/* See the other architectures for details of these; Alpha has no + * loader-specific options yet. + */ +#define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS +#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR + #endif /* KEXEC_ARCH_ALPHA_OPTIONS_H */ diff --git a/kexec/arch/arm/include/arch/options.h b/kexec/arch/arm/include/arch/options.h index 248230b..d89c91f 100644 --- a/kexec/arch/arm/include/arch/options.h +++ b/kexec/arch/arm/include/arch/options.h @@ -3,9 +3,38 @@ #define OPT_ARCH_MAX (OPT_MAX+0) +#define OPT_APPEND 'a' +#define OPT_RAMDISK 'r' + +/* Options relevant to the architecture (excluding loader-specific ones), + * in this case none: + */ #define KEXEC_ARCH_OPTIONS \ KEXEC_OPTIONS \ #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" +/* The following two #defines list ALL of the options added by all of the + * architecture's loaders. + * o main() uses this complete list to scan for its options, ignoring + * arch-specific/loader-specific ones. + * o Then, arch_process_options() uses this complete list to scan for its + * options, ignoring general/loader-specific ones. + * o Then, the file_type[n].load re-scans for options, using + * KEXEC_ARCH_OPTIONS plus its loader-specific options subset. + * Any unrecognised options cause an error here. + * + * This is done so that main()'s/arch_process_options()'s getopt_long() calls + * don't choose a kernel filename from random arguments to options they don't + * recognise -- as they now recognise (if not act upon) all possible options. + */ +#define KEXEC_ALL_OPTIONS \ + KEXEC_ARCH_OPTIONS \ + { "command-line", 1, 0, OPT_APPEND }, \ + { "append", 1, 0, OPT_APPEND }, \ + { "initrd", 1, 0, OPT_RAMDISK }, \ + { "ramdisk", 1, 0, OPT_RAMDISK }, + +#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR "a:r:" + #endif /* KEXEC_ARCH_ARM_OPTIONS_H */ diff --git a/kexec/arch/arm/kexec-zImage-arm.c b/kexec/arch/arm/kexec-zImage-arm.c index 1a446d9..e060f6e 100644 --- a/kexec/arch/arm/kexec-zImage-arm.c +++ b/kexec/arch/arm/kexec-zImage-arm.c @@ -219,8 +219,7 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len, off_t ramdisk_length; off_t ramdisk_offset; int opt; -#define OPT_APPEND 'a' -#define OPT_RAMDISK 'r' + /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS { "command-line", 1, 0, OPT_APPEND }, diff --git a/kexec/arch/cris/include/arch/options.h b/kexec/arch/cris/include/arch/options.h index bc5f706..1c1a029 100644 --- a/kexec/arch/cris/include/arch/options.h +++ b/kexec/arch/cris/include/arch/options.h @@ -1,11 +1,35 @@ -#ifndef KEXEC_ARCH_MIPS_OPTIONS_H -#define KEXEC_ARCH_MIPS_OPTIONS_H +#ifndef KEXEC_ARCH_CRIS_OPTIONS_H +#define KEXEC_ARCH_CRIS_OPTIONS_H -#define OPT_ARCH_MAX (OPT_MAX+0) +#define OPT_ARCH_MAX (OPT_MAX+0) +#define OPT_APPEND (OPT_ARCH_MAX+0) +/* Options relevant to the architecture (excluding loader-specific ones), + * in this case none: + */ #define KEXEC_ARCH_OPTIONS \ KEXEC_OPTIONS \ #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" -#endif /* KEXEC_ARCH_MIPS_OPTIONS_H */ +/* The following two #defines list ALL of the options added by all of the + * architecture's loaders. + * o main() uses this complete list to scan for its options, ignoring + * arch-specific/loader-specific ones. + * o Then, arch_process_options() uses this complete list to scan for its + * options, ignoring general/loader-specific ones. + * o Then, the file_type[n].load re-scans for options, using + * KEXEC_ARCH_OPTIONS plus its loader-specific options subset. + * Any unrecognised options cause an error here. + * + * This is done so that main()'s/arch_process_options()'s getopt_long() calls + * don't choose a kernel filename from random arguments to options they don't + * recognise -- as they now recognise (if not act upon) all possible options. + */ +#define KEXEC_ALL_OPTIONS \ + KEXEC_ARCH_OPTIONS \ + {"append", 1, 0, OPT_APPEND}, + +#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR + +#endif /* KEXEC_ARCH_CRIS_OPTIONS_H */ diff --git a/kexec/arch/cris/kexec-elf-cris.c b/kexec/arch/cris/kexec-elf-cris.c index 4b56a20..b48b7b3 100644 --- a/kexec/arch/cris/kexec-elf-cris.c +++ b/kexec/arch/cris/kexec-elf-cris.c @@ -40,8 +40,6 @@ #include <arch/options.h> #include "kexec-cris.h" -#define OPT_APPEND (OPT_ARCH_MAX+0) - int elf_cris_probe(const char *buf, off_t len) { struct mem_ehdr ehdr; @@ -89,8 +87,10 @@ int elf_cris_load(int argc, char **argv, const char *buf, off_t len, unsigned int regs[16]; } cris_regframe; + /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS + {"append", 1, 0, OPT_APPEND}, { 0, 0, 0, 0 }, }; diff --git a/kexec/arch/i386/include/arch/options.h b/kexec/arch/i386/include/arch/options.h index 0695f37..990527c 100644 --- a/kexec/arch/i386/include/arch/options.h +++ b/kexec/arch/i386/include/arch/options.h @@ -1,6 +1,15 @@ #ifndef KEXEC_ARCH_I386_OPTIONS_H #define KEXEC_ARCH_I386_OPTIONS_H +/* + ************************************************************************* + * NOTE NOTE NOTE + * This file is included for i386 builds *and* x86_64 builds (which build + * both x86_64 and i386 loaders). + * It contains the combined set of options used by i386 and x86_64. + ************************************************************************* + */ + #define OPT_RESET_VGA (OPT_MAX+0) #define OPT_SERIAL (OPT_MAX+1) #define OPT_SERIAL_BAUD (OPT_MAX+2) @@ -10,6 +19,18 @@ #define OPT_ELF64_CORE (OPT_MAX+6) #define OPT_ARCH_MAX (OPT_MAX+7) +#define OPT_APPEND (OPT_ARCH_MAX+0) +#define OPT_REUSE_CMDLINE (OPT_ARCH_MAX+1) +#define OPT_RAMDISK (OPT_ARCH_MAX+2) +#define OPT_ARGS_ELF (OPT_ARCH_MAX+3) +#define OPT_ARGS_LINUX (OPT_ARCH_MAX+4) +#define OPT_ARGS_NONE (OPT_ARCH_MAX+5) +#define OPT_CL (OPT_ARCH_MAX+6) +#define OPT_MOD (OPT_ARCH_MAX+7) +#define OPT_VGA (OPT_ARCH_MAX+8) +#define OPT_REAL_MODE (OPT_ARCH_MAX+9) + +/* Options relevant to the architecture (excluding loader-specific ones): */ #define KEXEC_ARCH_OPTIONS \ KEXEC_OPTIONS \ { "reset-vga", 0, 0, OPT_RESET_VGA }, \ @@ -22,5 +43,35 @@ #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" +/* The following two #defines list ALL of the options added by all of the + * architecture's loaders. + * o main() uses this complete list to scan for its options, ignoring + * arch-specific/loader-specific ones. + * o Then, arch_process_options() uses this complete list to scan for its + * options, ignoring general/loader-specific ones. + * o Then, the file_type[n].load re-scans for options, using + * KEXEC_ARCH_OPTIONS plus its loader-specific options subset. + * Any unrecognised options cause an error here. + * + * This is done so that main()'s/arch_process_options()'s getopt_long() calls + * don't choose a kernel filename from random arguments to options they don't + * recognise -- as they now recognise (if not act upon) all possible options. + */ +#define KEXEC_ALL_OPTIONS \ + KEXEC_ARCH_OPTIONS \ + { "command-line", 1, NULL, OPT_APPEND }, \ + { "append", 1, NULL, OPT_APPEND }, \ + { "reuse-cmdline", 0, NULL, OPT_REUSE_CMDLINE }, \ + { "initrd", 1, NULL, OPT_RAMDISK }, \ + { "ramdisk", 1, NULL, OPT_RAMDISK }, \ + { "args-elf", 0, NULL, OPT_ARGS_ELF }, \ + { "args-linux", 0, NULL, OPT_ARGS_LINUX }, \ + { "args-none", 0, NULL, OPT_ARGS_NONE }, \ + { "debug", 0, NULL, OPT_DEBUG }, \ + { "module", 1, 0, OPT_MOD }, \ + { "real-mode", 0, NULL, OPT_REAL_MODE }, + +#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR + #endif /* KEXEC_ARCH_I386_OPTIONS_H */ diff --git a/kexec/arch/i386/kexec-beoboot-x86.c b/kexec/arch/i386/kexec-beoboot-x86.c index 27c5a2c..6d459ae 100644 --- a/kexec/arch/i386/kexec-beoboot-x86.c +++ b/kexec/arch/i386/kexec-beoboot-x86.c @@ -84,7 +84,8 @@ int beoboot_load(int argc, char **argv, const char *buf, off_t UNUSED(len), int debug, real_mode_entry; int opt; int result; -#define OPT_REAL_MODE (OPT_ARCH_MAX+0) + + /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS { "debug", 0, 0, OPT_DEBUG }, diff --git a/kexec/arch/i386/kexec-bzImage.c b/kexec/arch/i386/kexec-bzImage.c index 53a50b3..ae18689 100644 --- a/kexec/arch/i386/kexec-bzImage.c +++ b/kexec/arch/i386/kexec-bzImage.c @@ -341,10 +341,8 @@ int bzImage_load(int argc, char **argv, const char *buf, off_t len, int debug, real_mode_entry; int opt; int result; -#define OPT_APPEND (OPT_ARCH_MAX+0) -#define OPT_REUSE_CMDLINE (OPT_ARCH_MAX+1) -#define OPT_RAMDISK (OPT_ARCH_MAX+2) -#define OPT_REAL_MODE (OPT_ARCH_MAX+3) + + /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS { "debug", 0, 0, OPT_DEBUG }, diff --git a/kexec/arch/i386/kexec-elf-x86.c b/kexec/arch/i386/kexec-elf-x86.c index 2cb9d11..2e9cf9a 100644 --- a/kexec/arch/i386/kexec-elf-x86.c +++ b/kexec/arch/i386/kexec-elf-x86.c @@ -99,13 +99,8 @@ int elf_x86_load(int argc, char **argv, const char *buf, off_t len, #define ARG_STYLE_LINUX 1 #define ARG_STYLE_NONE 2 int opt; -#define OPT_APPEND (OPT_ARCH_MAX+0) -#define OPT_REUSE_CMDLINE (OPT_ARCH_MAX+1) -#define OPT_RAMDISK (OPT_ARCH_MAX+2) -#define OPT_ARGS_ELF (OPT_ARCH_MAX+3) -#define OPT_ARGS_LINUX (OPT_ARCH_MAX+4) -#define OPT_ARGS_NONE (OPT_ARCH_MAX+5) + /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS { "command-line", 1, NULL, OPT_APPEND }, diff --git a/kexec/arch/i386/kexec-multiboot-x86.c b/kexec/arch/i386/kexec-multiboot-x86.c index 970de2a..23dab7b 100644 --- a/kexec/arch/i386/kexec-multiboot-x86.c +++ b/kexec/arch/i386/kexec-multiboot-x86.c @@ -157,10 +157,7 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len, uint32_t u; int opt; int modules, mod_command_line_space; -#define OPT_CL (OPT_ARCH_MAX+0) -#define OPT_REUSE_CMDLINE (OPT_ARCH_MAX+1) -#define OPT_MOD (OPT_ARCH_MAX+2) -#define OPT_VGA (OPT_ARCH_MAX+3) + /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS { "command-line", 1, 0, OPT_CL }, diff --git a/kexec/arch/i386/kexec-x86.c b/kexec/arch/i386/kexec-x86.c index d33a14b..5c701aa 100644 --- a/kexec/arch/i386/kexec-x86.c +++ b/kexec/arch/i386/kexec-x86.c @@ -69,10 +69,10 @@ struct arch_options_t arch_options = { int arch_process_options(int argc, char **argv) { static const struct option options[] = { - KEXEC_ARCH_OPTIONS + KEXEC_ALL_OPTIONS { 0, 0, NULL, 0 }, }; - static const char short_options[] = KEXEC_ARCH_OPT_STR; + static const char short_options[] = KEXEC_ALL_OPT_STR; int opt; unsigned long value; char *end; diff --git a/kexec/arch/ia64/include/arch/options.h b/kexec/arch/ia64/include/arch/options.h index 3053576..e8754ad 100644 --- a/kexec/arch/ia64/include/arch/options.h +++ b/kexec/arch/ia64/include/arch/options.h @@ -1,11 +1,42 @@ #ifndef KEXEC_ARCH_IA64_OPTIONS_H #define KEXEC_ARCH_IA64_OPTIONS_H -#define OPT_ARCH_MAX (OPT_MAX+0) +#define OPT_ARCH_MAX (OPT_MAX+0) +#define OPT_APPEND (OPT_ARCH_MAX+0) +#define OPT_RAMDISK (OPT_ARCH_MAX+1) +#define OPT_NOIO (OPT_ARCH_MAX+2) +#define OPT_VMM (OPT_ARCH_MAX+3) +/* Options relevant to the architecture (excluding loader-specific ones), + * in this case none: + */ #define KEXEC_ARCH_OPTIONS \ KEXEC_OPTIONS \ #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" +/* The following two #defines list ALL of the options added by all of the + * architecture's loaders. + * o main() uses this complete list to scan for its options, ignoring + * arch-specific/loader-specific ones. + * o Then, arch_process_options() uses this complete list to scan for its + * options, ignoring general/loader-specific ones. + * o Then, the file_type[n].load re-scans for options, using + * KEXEC_ARCH_OPTIONS plus its loader-specific options subset. + * Any unrecognised options cause an error here. + * + * This is done so that main()'s/arch_process_options()'s getopt_long() calls + * don't choose a kernel filename from random arguments to options they don't + * recognise -- as they now recognise (if not act upon) all possible options. + */ +#define KEXEC_ALL_OPTIONS \ + KEXEC_ARCH_OPTIONS \ + {"command-line", 1, 0, OPT_APPEND}, \ + {"append", 1, 0, OPT_APPEND}, \ + {"initrd", 1, 0, OPT_RAMDISK}, \ + {"noio", 0, 0, OPT_NOIO}, \ + {"vmm", 1, 0, OPT_VMM}, \ + +#define KEXEC_ALL_OPT_STR KEXEC_OPT_STR + #endif /* KEXEC_ARCH_IA64_OPTIONS_H */ diff --git a/kexec/arch/ia64/kexec-elf-ia64.c b/kexec/arch/ia64/kexec-elf-ia64.c index 3bb5a4d..8da061e 100644 --- a/kexec/arch/ia64/kexec-elf-ia64.c +++ b/kexec/arch/ia64/kexec-elf-ia64.c @@ -45,11 +45,6 @@ #include "crashdump-ia64.h" #include <arch/options.h> -#define OPT_APPEND (OPT_ARCH_MAX+0) -#define OPT_RAMDISK (OPT_ARCH_MAX+1) -#define OPT_NOIO (OPT_ARCH_MAX+2) -#define OPT_VMM (OPT_ARCH_MAX+3) - static const int probe_debug = 0; extern unsigned long saved_efi_memmap_size; @@ -136,6 +131,8 @@ int elf_ia64_load(int argc, char **argv, const char *buf, off_t len, int result; int opt; char *efi_memmap_buf, *boot_param; + + /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS {"command-line", 1, 0, OPT_APPEND}, diff --git a/kexec/arch/mips/include/arch/options.h b/kexec/arch/mips/include/arch/options.h index bc5f706..07b4f63 100644 --- a/kexec/arch/mips/include/arch/options.h +++ b/kexec/arch/mips/include/arch/options.h @@ -1,11 +1,36 @@ #ifndef KEXEC_ARCH_MIPS_OPTIONS_H #define KEXEC_ARCH_MIPS_OPTIONS_H -#define OPT_ARCH_MAX (OPT_MAX+0) +#define OPT_ARCH_MAX (OPT_MAX+0) +#define OPT_APPEND (OPT_ARCH_MAX+0) +/* Options relevant to the architecture (excluding loader-specific ones), + * in this case none: + */ #define KEXEC_ARCH_OPTIONS \ KEXEC_OPTIONS \ #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" +/* The following two #defines list ALL of the options added by all of the + * architecture's loaders. + * o main() uses this complete list to scan for its options, ignoring + * arch-specific/loader-specific ones. + * o Then, arch_process_options() uses this complete list to scan for its + * options, ignoring general/loader-specific ones. + * o Then, the file_type[n].load re-scans for options, using + * KEXEC_ARCH_OPTIONS plus its loader-specific options subset. + * Any unrecognised options cause an error here. + * + * This is done so that main()'s/arch_process_options()'s getopt_long() calls + * don't choose a kernel filename from random arguments to options they don't + * recognise -- as they now recognise (if not act upon) all possible options. + */ +#define KEXEC_ALL_OPTIONS \ + KEXEC_ARCH_OPTIONS \ + {"command-line", 1, 0, OPT_APPEND}, \ + {"append", 1, 0, OPT_APPEND}, + +#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR + #endif /* KEXEC_ARCH_MIPS_OPTIONS_H */ diff --git a/kexec/arch/mips/kexec-elf-mips.c b/kexec/arch/mips/kexec-elf-mips.c index ce6bf0c..a9c865e 100644 --- a/kexec/arch/mips/kexec-elf-mips.c +++ b/kexec/arch/mips/kexec-elf-mips.c @@ -35,7 +35,6 @@ static const int probe_debug = 0; #define BOOTLOADER "kexec" #define MAX_COMMAND_LINE 256 #define UPSZ(X) ((sizeof(X) + 3) & ~3) -#define OPT_APPEND (OPT_ARCH_MAX+0) static char cmdline_buf[256] = "kexec "; int elf_mips_probe(const char *buf, off_t len) @@ -82,6 +81,8 @@ int elf_mips_load(int argc, char **argv, const char *buf, off_t len, unsigned long cmdline_addr; size_t i; unsigned long bss_start = 0, bss_size = 0; + + /* See options.h if adding any more options. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS {"command-line", 1, 0, OPT_APPEND}, diff --git a/kexec/arch/ppc/include/arch/options.h b/kexec/arch/ppc/include/arch/options.h index df14db5..f646ccc 100644 --- a/kexec/arch/ppc/include/arch/options.h +++ b/kexec/arch/ppc/include/arch/options.h @@ -3,9 +3,43 @@ #define OPT_ARCH_MAX (OPT_MAX+0) +/* All 'local' loader options: */ +#define OPT_APPEND (OPT_ARCH_MAX+0) +#define OPT_GAMECUBE (OPT_ARCH_MAX+1) +#define OPT_DTB (OPT_ARCH_MAX+2) +#define OPT_NODES (OPT_ARCH_MAX+3) + +/* Options relevant to the architecture (excluding loader-specific ones), + * in this case none: + */ #define KEXEC_ARCH_OPTIONS \ KEXEC_OPTIONS \ #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" +/* The following two #defines list ALL of the options added by all of the + * architecture's loaders. + * o main() uses this complete list to scan for its options, ignoring + * arch-specific/loader-specific ones. + * o Then, arch_process_options() uses this complete list to scan for its + * options, ignoring general/loader-specific ones. + * o Then, the file_type[n].load re-scans for options, using + * KEXEC_ARCH_OPTIONS plus its loader-specific options subset. + * Any unrecognised options cause an error here. + * + * This is done so that main()'s/arch_process_options()'s getopt_long() calls + * don't choose a kernel filename from random arguments to options they don't + * recognise -- as they now recognise (if not act upon) all possible options. + */ +#define KEXEC_ALL_OPTIONS \ + KEXEC_ARCH_OPTIONS \ + {"command-line", 1, 0, OPT_APPEND},\ + {"append", 1, 0, OPT_APPEND},\ + {"gamecube", 1, 0, OPT_GAMECUBE},\ + {"dtb", 1, 0, OPT_DTB},\ + {"reuse-node", 1, 0, OPT_NODES},\ + {"debug", 0, 0, OPT_DEBUG}, + +#define KEXEC_ALL_OPT_STR KEXEC_OPT_STR + #endif /* KEXEC_ARCH_PPC_OPTIONS_H */ diff --git a/kexec/arch/ppc/kexec-dol-ppc.c b/kexec/arch/ppc/kexec-dol-ppc.c index 83c122a..8de5293 100644 --- a/kexec/arch/ppc/kexec-dol-ppc.c +++ b/kexec/arch/ppc/kexec-dol-ppc.c @@ -335,8 +335,8 @@ int dol_ppc_load(int argc, char **argv, const char *buf, off_t UNUSED(len), unsigned long lowest_start; int i, j, k; int opt; -#define OPT_APPEND (OPT_ARCH_MAX+0) + /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS {"debug", 0, 0, OPT_DEBUG}, @@ -344,7 +344,7 @@ int dol_ppc_load(int argc, char **argv, const char *buf, off_t UNUSED(len), {"append", 1, 0, OPT_APPEND}, {0, 0, 0, 0}, }; - static const char short_options[] = KEXEC_ARCH_OPT_STR "d"; + static const char short_options[] = KEXEC_ARCH_OPT_STR; /* * Parse the command line arguments diff --git a/kexec/arch/ppc/kexec-elf-ppc.c b/kexec/arch/ppc/kexec-elf-ppc.c index a54a5d5..cb2c07a 100644 --- a/kexec/arch/ppc/kexec-elf-ppc.c +++ b/kexec/arch/ppc/kexec-elf-ppc.c @@ -113,10 +113,7 @@ static void gamecube_hack_addresses(struct mem_ehdr *ehdr) } } -#define OPT_APPEND (OPT_ARCH_MAX+0) -#define OPT_GAMECUBE (OPT_ARCH_MAX+1) -#define OPT_DTB (OPT_ARCH_MAX+2) -#define OPT_NODES (OPT_ARCH_MAX+3) +/* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS {"command-line", 1, 0, OPT_APPEND}, @@ -126,7 +123,7 @@ static const struct option options[] = { {"reuse-node", 1, 0, OPT_NODES}, {0, 0, 0, 0}, }; -static const char short_options[] = KEXEC_ARCH_OPT_STR "d"; +static const char short_options[] = KEXEC_ARCH_OPT_STR; void elf_ppc_usage(void) { diff --git a/kexec/arch/ppc/kexec-uImage-ppc.c b/kexec/arch/ppc/kexec-uImage-ppc.c index 0a655a3..45cde2f 100644 --- a/kexec/arch/ppc/kexec-uImage-ppc.c +++ b/kexec/arch/ppc/kexec-uImage-ppc.c @@ -14,9 +14,7 @@ #include "fixup_dtb.h" #include <kexec-uImage.h> -#define OPT_APPEND (OPT_ARCH_MAX+0) -#define OPT_DTB (OPT_ARCH_MAX+1) -#define OPT_NODES (OPT_ARCH_MAX+2) +/* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS {"command-line", 1, 0, OPT_APPEND}, @@ -25,7 +23,7 @@ static const struct option options[] = { {"reuse-node", 1, 0, OPT_NODES}, {0, 0, 0, 0}, }; -static const char short_options[] = KEXEC_ARCH_OPT_STR "d"; +static const char short_options[] = KEXEC_ARCH_OPT_STR; void uImage_ppc_usage(void) { diff --git a/kexec/arch/ppc64/include/arch/options.h b/kexec/arch/ppc64/include/arch/options.h index 973cd4f..8f11c83 100644 --- a/kexec/arch/ppc64/include/arch/options.h +++ b/kexec/arch/ppc64/include/arch/options.h @@ -1,13 +1,46 @@ #ifndef KEXEC_ARCH_PPC64_OPTIONS_H #define KEXEC_ARCH_PPC64_OPTIONS_H -#define OPT_ARCH_MAX (OPT_MAX+0) -#define OPT_ELF64_CORE (OPT_MAX+1) +#define OPT_ELF64_CORE (OPT_MAX+0) +#define OPT_ARCH_MAX (OPT_MAX+1) +/* All 'local' loader options: */ +#define OPT_APPEND (OPT_ARCH_MAX+0) +#define OPT_RAMDISK (OPT_ARCH_MAX+1) +#define OPT_DEVICETREEBLOB (OPT_ARCH_MAX+2) +#define OPT_ARGS_IGNORE (OPT_ARCH_MAX+3) + +/* Options relevant to the architecture (excluding loader-specific ones): */ #define KEXEC_ARCH_OPTIONS \ KEXEC_OPTIONS \ { "elf64-core-headers", 0, 0, OPT_ELF64_CORE }, \ #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" +/* The following two #defines list ALL of the options added by all of the + * architecture's loaders. + * o main() uses this complete list to scan for its options, ignoring + * arch-specific/loader-specific ones. + * o Then, arch_process_options() uses this complete list to scan for its + * options, ignoring general/loader-specific ones. + * o Then, the file_type[n].load re-scans for options, using + * KEXEC_ARCH_OPTIONS plus its loader-specific options subset. + * Any unrecognised options cause an error here. + * + * This is done so that main()'s/arch_process_options()'s getopt_long() calls + * don't choose a kernel filename from random arguments to options they don't + * recognise -- as they now recognise (if not act upon) all possible options. + */ +#define KEXEC_ALL_OPTIONS \ + KEXEC_ARCH_OPTIONS \ + { "command-line", 1, NULL, OPT_APPEND }, \ + { "append", 1, NULL, OPT_APPEND }, \ + { "ramdisk", 1, NULL, OPT_RAMDISK }, \ + { "initrd", 1, NULL, OPT_RAMDISK }, \ + { "devicetreeblob", 1, NULL, OPT_DEVICETREEBLOB }, \ + { "args-linux", 0, NULL, OPT_ARGS_IGNORE }, + +#define KEXEC_ALL_OPT_STR KEXEC_OPT_STR + + #endif /* KEXEC_ARCH_PPC64_OPTIONS_H */ diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c index d65a5d5..ab6da7c 100644 --- a/kexec/arch/ppc64/kexec-elf-ppc64.c +++ b/kexec/arch/ppc64/kexec-elf-ppc64.c @@ -93,11 +93,7 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, uint32_t my_run_at_load; unsigned int slave_code[256/sizeof (unsigned int)], master_entry; -#define OPT_APPEND (OPT_ARCH_MAX+0) -#define OPT_RAMDISK (OPT_ARCH_MAX+1) -#define OPT_DEVICETREEBLOB (OPT_ARCH_MAX+2) -#define OPT_ARGS_IGNORE (OPT_ARCH_MAX+3) - + /* See options.h -- add any more there, too. */ static const struct option options[] = { KEXEC_ARCH_OPTIONS { "command-line", 1, NULL, OPT_APPEND }, @@ -347,5 +343,11 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, void elf_ppc64_usage(void) { + fprintf(stderr, " --command-line=<Command line> command line to append.\n"); + fprintf(stderr, " --append=<Command line> same as --command-line.\n"); + fprintf(stderr, " --ramdisk=<filename> Initial RAM disk.\n"); + fprintf(stderr, " --initrd=<filename> same as --ramdisk.\n"); + fprintf(stderr, " --devicetreeblob=<filename> Specify device tree blob file.\n"); + fprintf(stderr, "elf support is still broken\n"); } diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c index f9dc65b..48ea421 100644 --- a/kexec/arch/ppc64/kexec-ppc64.c +++ b/kexec/arch/ppc64/kexec-ppc64.c @@ -735,11 +735,6 @@ int file_types = sizeof(file_type) / sizeof(file_type[0]); void arch_usage(void) { - fprintf(stderr, " --command-line=<Command line> command line to append.\n"); - fprintf(stderr, " --append=<Command line> same as --command-line.\n"); - fprintf(stderr, " --ramdisk=<filename> Initial RAM disk.\n"); - fprintf(stderr, " --initrd=<filename> same as --ramdisk.\n"); - fprintf(stderr, " --devicetreeblob=<filename> Specify device tree blob file.\n"); fprintf(stderr, " --elf64-core-headers Prepare core headers in ELF64 format\n"); } @@ -749,11 +744,14 @@ struct arch_options_t arch_options = { int arch_process_options(int argc, char **argv) { + /* We look for all options so getopt_long doesn't start reordering + * argv[] before file_type[n].load() gets a look in. + */ static const struct option options[] = { - KEXEC_ARCH_OPTIONS + KEXEC_ALL_OPTIONS { 0, 0, NULL, 0 }, }; - static const char short_options[] = KEXEC_ARCH_OPT_STR; + static const char short_options[] = KEXEC_ALL_OPT_STR; int opt; opterr = 0; /* Don't complain about unrecognized options here */ diff --git a/kexec/arch/s390/include/arch/options.h b/kexec/arch/s390/include/arch/options.h index 2979617..b57539f 100644 --- a/kexec/arch/s390/include/arch/options.h +++ b/kexec/arch/s390/include/arch/options.h @@ -1,11 +1,37 @@ #ifndef KEXEC_ARCH_S390_OPTIONS_H #define KEXEC_ARCH_S390_OPTIONS_H -#define OPT_ARCH_MAX (OPT_MAX+0) +#define OPT_ARCH_MAX (OPT_MAX+0) +#define OPT_APPEND OPT_MAX+0 +#define OPT_RAMDISK OPT_MAX+1 +/* Options relevant to the architecture (excluding loader-specific ones), + * in this case none: + */ #define KEXEC_ARCH_OPTIONS \ KEXEC_OPTIONS \ #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" +/* The following two #defines list ALL of the options added by all of the + * architecture's loaders. + * o main() uses this complete list to scan for its options, ignoring + * arch-specific/loader-specific ones. + * o Then, arch_process_options() uses this complete list to scan for its + * options, ignoring general/loader-specific ones. + * o Then, the file_type[n].load re-scans for options, using + * KEXEC_ARCH_OPTIONS plus its loader-specific options subset. + * Any unrecognised options cause an error here. + * + * This is done so that main()'s/arch_process_options()'s getopt_long() calls + * don't choose a kernel filename from random arguments to options they don't + * recognise -- as they now recognise (if not act upon) all possible options. + */ +#define KEXEC_ALL_OPTIONS \ + KEXEC_ARCH_OPTIONS \ + {"command-line", 1, 0, OPT_APPEND}, \ + {"initrd", 1, 0, OPT_RAMDISK}, + +#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR + #endif /* KEXEC_ARCH_S390_OPTIONS_H */ diff --git a/kexec/arch/s390/kexec-image.c b/kexec/arch/s390/kexec-image.c index 13e550d..7ef8e29 100644 --- a/kexec/arch/s390/kexec-image.c +++ b/kexec/arch/s390/kexec-image.c @@ -19,9 +19,7 @@ #include <getopt.h> #include "../../kexec.h" #include "kexec-s390.h" - -#define OPT_APPEND OPT_MAX+0 -#define OPT_RAMDISK OPT_MAX+1 +#include <arch/options.h> int image_s390_load(int argc, char **argv, const char *kernel_buf, diff --git a/kexec/arch/sh/include/arch/options.h b/kexec/arch/sh/include/arch/options.h index e02960d..4bdd6a3 100644 --- a/kexec/arch/sh/include/arch/options.h +++ b/kexec/arch/sh/include/arch/options.h @@ -7,16 +7,36 @@ #define OPT_NBSD_HOWTO (OPT_ARCH_MAX+3) #define OPT_NBSD_MROOT (OPT_ARCH_MAX+4) - +/* Options relevant to the architecture (excluding loader-specific ones): */ #define KEXEC_ARCH_OPTIONS \ KEXEC_OPTIONS \ {"command-line", 1, 0, OPT_APPEND}, \ {"append", 1, 0, OPT_APPEND}, \ {"empty-zero", 1, 0, OPT_APPEND}, \ {"howto", 1, 0, OPT_NBSD_HOWTO}, \ - {"miniroot", 1, 0, OPT_NBSD_MROOT}, \ - + {"miniroot", 1, 0, OPT_NBSD_MROOT}, +/* These options seem to be loader-specific rather than cris-specific, so + * ought to be moved to KEXEC_ALL_OPTIONS below and parsed in the relevant + * loader, e.g. kexec-netbsd-sh.c + */ #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" +/* The following two #defines list ALL of the options added by all of the + * architecture's loaders. + * o main() uses this complete list to scan for its options, ignoring + * arch-specific/loader-specific ones. + * o Then, arch_process_options() uses this complete list to scan for its + * options, ignoring general/loader-specific ones. + * o Then, the file_type[n].load re-scans for options, using + * KEXEC_ARCH_OPTIONS plus its loader-specific options subset. + * Any unrecognised options cause an error here. + * + * This is done so that main()'s/arch_process_options()'s getopt_long() calls + * don't choose a kernel filename from random arguments to options they don't + * recognise -- as they now recognise (if not act upon) all possible options. + */ +#define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS +#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR + #endif /* KEXEC_ARCH_SH_OPTIONS_H */ diff --git a/kexec/arch/sh/kexec-sh.c b/kexec/arch/sh/kexec-sh.c index 1ad3d38..4b21ee8 100644 --- a/kexec/arch/sh/kexec-sh.c +++ b/kexec/arch/sh/kexec-sh.c @@ -97,8 +97,13 @@ void arch_usage(void) int arch_process_options(int argc, char **argv) { + /* The common options amongst loaders (e.g. --append) should be read + * here, and the loader-specific options (e.g. NetBSD stuff) should + * then be re-parsed in the loader. + * (e.g. in kexec-netbsd-sh.c, for example.) + */ static const struct option options[] = { - KEXEC_ARCH_OPTIONS + KEXEC_ALL_OPTIONS { 0, 0, NULL, 0 }, }; static const char short_options[] = KEXEC_ARCH_OPT_STR; diff --git a/kexec/arch/x86_64/include/arch/options.h b/kexec/arch/x86_64/include/arch/options.h deleted file mode 100644 index 75065b9..0000000 --- a/kexec/arch/x86_64/include/arch/options.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef KEXEC_ARCH_X86_64_OPTIONS_H -#define KEXEC_ARCH_X86_64_OPTIONS_H - -#define OPT_RESET_VGA (OPT_MAX+0) -#define OPT_SERIAL (OPT_MAX+1) -#define OPT_SERIAL_BAUD (OPT_MAX+2) -#define OPT_CONSOLE_VGA (OPT_MAX+3) -#define OPT_CONSOLE_SERIAL (OPT_MAX+4) -#define OPT_ARCH_MAX (OPT_MAX+5) - -#define KEXEC_ARCH_OPTIONS \ - KEXEC_OPTIONS \ - { "reset-vga", 0, 0, OPT_RESET_VGA }, \ - { "serial", 1, 0, OPT_SERIAL }, \ - { "serial-baud", 1, 0, OPT_SERIAL_BAUD }, \ - { "console-vga", 0, 0, OPT_CONSOLE_VGA }, \ - { "console-serial", 0, 0, OPT_CONSOLE_SERIAL }, \ - -#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" - -#endif /* KEXEC_ARCH_X86_64_OPTIONS_H */ - diff --git a/kexec/arch/x86_64/include/arch/options.h b/kexec/arch/x86_64/include/arch/options.h new file mode 120000 index 0000000..047b0f9 --- /dev/null +++ b/kexec/arch/x86_64/include/arch/options.h @@ -0,0 +1 @@ +../../../i386/include/arch/options.h \ No newline at end of file diff --git a/kexec/arch/x86_64/kexec-elf-x86_64.c b/kexec/arch/x86_64/kexec-elf-x86_64.c index 20c7d77..a8204bc 100644 --- a/kexec/arch/x86_64/kexec-elf-x86_64.c +++ b/kexec/arch/x86_64/kexec-elf-x86_64.c @@ -98,13 +98,8 @@ int elf_x86_64_load(int argc, char **argv, const char *buf, off_t len, #define ARG_STYLE_LINUX 1 #define ARG_STYLE_NONE 2 int opt; -#define OPT_APPEND (OPT_ARCH_MAX+0) -#define OPT_REUSE_CMDLINE (OPT_ARCH_MAX+1) -#define OPT_RAMDISK (OPT_ARCH_MAX+2) -#define OPT_ARGS_ELF (OPT_ARCH_MAX+3) -#define OPT_ARGS_LINUX (OPT_ARCH_MAX+4) -#define OPT_ARGS_NONE (OPT_ARCH_MAX+5) + /* See options.h and add any new options there too! */ static const struct option options[] = { KEXEC_ARCH_OPTIONS { "command-line", 1, NULL, OPT_APPEND }, diff --git a/kexec/arch/x86_64/kexec-x86_64.c b/kexec/arch/x86_64/kexec-x86_64.c index 49bfd36..a4f2d10 100644 --- a/kexec/arch/x86_64/kexec-x86_64.c +++ b/kexec/arch/x86_64/kexec-x86_64.c @@ -74,10 +74,10 @@ static struct { int arch_process_options(int argc, char **argv) { static const struct option options[] = { - KEXEC_ARCH_OPTIONS + KEXEC_ALL_OPTIONS { 0, 0, NULL, 0 }, }; - static const char short_options[] = KEXEC_ARCH_OPT_STR; + static const char short_options[] = KEXEC_ALL_OPT_STR; int opt; unsigned long value; char *end; diff --git a/kexec/kexec.c b/kexec/kexec.c index e9a13a7..2d8258f 100644 --- a/kexec/kexec.c +++ b/kexec/kexec.c @@ -1062,17 +1062,17 @@ int main(int argc, char *argv[]) int result = 0; int fileind; static const struct option options[] = { - KEXEC_ARCH_OPTIONS + KEXEC_ALL_OPTIONS { 0, 0, 0, 0}, }; - static const char short_options[] = KEXEC_OPT_STR; + static const char short_options[] = KEXEC_ALL_OPT_STR; arch_init(); - opterr = 0; /* Don't complain about unrecognized options here */ while ((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { switch(opt) { + case '?': case OPT_HELP: usage(); return 0; -- 1.6.3.3