summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien BLACHE <jblache@debian.org>2007-09-26 13:13:36 +0200
committerGuido Guenther <agx@sigxcpu.org>2007-11-21 16:06:48 +0100
commitf577c71678df55756b7f41838a9c1eb9b2fdb7e8 (patch)
tree6c6b6431a340aee08d5aeb7af46634dd7a3eb51b
parent7ad3285e7ff99cd2b586620869dedfd2c84588e1 (diff)
arcboot initrd support patch
Hi Guido, Attached is a proposed patch for initrd support in arcboot. It's mostly based on an old patch submitted long ago, with some changes. I'm using what should be the max page size for the machine to align the initrd address, that's the offset of the first section of the ELF image (found that in IRIX' elf manpage, thought it'd be nice to be able to load kernels with different page sizes). I've changed the order of the params[] array slightly to add the initrd to the mix. It looks like gcc 4.2 brings a ton of new warnings while building arcboot :/ Tested on IP22 with a standard debian initrd. JB. -- Julien BLACHE <jblache@debian.org> | Debian, because code matters more Debian & GNU/Linux Developer | <http://www.debian.org> Public key available on <http://www.jblache.org> - KeyID: F5D6 5169 GPG Fingerprint : 935A 79F1 C8B3 3521 FD62 7CC7 CD61 4FD7 F5D6 5169 Signed-off-by: Guido Guenther <agx@sigxcpu.org>
-rw-r--r--ext2load/conffile.c21
-rw-r--r--ext2load/loader.c72
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 = &params[1]; /* nargv[0] is the labels name */
+ 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;
@@ -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 ---");