aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Lohoff <flo@rfc822.org>2008-10-05 11:42:41 +0000
committerGuido G√ľnther <agx@sigxcpu.org>2009-04-26 15:26:26 +0200
commit2fbf57533b7037c7b21c6c00a766fee91dd1b8c7 (patch)
tree17e8cc815570f9375833a57de3083d576e76c7a4
parent9a9e8c11088f1772eb7070e4e1ab1c8d5b4bc528 (diff)
Move arg handling to prom code
-rw-r--r--arclib/prom.c106
-rw-r--r--common/prom.h7
-rw-r--r--ext2load/conffile.c2
-rw-r--r--ext2load/loader.c201
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 <stdlib.h>
+#include <subarch.h>
#include <stdio.h>
+#include <string.h>
+
#include "arc.h"
#include "prom.h"
-#include <stddef.h>
-#include <stdlib.h>
-#include <subarch.h>
+#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 <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <types.h>
#include <stdint.h>
#include <arc.h>
@@ -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 = &params[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 <spacebar> 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");
}