/* CiscoLoad - Bootloader for Cisco Routers * (c) 2008 Philippe Vachon * Licensed under the GNU General Public License v2 */ #include #include #include #include #include #include /* platform-specific defines */ #include #include /** * Dump 0x10 bytes of memory in canonical hexadecimal form * @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'; /* determine amount of RAM present */ c_putc('I'); r = c_memsz(); /* check flash filesystem sanity */ c_putc('L'); f = check_flash(); if (!f) { printf("\nError: Unable to find any valid flash! Aborting load.\n"); return; } c_putc('O'); 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("Available RAM: %d kB\n", r); printf("Available files:\n"); flash_directory(); enter_filename: printf("\nEnter filename to boot:\n> "); c_gets(buf, 128); /* 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'; } else { cmd_line[0] = '\0'; strncpy(kernel, buf, 48); } printf("\n\nAttempting to load file %s\n", kernel); struct file kernel_file = cilo_open(kernel); if (kernel_file.code == 0) { printf("Unable to find \"%s\" on the flash filesystem.\n", kernel); } else { #ifdef DEBUG printf("DEBUG: cmd_line: %s\n", cmd_line); #endif printf("Booting %s.\n"); if (load_elf32_file(&kernel_file) < 0) { printf("Fatal error while loading kernel. Aborting.\n"); } } goto enter_filename; /* return to ROMMON */ }