diff options
Diffstat (limited to 'ext2load')
-rw-r--r-- | ext2load/conffile.c | 21 | ||||
-rw-r--r-- | ext2load/loader.c | 72 |
2 files changed, 81 insertions, 12 deletions
diff --git a/ext2load/conffile.c b/ext2load/conffile.c index 518ccf1..dbdfaa4 100644 --- a/ext2load/conffile.c +++ b/ext2load/conffile.c @@ -19,8 +19,9 @@ #define _PARM_LIMIT 32 -static char *carray[_PARM_LIMIT+3]; /* 0 is the name, - 1 the boofile, ... +static char *carray[_PARM_LIMIT+4]; /* 0 is the name, + 1 an initrd, + 2 the bootfile, X is OSLoadOptions X+1 ... _PARM_LIMIT are options given on the command line */ @@ -70,18 +71,20 @@ CHAR** GetConfig(char* config, char* name) if (((strcmp(carray[0], name) == 0) && (strcmp(name, carray[0]) == 0))) { return carray; } - /* Reset image & append */ - carray[1]=carray[2]=0; + /* Reset initrd & image & append */ + carray[1]=carray[2]=carray[3]=0; carray[0]=&start[6]; } else if (strncmp("image=",start,6) == 0) { - carray[1]=&start[6]; + carray[2]=&start[6]; + } else if (strncmp("initrd=",start,7) == 0) { + carray[1]=&start[7]; } else if (strncmp("append=",start,7) == 0) { t=&start[7]; /* Does append start with " */ if (*t == '"') { t++; /* If so - append starts +1 */ - carray[2]=t; + carray[3]=t; /* Search ending quote */ while(*t != '"' && *t != 0x0) t++; @@ -89,9 +92,9 @@ CHAR** GetConfig(char* config, char* name) if (*t == '"') *t=0x0; } else - carray[2]=&start[7]; - t=carray[2]; - i=3; + carray[3]=&start[7]; + t=carray[3]; + i=4; while(i<_PARM_LIMIT && *t != 0x0) { t++; diff --git a/ext2load/loader.c b/ext2load/loader.c index f8036e9..362b368 100644 --- a/ext2load/loader.c +++ b/ext2load/loader.c @@ -26,6 +26,11 @@ #define ANSI_CLEAR "\033[2J" #define CONF_FILE "/etc/arcboot.conf" +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; @@ -191,6 +196,10 @@ int LoadProgramSegments32(ext2_file_t file, Elf_Ehdr * header, void *segments) printf("Loading 32-bit executable\n\r"); for (idx = 0; idx < header->header32.e_phnum; idx++) { + if(max_page_size == 0) { + max_page_size = segment->p_offset; + } + if (segment->p_type == PT_LOAD) { printf ("Loading program segment %u at 0x%x, offset=0x%x, size = 0x%x\n\r", @@ -251,6 +260,10 @@ int LoadProgramSegments64(ext2_file_t file, Elf_Ehdr * header, void *segments) printf("Loading 64-bit executable\n\r"); for (idx = 0; idx < header->header64.e_phnum; idx++) { + if(max_page_size == 0) { + max_page_size = segment->p_offset; + } + if (segment->p_type == PT_LOAD) { printf ("Loading program segment %u at 0x%x, " "offset=0x%lx %lx, size = 0x%lx %lx\n\r", @@ -303,7 +316,6 @@ int LoadProgramSegments64(ext2_file_t file, Elf_Ehdr * header, void *segments) void LoadProgramSegments(ext2_file_t file, Elf_Ehdr * header) { - int idx; Boolean loaded = False; void *segments; size_t size; @@ -452,6 +464,49 @@ Elf64_Addr LoadKernel(const char *partition, const char *filename) return LoadKernelFile(file); } + +void LoadInitrd(const char *partition, const char *filename, int *argc, char **argv) +{ + ext2_file_t file; + UCHAR *initrd_addr; + ULONG initrd_sz; + int status; + + if (!OpenFile(partition, filename, &file)) + Fatal("Can't load initrd!\n\r"); + + initrd_sz = ext2fs_file_get_size(file); + + initrd_addr = malloc(initrd_sz + max_page_size); + + if (initrd_addr == NULL) { + Fatal("Cannot allocate memory for initrd\n\r"); + } + + initrd_addr = ((ULONG)initrd_addr + max_page_size) & ~(max_page_size - 1); + + printf("Loading initrd at 0x%p, %u bytes...\n\r", initrd_addr, initrd_sz); + + arc_do_progress = 1; + status = ext2fs_file_read(file, + KSEG0ADDR((ULONG)initrd_addr), + initrd_sz, NULL); + arc_do_progress = 0; + if (status != 0) { + print_ext2fs_error(status); + Fatal("Cannot read initrd\n\r"); + } + + /* Add rd_start=, rd_size= */ + sprintf(argv_rd_start, "rd_start=0x%x", initrd_addr); + sprintf(argv_rd_size, "rd_size=0x%x", initrd_sz); + argv[*argc]=argv_rd_start; + (*argc)++; + argv[*argc]=argv_rd_size; + (*argc)++; +} + + void printCmdLine(int argc, CHAR *argv[]) { int i; @@ -520,8 +575,8 @@ void _start(LONG argc, CHAR *argv[], CHAR *envp[]) nargv = argv; } else { int i; - OSLoadFilename = params[1]; - nargv = ¶ms[1]; /* nargv[0] is the labels name */ + 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; @@ -536,9 +591,20 @@ void _start(LONG argc, CHAR *argv[], CHAR *envp[]) 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 + + if (params[1]) { + printf("Loading initrd %s from %s\n\r", params[1], OSLoadPartition); + LoadInitrd(OSLoadPartition, params[1], &nargc, nargv); + } + +#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)); Wait("\n\r--- Debug: press <spacebar> to boot kernel ---"); |