📄 bootldr.c
字号:
/****************************************************************************//* Copyright 2000 Compaq Computer Corporation. *//* . *//* Copying or modifying this code for any purpose is permitted, *//* provided that this copyright notice is preserved in its entirety *//* in all copies or modifications. COMPAQ COMPUTER CORPORATION *//* MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, AS TO THE USEFULNESS *//* OR CORRECTNESS OF THIS CODE OR ITS FITNESS FOR ANY PARTICULAR *//* PURPOSE. *//****************************************************************************//* * bootldr file for Compaq Personal Server Bootloader * *//* * Maintainer: Jamey Hicks (jamey@crl.dec.com) * Original Authors: Edwin Foo, Jamey Hicks, Dave Panariti, Mike Schexnaydre, Chris Joerg */static char bootprog_name[] = "Compaq OHH BootLoader";static char bootprog_date[] = DATE;static char cvsversion[] = "$Id: bootldr.c,v 1.13 2000/06/23 18:28:24 jamey Exp $";#define USE_XMODEM#define BOOT_ALTKERNEL#include "bootldr.h"#include "btpci.h"#include "btflash.h"#include "btusb.h"#include "heap.h"#include "xmodem.h"#include <asm-arm/setup.h>#include "sa1100.h"#include "bsdsum.h"#ifdef BZIPPED_KERNELS#define BZ_NO_STDIO#include "bzip/bzlib.h"#endif#define DEB(s) putstr(s) typedef unsigned long u_int32_t;typedef unsigned long pd_entry_t;#include "cyclone_boot.h" #define ROUNDUP(v,szpwr2) (((v)+((szpwr2)-1))&~(szpwr2-1))#if 0void reboot(void);#endifvoid enableMMU(void);void flushTLB(void);void writeBackDcache(unsigned long region);unsigned long readCPR1(void);unsigned long readCPR3(void);/* Boot Loader Function Prototypes */void print_help_on_commands(struct bootblk_command *commands);void command_help(int argc, const char **argv);void command_boot(int argc, const char **argv);void command_boot_flash(int argc, const char **argv);void command_boot_nfsroot(int argc, const char **argv);void command_load(int argc, const char **argv);void command_load_flash(int argc, const char **argv);void command_load_altkernel(int argc, const char **argv);void command_load_debugger(int argc, const char **argv);void command_load_ram(int argc, const char **argv);/* helper function */static void command_load_flash_region(const char *regionName, unsigned long regionBase, unsigned long regionSize, int flags);void command_load_bootldr(int argc, const char **argv);void command_load_usercode(int argc, const char **argv);void command_load_ramdisk(int argc, const char **argv);void command_load_params(int argc, const char **argv);void command_load_kernel(int argc, const char **argv);void command_boot_altkernel(int argc, const char **argv);void command_peek(int argc, const char **argv);void command_peek_ram(int argc, const char **argv);void command_poke(int argc, const char **argv);void command_poke_ram(int argc, const char **argv);void command_breakpoint(int argc, const char **argv);void command_qflash(int argc, const char **argv);void command_eflash(int argc, const char **argv);void command_pflash(int argc, const char **argv);#if 0void command_reboot(int argc, const char **argv);#endifvoid command_physaddr(int argc, const char **argv);void command_call(int argc, const char **argv);void command_set(int argc, const char **argv);struct bootblk_param *get_param(const char *name);int get_param_value(const char *name, void *value_p);void command_flash_type(int argc, const char **argv);void command_params(int argc, const char **argv);void command_params_show(int argc, const char **argv);void command_params_eval(int argc, const char **argv);void command_params_save(int argc, const char **argv);void testCirrusCardbusBridge(int argc, const char **argv);void parseargs(char *argstr, int *argc_p, char **argv);void unparseargs(char *argstr, int argc, const char **argv);byte awaitkey(unsigned long delay, int *error_p);void bootmenu(void);void monitorConfigureMMU(void);#ifdef GZIPPED_KERNELS int gunzip_region(char* src, char* dst, long len, const char *name);#endif/* Boot Loader Variables/Constants */static struct bootblk_command commands[] = { { "?", command_help, "?" }, { "help", command_help, "help <command>" }, { "help", command_help, "<command> help" }, { "boot", command_boot, "boot [flash|nfsroot|altkernel]" }, { "load", command_load, "load [kernel | ramdisk | bootldr | params | usercode]" }, { "peek", command_peek, "peek ram|flash|int|short|byte <addr>" }, { "poke", command_poke, "poke ram|flash|int|short|byte <addr>" },#ifdef CONFIG_BITSY { "breakpoint", command_breakpoint, "breakpoint" },#endif { "qflash", command_qflash, "qflash [cfi|id] <waddr> -- query flash" }, { "eflash", command_eflash, "eflash <sectoraddr>|chip -- erase sector or chip" }, { "pflash", command_pflash, "pflash <sectoraddr>|chip -- protect sector or chip" },#if 0 { "reboot", command_reboot, "reboot" },#endif { "physaddr", command_physaddr, "physaddr <vaddr> -- returns <paddr>" }, /* { "testusb", testUSB, "testusb" },*/ { "call", command_call, "call <addr> args" }, { "jump", command_call, "jump <addr>" }, { "set", command_set, "set <param> <value>" }, { "show", command_params_show, "show [<param>]" }, { "evalparams", command_params_eval, "evalparams"}, { "params", command_params, "params [eval|show|save|reset]"}, { "flash_type", command_flash_type, "flash_type <flashtype>"},#if 0 { "cardbus", testCirrusCardbusBridge, "cardbus" },#endif { NULL, NULL, NULL }};static struct bootblk_command boot_commands[] = { { "flash", command_boot_flash, "boot flash [bootargs ...]" },#ifdef BOOT_ALTKERNEL { "altkernel", command_boot_altkernel, "boot altkernel [bootargs ...]" },#endif { "nfsroot", command_boot_nfsroot, "boot nfsroot [bootargs ...]" }, { NULL, NULL, NULL }};static struct bootblk_command load_commands[] = { { "kernel", command_load_kernel, "load kernel" }, { "bootldr", command_load_bootldr,"load bootldr" },#ifdef BOOT_ALTKERNEL { "altkernel", command_load_altkernel, "load altkernel (alternate kernel)" },#endif { "usercode", command_load_usercode,"load usercode" }, { "ramdisk", command_load_ramdisk,"load ramdisk" }, { "params", command_load_params,"load params" }, { "ram", command_load_ram, "load ram <dstaddr>" }, { "flash", command_load_flash, "load flash <dstaddr>" }, { "debugger", command_load_debugger, "load debugger" }, { NULL, NULL, NULL }};static struct bootblk_command peek_commands[] = { { "ram", command_peek_ram, "peek ram <addr> reads 32 bits" }, { "byte", command_peek_ram, "peek byte <addr> reads 8 bits" }, { "short", command_peek_ram, "peek short <addr> reads 16 bits" }, { "int", command_peek_ram, "peek int <addr> reads 32 bits" }, { "flash", command_peek_ram, "peek flash <offset>" }, { "gpio", command_peek_ram, "peek gpio <offset>" }, { NULL, NULL, NULL }};static struct bootblk_command poke_commands[] = { { "ram", command_poke_ram, "poke ram <addr> <dword>" }, { "byte", command_poke_ram, "poke byte <addr> <byte> writes 8 bits" }, { "short", command_poke_ram, "poke short <addr> <word> writes 16 bits" }, { "int", command_poke_ram, "poke int <addr> <dword> writes 32 bits" }, { "flash", command_poke_ram, "poke flash <offset> <dword>" }, { "gpio", command_poke_ram, "poke gpio <offset> <dword>" }, { NULL, NULL, NULL }};static struct bootblk_command params_commands[] = { { "eval", command_params_eval, "params eval" }, { "show", command_params_show, "params show" }, { "save", command_params_save, "params save" }, { "reset", command_params, "params reset" }, { NULL, NULL, NULL }};static struct bootblk_param bootldr_params[] = {#define UPDATE_BAUDRATE#ifdef UPDATE_BAUDRATE { "baudrate", PT_INT, PF_HEX, UART_BAUD_RATE, update_baudrate }, #endif { "os", PT_STRING, PF_STRING, (long)"autoselect", NULL }, /* "linux", "netbsd", "autoselect" */ { "boot_type", PT_STRING, PF_STRING, (long)"flash", NULL }, { "download_kernel", PT_INT, PF_HEX, 0, NULL }, { "kernel_in_ram", PT_INT, PF_HEX, 0, NULL }, /* set this to the address of where kernel is loaded in ram (0xC0008000) */ { "force_unzip", PT_INT, PF_HEX, 0, NULL }, { "noerase", PT_INT, PF_HEX, 0, NULL }, { "override", PT_INT, PF_HEX, 0, NULL }, #ifdef CONFIG_SKIFF { "entry", PT_INT, PF_HEX, 0x00000000, NULL }, #else { "entry", PT_INT, PF_HEX, 0xC0000000, NULL }, #endif { "copy_ramdisk", PT_INT, PF_HEX, 0, NULL }, { "dram_size", PT_INT|PT_READONLY, PF_HEX, DRAM_SIZE, NULL }, { "dcache_enabled", PT_INT, PF_HEX, 0x1, update_dcache_enabled }, { "icache_enabled", PT_INT, PF_HEX, 0x1, update_icache_enabled }, { "memc_ctrl_reg", PT_INT, PF_HEX, 0x110c, NULL },#ifdef CONFIG_PCI { "mem_fclk_21285", PT_INT|PT_READONLY, PF_DECIMAL, 48000000, NULL }, { "maclsbyte", PT_INT, PF_HEX, 0xFF, program_all_eeprom },#endif { "serial_number", PT_INT|PT_READONLY, PF_HEX, 0xFF, set_serial_number }, { "system_rev", PT_INT|PT_READONLY, PF_HEX, 0x01, set_system_rev },#ifdef CONFIG_SKIFF { "linuxargs", PT_STRING, PF_STRING, (long)" root=/dev/ram initrd ramdisk_size=8192", NULL },#else { "linuxargs", PT_STRING, PF_STRING, (long)" root=/dev/ram initrd ramdisk_size=8192", NULL },#endif { "hostname", PT_STRING, PF_STRING, 0, NULL }, { "ipaddr", PT_STRING, PF_STRING, 0, NULL }, { "gateway", PT_STRING, PF_STRING, 0, NULL }, { "netmask", PT_STRING, PF_STRING, 0, NULL }, { "nfs_server_address", PT_STRING, PF_STRING, 0, NULL }, { "nfsroot", PT_STRING, PF_STRING, 0, NULL }, { "xmodem", PT_INT, PF_HEX, 1, NULL }, { "verbose", PT_INT, PF_HEX, 0, NULL }, { NULL, PT_NONE, PF_HEX, 0, NULL }};struct bootblk_param *get_param(const char *name){ struct bootblk_param *param = bootldr_params; while (param->name != NULL) { int namelen = strlen(param->name); if (strncmp(name, param->name, namelen) == 0 && name[namelen] == 0) { return param; } param++; } putstr("get_param: could not find parameter "); putstr(name); putstr("\r\n"); return NULL;}int get_param_value(const char *name, void *value_p){ struct bootblk_param *param = get_param(name); if (param != NULL) { if (value_p != NULL) *(long *)value_p = param->value; return 0; } else { return -1; } }#ifdef CONFIG_BITSY/* The EGPIO is a write only control register at physical address 0x49000000 * See the hardware spec for more details. */static int egpio = EGPIO_BITSY_RS232_ON;static void set_egpio(int mask){ egpio |= mask; *(volatile int *)BITSY_EGPIO = egpio;}static void clr_egpio(int mask){ egpio &= ~mask; *(volatile int *)BITSY_EGPIO = egpio;}#define SET_VPPEN() set_egpio(EGPIO_BITSY_VPEN)#define CLR_VPPEN() clr_egpio(EGPIO_BITSY_VPEN)#else#define SET_VPPEN() #define CLR_VPPEN() #endif/* * this variable MUST be initialized explicitly to zero to prevent its * placement in the BSS. */enum { mmue_enabled = 99, mmue_notenabled = 101};byte mmuEnabled = mmue_notenabled; /* we set this after we call enableMMU() */#define isMmuEnabled() (mmuEnabled == mmue_enabled)#define setMmuEnabled() (mmuEnabled = mmue_enabled)#ifdef NoLibC/* * very simple memcpy to blast bits around from place to place */void *memcpy(char *dst, const char *src, long n){ if ( (((dword)dst)&3) == 0 && (((dword)src)&3) == 0 && (n&3) == 0 ) { unsigned long *ca,*cb; for (ca = (unsigned long *)dst, cb = (unsigned long *)src; n > 0;n -= 4) *ca++ = *cb++; } else { byte *ca,*cb; for (ca = (byte *)dst, cb = (byte *)src; n-- > 0;) *ca++ = *cb++; } return dst;}/* * memset routine: fills first n bytes of dst with value c */void memset(void *dst, char c, unsigned long n){ byte *ca; for (ca = (byte *)dst; n-- > 0; ) *ca++ = c;}int strlen(const char *s){ int l = 0; while (*s++ != 0) l++; return l;}char *strcat(char *dest, const char *src){ char c; int len = strlen(dest); dest += len; while (( *dest++ = *src++) != 0) { }}int strncmp(const char *s1, const char *s2, int len){ int i = 0; int c1, c2; if (s1 == NULL || s2 == NULL) return -1; for (c1 = s1[i], c2 = s2[i]; i < len; c1 = s1[i], c2 = s2[i], i++) { if (c1 < c2) return -1; else if (c1 > c2) return 1; else continue; } return 0;}int strcmp(const char *s1, const char *s2){ int l1 = strlen(s1); int l2 = strlen(s2); int l = (l1 < l2) ? l1 : l2; int result = strncmp(s1, s2, l); if (l == 0 && (l1 != l2)) { if (l1 < l2) return -1; else return 1; } else { return result; }}char *strchr(const char *s, int c){ char sc; while (((sc = *s) != c) && sc != 0) { s++; } if (sc == c) return (char *)s; else return NULL;}#endif /* NoLibC */void putc(char c) { /* wait for space in the TX FIFO */#ifdef CONFIG_SKIFF while (CSR_READ_BYTE(UARTFLG_REG) & UART_TX_FIFO_BUSY); CSR_WRITE_BYTE(UARTDR_REG,c);#elif defined(CONFIG_BITSY) while (!((*(volatile long *)SA1100_UART3_UTSR1) & SA1100_UTSR1_TNF)); /* wait until TX FIFO not full */ *(byte *)SA1100_UART3_UTDR = c;#else#error no definition for putc for this architecture#endif}void putstr(const char *str){ extern void *Ser3Base; if (str == NULL) return; while (*str != '\0') {#ifdef CONFIG_BITSY PrintChar(*str, Ser3Base) ;#else putc(*str) ;#endif str++ ; }}#ifdef ZBSS/* * zero bss (using no bss vars!) */voidzbss(void){ char* start; unsigned len; aout_header* hdrp; hdrp = (aout_header*)FLASH_BASE; start = (char*)hdrp + hdrp->a_text + hdrp->a_data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -