From 2fbf57533b7037c7b21c6c00a766fee91dd1b8c7 Mon Sep 17 00:00:00 2001 From: Florian Lohoff Date: Sun, 5 Oct 2008 11:42:41 +0000 Subject: Move arg handling to prom code --- arclib/prom.c | 106 ++++++++++++++++++++++++++- common/prom.h | 7 ++ ext2load/conffile.c | 2 +- ext2load/loader.c | 201 ++++++++++++++-------------------------------------- 4 files changed, 165 insertions(+), 151 deletions(-) diff --git a/arclib/prom.c b/arclib/prom.c index 87a2bf3..5c12ff4 100644 --- a/arclib/prom.c +++ b/arclib/prom.c @@ -1,11 +1,20 @@ +#include +#include #include +#include + #include "arc.h" #include "prom.h" -#include -#include -#include +#define MAX_ARG 64 + +static char *iargv[MAX_ARG]; +static int iargc=0; + +static char *OSLoadPartition=NULL; +static char *OSLoadFilename=NULL; +static char *OSLoadOptions=NULL; void prom_flush_cache_all(void ) { ArcFlushAllCaches(); @@ -139,3 +148,94 @@ int prom_read(FILE stream, char *string, unsigned long len, unsigned long *rlen) return ArcRead(stream, string, len, rlen); } +/* we filter these out of the command line */ +static char* env_vars[] = { "ConsoleIn=", + "ConsoleOut=", + "OSLoader=", + "OSLoadPartition=", + "OSLoadFilename=", + "OSLoadOptions=", + }; +#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0]))))) + + +static int isEnvVar(const char* arg) +{ + unsigned int i; + + for (i = 0; i < NENTS(env_vars); i++) { + if(strncmp( env_vars[i], arg, strlen(env_vars[i]) ) == 0) + return 1; + } + return 0; +} + +int prom_parse_args(int argc, char **argv) +{ + unsigned long arg; + char *equals; + size_t len; + + /* save some things we need later */ + for (arg = 1; arg < argc; arg++) { + equals = strchr(argv[arg], '='); + if (equals != NULL) { + len = equals - argv[arg]; + if (strncmp(argv[arg], "OSLoadPartition", len) == 0) + OSLoadPartition = equals + 1; + if (strncmp(argv[arg], "OSLoadFilename", len) == 0) + OSLoadFilename = equals + 1; + if (strncmp(argv[arg], "OSLoadOptions", len) == 0) { + /* Copy options to local memory to avoid overwrite later */ + OSLoadOptions = strdup(equals + 1); + if (OSLoadOptions == NULL) + prom_fatal("Cannot allocate memory for options string\n\r"); + } + } + } + /* + * in case the user typed "boot a b c" the argv looks like: + * scsi(0)..(8)/arcboot a b c OSLoadPartition=.. SystemPartition=.. + * argv: `0 `-1`-2`-3`-4 `-5 + * we're interested in a,b,c so scan the command line and check for + * each argument if it is an environment variable. We're using a fixed + * list instead of ArcGetEnvironmentVariable since e.g. the prom sets + * "OSLoadOptions=auto" on reboot but + * EnvironmentVariable("OSLoadOptions") == NULL + */ + for( arg = 1; arg < argc; arg++ ) { + if(!isEnvVar(argv[arg])) { + iargv[iargc++]=strdup(argv[arg]); + } else { + if (OSLoadOptions) { + prom_add_arg(OSLoadOptions); + } + return (iargc); + } + } + return 0; +} + +void prom_add_arg(char *arg) { + iargv[iargc++]=strdup(arg); +} + +char *prom_get_label(void ) { + if (iargc > 1 && iargv[1]) { + return iargv[1]; + } + return "Linux"; +} + +char *prom_get_partition(void ) { + return OSLoadPartition; +} + +char *prom_get_options(void ) { + return OSLoadOptions; +} + +void prom_get_karg(int *argc, char ***argv) { + *argc=iargc; + *argv=iargv; +} diff --git a/common/prom.h b/common/prom.h index cfd255b..1a3acf5 100644 --- a/common/prom.h +++ b/common/prom.h @@ -40,3 +40,10 @@ enum { int prom_write(FILE stream, char *buf, unsigned long len, unsigned long *rlen); int prom_read(FILE stream, char *buf, unsigned long len, unsigned long *rlen); + +int prom_parse_args(int argc, char **argv); +void prom_add_arg(char *arg); +char *prom_get_label(void ); +char *prom_get_partition(void ); +char *prom_get_options(void ); +void prom_get_karg(int *argc, char ***argv); diff --git a/ext2load/conffile.c b/ext2load/conffile.c index dbdfaa4..0bcc2b7 100644 --- a/ext2load/conffile.c +++ b/ext2load/conffile.c @@ -97,7 +97,7 @@ CHAR** GetConfig(char* config, char* name) i=4; while(i<_PARM_LIMIT && *t != 0x0) { t++; - + if (*t == ' ' || *t == '\t') { *t++=0x0; if (*t != 0x0) diff --git a/ext2load/loader.c b/ext2load/loader.c index 1995b44..6eb1682 100644 --- a/ext2load/loader.c +++ b/ext2load/loader.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include @@ -31,86 +30,14 @@ static char argv_rd_start[32]; static char argv_rd_size[32]; unsigned long max_page_size = 0; - -CHAR *OSLoadPartition = NULL; -CHAR *OSLoadFilename = NULL; -CHAR *OSLoadOptions = NULL; static int is64=0; - typedef union { unsigned char e_ident[EI_NIDENT]; Elf32_Ehdr header32; Elf64_Ehdr header64; } Elf_Ehdr; -/* we filter these out of the command line */ -static char* env_vars[] = { "ConsoleIn=", - "ConsoleOut=", - "OSLoader=", - "OSLoadPartition=", - "OSLoadFilename=", - "OSLoadOptions=", - }; -#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0]))))) - - -static int isEnvVar(const char* arg) -{ - unsigned int i; - - for (i = 0; i < NENTS(env_vars); i++) { - if(strncmp( env_vars[i], arg, strlen(env_vars[i]) ) == 0) - return 1; - } - return 0; -} - -int ProcessArguments(LONG argc, CHAR * argv[]) -{ - LONG arg; - CHAR *equals; - size_t len; - - /* save some things we need later */ - for (arg = 1; arg < argc; arg++) { - equals = strchr(argv[arg], '='); - if (equals != NULL) { - len = equals - argv[arg]; - if (strncmp(argv[arg], "OSLoadPartition", len) == 0) - OSLoadPartition = equals + 1; - if (strncmp(argv[arg], "OSLoadFilename", len) == 0) - OSLoadFilename = equals + 1; - if (strncmp(argv[arg], "OSLoadOptions", len) == 0) { - /* Copy options to local memory to avoid overwrite later */ - OSLoadOptions = strdup(equals + 1); - if (OSLoadOptions == NULL) - prom_fatal("Cannot allocate memory for options string\n\r"); - } - } - } - /* - * in case the user typed "boot a b c" the argv looks like: - * scsi(0)..(8)/arcboot a b c OSLoadPartition=.. SystemPartition=.. - * argv: `0 `-1`-2`-3`-4 `-5 - * we're interested in a,b,c so scan the command line and check for - * each argument if it is an environment variable. We're using a fixed - * list instead of ArcGetEnvironmentVariable since e.g. the prom sets - * "OSLoadOptions=auto" on reboot but - * EnvironmentVariable("OSLoadOptions") == NULL - */ - for( arg = 1; arg < argc; arg++ ) { - if( isEnvVar(argv[arg])) { - return (arg-1); -#ifdef DEBUG - } else { - printf("%s is not an envVar\n\r", argv[arg]); -#endif - } - } - return 0; -} - int LoadProgramSegments32(ext2_file_t file, Elf_Ehdr * header, void *segments) { int idx; @@ -391,7 +318,7 @@ Elf64_Addr LoadKernel(const char *partition, const char *filename) } -void LoadInitrd(const char *partition, const char *filename, int *argc, char **argv) +void LoadInitrd(const char *partition, const char *filename) { ext2_file_t file; ULONG initrd_addr, initrd_sz; @@ -424,10 +351,9 @@ void LoadInitrd(const char *partition, const char *filename, int *argc, char **a /* Add rd_start=, rd_size= */ sprintf(argv_rd_start, "rd_start=0x%lx", initrd_addr); sprintf(argv_rd_size, "rd_size=0x%lx", initrd_sz); - argv[*argc]=argv_rd_start; - (*argc)++; - argv[*argc]=argv_rd_size; - (*argc)++; + + prom_add_arg(argv_rd_start); + prom_add_arg(argv_rd_size); } @@ -457,95 +383,76 @@ void _start64(LONG argc, CHAR * argv[], CHAR * envp[], void _start(LONG argc, CHAR *argv[], CHAR *envp[]) { - CHAR** nargv; - CHAR** params; - int nargc, nopt; + CHAR **nargv; + CHAR **params; + char *bootpartition, *label, *kernelfile=NULL, *initrdfile=NULL; + int nargc, nopt; Elf32_Addr kernel_entry32; Elf64_Addr kernel_entry64; + prom_init(); + prom_init_malloc(); + /* Print identification */ printf(ANSI_CLEAR "\n\rarcsboot: ARCS Linux ext2fs loader " __ARCSBOOT_VERSION__ "\n\n\r"); - prom_init_malloc(); + prom_parse_args(argc, argv); - nopt = ProcessArguments(argc, argv); + label=prom_get_label(); + bootpartition=prom_get_partition(); -#if DEBUG - printf("Command line: \n\r"); - printCmdLine(argc, argv); + if (!bootpartition) + prom_fatal("No partition to boot\n\r"); +#if 1 + printf("label: %s\n\r", label); + printf("bootpartition: %s\n\r", bootpartition); #endif - if (nopt) { /* the user typed s.th. on the commandline */ - OSLoadFilename = argv[1]; - } + params=ReadConfFile(&bootpartition, CONF_FILE, label); - /* Fall back to "Linux" as default name. */ - if (OSLoadFilename == NULL) - OSLoadFilename = "Linux"; + if(!params) { + printf("Couldn't find label: %s in %s.\n\r", label, CONF_FILE); + printf("Will try to boot %s%s.\n\r", bootpartition, label); - if (OSLoadPartition == NULL) - prom_fatal("Invalid load partition\n\r"); -#if DEBUG - printf("OSLoadPartition: %s\n\r", OSLoadPartition); - printf("OSLoadFilename: %s\n\r", OSLoadFilename); -#endif - /* - * XXX: let's play stupid for now: assume /etc/arcboot.conf - * is on OSLoadPartition - */ - if( !(params = ReadConfFile(&OSLoadPartition, CONF_FILE, OSLoadFilename))) { - printf("Couldn't find label: %s in %s.\n\r", OSLoadFilename, CONF_FILE); - printf("Will try to boot %s%s.\n\r", OSLoadPartition, OSLoadFilename); - nargc = argc; - nargv = argv; + kernelfile=label; } else { - int i; - OSLoadFilename = params[2]; - nargv = ¶ms[2]; /* nargv[0] is the labels name */ - for( nargc=0; nargv[nargc]; nargc++); /* count nargv argumnts */ - if(OSLoadOptions != NULL) { /* append OSLoadOptions if present */ - nargv[nargc] = OSLoadOptions; - nargc++; - } - /* append command line arguments */ - for(i = 2; i <= nopt; i++) { - nargv[nargc] = argv[i]; - nargc++; + int i; + + initrdfile=params[1]; + kernelfile=params[2]; + + /* Add contents of config file to kernel arg line */ + for(i=3;params[i];i++) { + prom_add_arg(params[i]); } } - printf("Loading %s from %s\n\r",(params) ? params[0] : OSLoadFilename, OSLoadPartition); - kernel_entry64 = LoadKernel(OSLoadPartition, OSLoadFilename); - kernel_entry32 = (Elf32_Addr) kernel_entry64; -#if DEBUG - printf("Command line after config file: \n\r"); - printCmdLine(nargc, nargv); -#endif + printf("Loading %s from %s\n\r",kernelfile, bootpartition); + kernel_entry64 = LoadKernel(bootpartition, kernelfile); + kernel_entry32 = (Elf32_Addr) kernel_entry64; - if (params[1]) { - printf("Loading initrd %s from %s\n\r", params[1], OSLoadPartition); - LoadInitrd(OSLoadPartition, params[1], &nargc, nargv); + if(initrdfile) { + printf("Loading initrd %s from %s\n\r", initrdfile, bootpartition); + LoadInitrd(bootpartition, initrdfile); } -#if DEBUG - printf("Command line after initrd: \n\r"); - printCmdLine(nargc, nargv); - printf("Kernel entry: 0x%lx %lx\n\r", - (long)(kernel_entry64>>32),(long)(kernel_entry64&0xffffffff)); - prom_wait("\n\r--- Debug: press to boot kernel ---"); -#endif - if( kernel_entry64 ) { - if(is64==0){ - printf("Starting ELF32 kernel\n\r"); - prom_flush_cache_all(); - ((void (*)(int argc, CHAR * argv[], CHAR * envp[])) - kernel_entry32)(nargc ,nargv, envp); - } else { - printf("Starting ELF64 kernel\n\r"); - prom_flush_cache_all(); - _start64(nargc, nargv, envp, &kernel_entry64); - } + if(kernel_entry64) { + int kargc; + char **kargv; + + prom_get_karg(&kargc, &kargv); + + if(is64==0) { + printf("Starting ELF32 kernel\n\r"); + prom_flush_cache_all(); + ((void (*)(int argc, CHAR * argv[], CHAR * envp[])) + kernel_entry32)(kargc ,kargv, envp); + } else { + printf("Starting ELF64 kernel\n\r"); + prom_flush_cache_all(); + _start64(kargc, kargv, envp, &kernel_entry64); + } } else { printf("Invalid kernel entry NULL\n\r"); } -- cgit v1.2.3