aboutsummaryrefslogtreecommitdiff
path: root/ext2load/loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext2load/loader.c')
-rw-r--r--ext2load/loader.c201
1 files changed, 54 insertions, 147 deletions
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");
}