Rest of monolithic CILO files.

master
Philippe Vachon 16 years ago
parent 03bcff8271
commit 327920bf55

@ -5,6 +5,8 @@ TEXTADDR=0x80008000
ifndef CROSS_COMPILE ifndef CROSS_COMPILE
CROSS_COMPILE=mips-elf- CROSS_COMPILE=mips-elf-
endif endif
CFLAGS=-DDEBUG -mno-abicalls
LDFLAGS=-Ttext ${TEXTADDR}
# Configuration for the Cisco 3660 Routers # Configuration for the Cisco 3660 Routers
# TARGET=c3600 # TARGET=c3600
@ -16,14 +18,15 @@ endif
# Configuration for the Cisco 1700 Series Routers # Configuration for the Cisco 1700 Series Routers
#TARGET=c1700 #TARGET=c1700
# MACHINE=0x33 #MACHCODE=0x33
#TEXTADDR=0x80008000 #TEXTADDR=0x80008000
#ifndef CROSS_COMPILE #ifndef CROSS_COMPILE
#CROSS_COMPILE=powerpc-elf- #CROSS_COMPILE=powerpc-elf-
#endif #endif
#LDFLAGS=-Ttext=${TEXTADDR}
# additional CFLAGS # additional CFLAGS
CFLAGS= CFLAGS+=
# don't modify anything below here # don't modify anything below here
# =================================================================== # ===================================================================
@ -42,13 +45,13 @@ RAW=${OBJCOPY} --strip-unneeded --alt-machine-code ${MACHCODE}
INCLUDE=-Iinclude/ -Imach/${TARGET} -Iinclude/mach/${TARGET} INCLUDE=-Iinclude/ -Imach/${TARGET} -Iinclude/mach/${TARGET}
CFLAGS+=-fno-builtin -fomit-frame-pointer -fno-pic -mno-abicalls \ CFLAGS+=-fno-builtin -fomit-frame-pointer -fno-pic \
-Wall -Wall
ASFLAGS=-D__ASSEMBLY__-xassembler-with-cpp -traditional-cpp ASFLAGS=-D__ASSEMBLY__-xassembler-with-cpp -traditional-cpp
LDFLAGS=--omagic -nostartfiles -nostdlib --discard-all --strip-all \ LDFLAGS+=--omagic -nostartfiles -nostdlib --discard-all --strip-all \
-Ttext ${TEXTADDR} --entry _start --entry _start
OBJECTS=string.o main.o ciloio.o printf.o elf_loader.o OBJECTS=string.o main.o ciloio.o printf.o elf_loader.o
@ -75,13 +78,11 @@ sub:
@for i in $(MACHDIR); do \ @for i in $(MACHDIR); do \
echo "Making all in $$i..."; \ echo "Making all in $$i..."; \
(cd $$i; $(MAKE) $(MFLAGS) $(THISFLAGS) all); done (cd $$i; $(MAKE) $(MFLAGS) $(THISFLAGS) all); done
(cd second/; $(MAKE) $(MFLAGS))
subclean: subclean:
@for i in $(MACHDIR); do \ @for i in $(MACHDIR); do \
echo "Cleaning all in $$i..."; \ echo "Cleaning all in $$i..."; \
(cd $$i; $(MAKE) $(MFLAGS) clean); done (cd $$i; $(MAKE) $(MFLAGS) clean); done
(cd second/; $(MAKE) $(MFLAGS) clean)
clean: subclean clean: subclean
-rm -f *.o -rm -f *.o

@ -22,23 +22,18 @@ target architecture is mips-elf and not mips-unknown-linux-gnu), just go
to the root directory of the source distribution and type make. Everything to the root directory of the source distribution and type make. Everything
should build from there. should build from there.
Next, build the second stage bootloader by going to the second/ directory Copy the ciscoload.bin file to the router's flash along with your kernel and
and typing make. set the router boot image to be ciscoload.bin.
Copy the ciscoload.bin and ciscoload.two files to the router's flash along
with your kernel and set the router boot image to be ciscoload.bin.
4. How do I use CILO? 4. How do I use CILO?
Assuming you have one of the supported routers, it is really quite easy. Assuming you have one of the supported routers, it is really quite easy.
In short, you must build CiscoLoad, build the stage-two loader and copy In short, you must build CiscoLoad and a kernel then copy them to your
them to your device's flash, typically using IOS. device's flash, typically using IOS.
When the router boots, it will load CILO; CILO then will prompt you to When the router boots, it will load CILO; CILO then will prompt you to
select the file you want to boot. Enter the file name you wish to boot, and select the file you want to boot. Enter the file name you wish to boot, and
away you go! away you go!
Of course, it makes sense to put your kernel on your flash device as well.
5. What hardware is supported? 5. What hardware is supported?
At this time, the Cisco 3600 Series of routers (3620 and 3640 at least) are At this time, the Cisco 3600 Series of routers (3620 and 3640 at least) are
very well supported. As well, preliminary support is underway for the very well supported. As well, preliminary support is underway for the

