You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
3.2 KiB
C

16 years ago
/* CiscoLoad - Bootloader for Cisco Routers
* (c) 2008 Philippe Vachon <philippe@cowpig.ca>
* Licensed under the GNU General Public License v2
*/
#include <printf.h>
#include <addr.h>
#include <elf.h>
#include <elf_loader.h>
#include <ciloio.h>
#include <promlib.h>
16 years ago
/* platform-specific defines */
#include <platform.h>
16 years ago
#include <string.h>
16 years ago
/**
* Dump 0x10 bytes of memory in canonical hexadecimal form
16 years ago
* @param addr Starting address to dump from
*/
void hex_dump(uint32_t addr)
{
uint8_t *rgn = (uint8_t *)addr;
int i;
/* print out the address of the 16 bytes of interest */
printf("%8x " , addr);
/* print out hex value for individual bytes */
for (i = 0; i < 16; i++) {
printf("%02x ", rgn[i]);
}
/* print out as chars */
for (i = 0; i < 16; i++) {
printf("%c", rgn[i] >= 32 && rgn[i] <= 126 ? rgn[i] : '.');
}
printf("\n");
}
/**
* Entry Point for CiscoLoad
*/
void start_bootloader()
{
int r = 0;
int f;
char buf[129];
char *cmd_line = (char *)MEMORY_BASE;
char kernel[49];
const char *cmd_line_append;
buf[128] = '\0';
kernel[48] = '\0';
16 years ago
/* determine amount of RAM present */
c_putc('I');
r = c_memsz();
/* check flash filesystem sanity */
c_putc('L');
f = check_flash();
16 years ago
if (!f) {
printf("\nError: Unable to find any valid flash! Aborting load.\n");
return;
}
c_putc('O');
platform_init();
16 years ago
/* locate the stage two loader */
if (!locate_stage_two()) {
16 years ago
printf("\nError: Unable to find valid stage two loader. "
"Aborting load.\n");
return;
}
printf("\nCiscoLoader (CILO) - Linux bootloader for Cisco Routers\n");
printf("Available RAM: %d kB\n", r);
printf("Available files:\n");
flash_directory();
enter_filename:
16 years ago
printf("\nEnter filename to boot:\n> ");
c_gets(buf, 128);
int baud = c_baud(); /* get console baud rate */
printf("Boot console baud rate: %d\n", baud);
/* determine if a command line string has been appended to kernel name */
if ((cmd_line_append = strchr(buf, ' ')) != NULL) {
strcpy(cmd_line, (char *)(cmd_line_append + 1));
/* extract the kernel file name now */
uint32_t kernel_name_len = cmd_line_append - buf;
strncpy(kernel, buf, kernel_name_len);
kernel[kernel_name_len + 1] = '\0';
/* determine if console is set in the command line; if not,
* append it.
*/
if (!strstr(cmd_line,"console")) {
sprintf(cmd_line, "%s console=ttyS0,%d", cmd_line, baud);
}
} else {
strncpy(kernel, buf, 48);
sprintf(cmd_line, "console=ttyS0,%d", baud);
}
printf("\n\nAttempting to load file %s\n", kernel);
16 years ago
struct file kernel_file = cilo_open(kernel);
16 years ago
if (kernel_file.code == 0) {
printf("Unable to find \"%s\" on the flash filesystem.\n", kernel);
16 years ago
} else {
#ifdef DEBUG
printf("DEBUG: cmd_line: %s\n", cmd_line);
#endif
printf("Booting %s.\n", kernel);
if (load_elf32_file(&kernel_file)
16 years ago
< 0)
{
printf("Fatal error while loading kernel. Aborting.\n");
}
}
goto enter_filename;
16 years ago
/* return to ROMMON */
}