@ -19,10 +19,11 @@
void usage(const char *s) void usage(const char *s)
{ {
printf("usage: %s [-m] [elffile] [outfile]\n", s); printf("usage: %s [-m] [elffile] [outfile] [descrfile]\n", s);
printf("\t-m Generates an MZIP image\n"); printf("\t-m Generates an MZIP image\n");
printf("\t[elffile] Input ELF file\n"); printf("\t[elffile] Input ELF file\n");
printf("\t[outfile] Output image\n"); printf("\t[outfile] Output image\n");
printf("\t[descrfile] file containing textual description of image\n");
printf("The parameters of the format to be converted to are determined " printf("The parameters of the format to be converted to are determined "
"based\non the structure of the input ELF file.\n\n"); "based\non the structure of the input ELF file.\n\n");
} }
@ -64,14 +65,15 @@ int main(const int argc, const char *argv[])
struct elf32_phdr *phdr; struct elf32_phdr *phdr;
int i; int i;
char swap = 0; char swap = 0;
const char *file_in = argv[argc - 2]; const char *file_in = argv[argc - 3];
const char *file_out = argv[argc - 1]; const char *file_out = argv[argc - 2];
const char *file_desc = argv[argc - 1];
char mzip = 0; char mzip = 0;
printf("elf2img - Cisco Router Image Generation Utility.\n"); printf("elf2img - Cisco Router Image Generation Utility.\n");
printf("(c) 2009 Philippe Vachon <philippe@cowpig.ca>\n\n"); printf("(c) 2009 Philippe Vachon <philippe@cowpig.ca>\n\n");
if (argc < 2) { if (argc < 3) {
printf("Insufficient arguments.\n"); printf("Insufficient arguments.\n");
USAGE; USAGE;
return -1; return -1;
@ -241,13 +243,43 @@ int main(const int argc, const char *argv[])
mzip_print_header(&mz); mzip_print_header(&mz);
/* read in the description file */
FILE *fp_desc = fopen(file_desc, "r");
if (!fp_desc) {
printf("Unable to open description file.\n");
USAGE;
goto quit;
}
fseek(fp_desc, 0, SEEK_END);
uint32_t desc_len = ftell(fp_desc);
char *desc_buf = (char *)malloc(desc_len);
if (desc_buf == NULL) {
printf("Error while allocating memory for description buffer.\n");
goto quit;
}
rewind(fp_desc);
fread(desc_buf, desc_len, 1, fp_desc);
fclose(fp_desc);
printf("Descriptor:\n%s", desc_buf);
/* write out the MZIP file */ /* write out the MZIP file */
mzip_write_header(fp_out, &mz); mzip_write_header(fp_out, &mz);
mzip_write_codeseg(fp_out, zip_buf, seg_size); mzip_write_codeseg(fp_out, zip_buf, seg_size);
fseek(fp_out, 0, SEEK_END);
fwrite(desc_buf, desc_len, 1, fp_out);
quit:
if (zip_buf) free(zip_buf); if (zip_buf) free(zip_buf);
free(phdr); free(phdr);
free(desc_buf);
fclose(fp_in); fclose(fp_in);
fclose(fp_out); fclose(fp_out);
return 0; return 0;

@ -63,10 +63,9 @@ void load_elf32_uninitialized_memory(uint32_t address, uint32_t length)
* @param loader_addr address of the loader binary in memory * @param loader_addr address of the loader binary in memory
* @return * @return
*/ */
int load_elf32_file(struct file *fp) int load_elf32_file(struct file *fp, char *cmd_line)
{ {
struct elf32_header hdr; struct elf32_header hdr;
uint32_t mem_sz = 0; uint32_t mem_sz = 0;
/* read in header entries */ /* read in header entries */
@ -110,21 +109,6 @@ int load_elf32_file(struct file *fp)
uint32_t offset = 0xffffffff; uint32_t offset = 0xffffffff;
cilo_seek(fp, hdr.phoff, SEEK_SET); cilo_seek(fp, hdr.phoff, SEEK_SET);
/* read in program header(s), determine total memory size of image */
/* TODO: figure out if there's a better way to determine this */
for (i = 0; i < hdr.phnum; i++) {
cilo_read(&phdr, sizeof(struct elf32_phdr), 1, fp);
if (phdr.type != ELF_PT_LOAD) continue;
mem_sz += phdr.memsz;
if (phdr.paddr < offset) offset = phdr.paddr;
}
#ifdef DEBUG
printf("mem_sz = %08x\n", mem_sz);
#endif
/* read the PT_LOAD segments into memory at paddr + mem_sz */ /* read the PT_LOAD segments into memory at paddr + mem_sz */
cilo_seek(fp, hdr.phoff, SEEK_SET); cilo_seek(fp, hdr.phoff, SEEK_SET);
@ -134,35 +118,32 @@ int load_elf32_file(struct file *fp)
/* skip unloadable segments */ /* skip unloadable segments */
if (phdr.type != ELF_PT_LOAD) continue; if (phdr.type != ELF_PT_LOAD) continue;
/* uint32_t leftover = phdr.memsz - phdr.filesz; */ load_elf32_section(fp, phdr.paddr,
load_elf32_section(fp, mem_sz + phdr.paddr,
phdr.offset, phdr.filesz); phdr.offset, phdr.filesz);
/* if (leftover > 0) { mem_sz += phdr.memsz;
load_elf32_uninitialized_memory(mem_sz + phdr.paddr +
phdr.filesz, leftover); if (phdr.memsz - phdr.filesz > 0) {
} */ load_elf32_uninitialized_memory(phdr.paddr +
phdr.filesz, phdr.memsz - phdr.filesz);
}
cilo_seek(fp, hdr.phoff + sizeof(struct elf32_phdr) * (i + 1), cilo_seek(fp, hdr.phoff + sizeof(struct elf32_phdr) * (i + 1),
SEEK_SET); SEEK_SET);
} }
/* assume the entry point is the smallest address we're loading */ /* assume the entry point is the smallest address we're loading */
uint32_t load_offset = mem_sz + offset; printf("Loaded %d bytes.\n", mem_sz);
printf("Loaded %d bytes at %08x.\n", mem_sz, load_offset);
printf("Kicking into Linux.\n"); printf("Kicking into Linux.\n");
#ifdef DEBUG #ifdef DEBUG
printf("load_offset = 0x%08x\n", load_offset);
printf("hdr.entry = 0x%08x\n", hdr.entry); printf("hdr.entry = 0x%08x\n", hdr.entry);
printf("mem_sz = 0x%08x\n", mem_sz); printf("mem_sz = 0x%08x\n", mem_sz);
printf("offset = 0x%08x\n", offset);
#endif #endif
/* Jump to the copy routine */ ((void (*)(uint32_t mem_sz, char *cmd_line))(hdr.entry))
stage_two(load_offset, hdr.entry, mem_sz, offset); (c_memsz(), cmd_line);
return -1; /* something failed, badly */ return -1; /* something failed, badly */
} }

@ -7,6 +7,6 @@
void load_elf32_section(struct file *fp, uint32_t address, void load_elf32_section(struct file *fp, uint32_t address,
uint32_t file_offset, uint32_t length); uint32_t file_offset, uint32_t length);
void load_elf32_uninitialized_memory(uint32_t address, uint32_t length); void load_elf32_uninitialized_memory(uint32_t address, uint32_t length);
int load_elf32_file(struct file *fp); int load_elf32_file(struct file *fp, char *cmd_line);
#endif /* _ELF_LOADER_H */ #endif /* _ELF_LOADER_H */

@ -10,8 +10,5 @@
void platform_init(); void platform_init();
uint32_t check_flash(); uint32_t check_flash();
void flash_directory(); void flash_directory();
uint32_t locate_stage_two();
void stage_two(uint32_t kern_off, uint32_t kern_entry, uint32_t kern_size,
uint32_t kern_loadpt);
#endif /* _INCLUDE_MACH_C3600_PLATFORM_H */ #endif /* _INCLUDE_MACH_C3600_PLATFORM_H */

@ -42,28 +42,3 @@ void flash_directory()
f = (struct fs_ent *)(FLASH_BASE + offset); f = (struct fs_ent *)(FLASH_BASE + offset);
} }
} }
/**
* Locate the stage two loader for CiscoLoad for this particular platform
* returns 0 if not found, 1 if found
*/
uint32_t locate_stage_two()
{
return platio_find_file("ciscoload.two");
}
/**
* Kick into the stage two loader.
*/
void stage_two(uint32_t kern_off, uint32_t kern_entry, uint32_t kern_size,
uint32_t kern_loadpt)
{
uint32_t s2addr = ((uint32_t)find_file("ciscoload.two", FLASH_BASE)) +
sizeof(struct fs_ent);
((void (*)(uint32_t data_offset, uint32_t data_length, uint32_t entry_pt,
uint32_t load_offset)) (s2addr))
(kern_off, kern_size, kern_entry, kern_loadpt);
}

@ -71,13 +71,6 @@ void start_bootloader()
c_putc('O'); c_putc('O');
platform_init(); platform_init();
/* locate the stage two loader */
if (!locate_stage_two()) {
printf("\nError: Unable to find valid stage two loader. "
"Aborting load.\n");
return;
}
printf("\nCiscoLoader (CILO) - Linux bootloader for Cisco Routers\n"); printf("\nCiscoLoader (CILO) - Linux bootloader for Cisco Routers\n");
printf("Available RAM: %d kB\n", r); printf("Available RAM: %d kB\n", r);
@ -121,7 +114,7 @@ enter_filename:
printf("DEBUG: cmd_line: %s\n", cmd_line); printf("DEBUG: cmd_line: %s\n", cmd_line);
#endif #endif
printf("Booting %s.\n", kernel); printf("Booting %s.\n", kernel);
if (load_elf32_file(&kernel_file) if (load_elf32_file(&kernel_file, cmd_line)
< 0) < 0)
{ {
printf("Fatal error while loading kernel. Aborting.\n"); printf("Fatal error while loading kernel. Aborting.\n");

Loading…
Cancel
Save