📄 bootldr.c
字号:
#define PARAM_PREFIX ("bootldr:")/* #define DEBUG_COMMAND_PARAMS_EVAL 1 */void command_params_eval(int argc, const char **argv){ char* p; char* endp; char* prefix; int cmdnum; char cmdbuf[1024]; char* cmdp; int just_show = 0; int my_argc; char *my_argv[128]; if (argc > 1) just_show = (strncmp(argv[1], "-n", 2) == 2); putstr("eval param blk\r\n"); p = ((char*)flashword) + flashDescriptor->params.base; endp = p + flashDescriptor->params.size; /* stops at end of sector or first unwritten byte */ while (p < endp && *p != 0xff && *p != 0) {#ifdef DEBUG_COMMAND_PARAMS_EVAL putLabeledWord("top of loop, p=", (dword)p);#endif prefix = PARAM_PREFIX; while (p < endp && *prefix && *p == *prefix) { p++; prefix++; }#ifdef DEBUG_COMMAND_PARAMS_EVAL putLabeledWord("past prefix check, p=", (dword)p);#endif if (*prefix != '\0') {#ifdef DEBUG_COMMAND_PARAMS_EVAL putstr("no prefix match\r\n");#endif /* skip to end of line */ while (p < endp && *p != '\n') p++;#ifdef DEBUG_COMMAND_PARAMS_EVAL putLabeledWord("skipped line, p=", (dword)p); putLabeledWord("char at p=", (dword)(*p) & 0xff);#endif p++; continue; } /* copy line to buffer */ /* terminate with eof, or eol */ cmdp = cmdbuf; while (p < endp && *p != 0xff) { if (*p == '\r' || *p == '\n') { p++; if (*p == '\r' || *p == '\n') p++; break; } *cmdp++ = *p++; } *cmdp = '\0'; cmdp = cmdbuf; putstr("+"); putstr(cmdbuf); putstr("\r\n"); if (just_show) continue; memset(my_argv, 0, sizeof(my_argv)); parseargs(cmdbuf, &my_argc, my_argv); execcmd(commands, my_argc, (const char **)my_argv); }}int main(){ char c; /* At this stage, we assume: SDRAM is configured. UART is configured and ready to go. Initial PCI setup is done. Interrupts are OFF. MMU is DISABLED */ #ifdef DEBUG putstr("\r\nBOOT");#endif#ifdef CONFIG_PCI /* Configure the PCI devices */#ifdef DEBUG putstr(" PCI");#endif bootConfigurePCI();#endif putLabeledWord("MMU table start=", (dword)mmu_table); putLabeledWord("Boot data start=", (dword)BOOT_DATA_START); putLabeledWord("Boot data size=", (dword)BOOT_DATA_SIZE); putLabeledWord("Stack data base=", (dword)STACK_BASE); putLabeledWord("Stack data size=", (dword)STACK_SIZE); /* * set up MMU table: * DRAM is cacheable * cached and uncached images of Flash * after MMU is enabled, bootldr is running in DRAM */ bootConfigureMMU(); writeBackDcache(CACHE_FLUSH_BASE); enableMMU(); /* initialize the heap */ mmalloc_init((unsigned char *)(HEAP_START), HEAP_SIZE); flashword = (unsigned long *)UNCACHED_FLASH_BASE; putLabeledWord("flashword=", (unsigned long)flashword); /* figure out what kind of flash we have */ btflash_init(); { struct bootblk_param *system_rev_param = get_param("system_rev"); struct bootblk_param *dram_size_param = get_param("dram_size");#ifdef CONFIG_SKIFF struct bootblk_param *mem_fclk_21285_param = get_param("mem_fclk_21285");#endif long system_rev = get_system_rev(); long dram_size;#ifdef CONFIG_SKIFF dram_size = ((system_rev&SYSTEM_REV_MAJOR_MASK) == SYSTEM_REV_SKIFF_V2) ? DRAM_SIZE : SZ_16M;#endif#ifdef CONFIG_BITSY /* assumes one bank of DRAM and that DRAM_BASE0 is not in the cache */ *(long *)(DRAM_BASE0 + SZ_64M) = SZ_64M; *(long *)(DRAM_BASE0 + SZ_32M) = SZ_32M; *(long *)(DRAM_BASE0 + SZ_16M) = SZ_16M; dram_size = *(long *)DRAM_BASE0;#endif#ifdef CONFIG_SKIFF if (system_rev_param != NULL) system_rev_param->value = system_rev; if (dram_size_param != NULL) dram_size_param->value = dram_size; putLabeledWord("system_rev: ", system_rev); switch (system_rev & SYSTEM_REV_MEMCLK_MASK) { case SYSTEM_REV_MEMCLK_60MHZ: mem_fclk_21285_param->value = 60000000; break; case SYSTEM_REV_MEMCLK_48MHZ: mem_fclk_21285_param->value = 48000000; break; case SYSTEM_REV_MEMCLK_33MHZ: default: mem_fclk_21285_param->value = 33333333; break; } putstr("memclk_hz: "); putstr(((system_rev & SYSTEM_REV_MEMCLK_MASK) == SYSTEM_REV_MEMCLK_33MHZ) ? "33MHz\r\n" : "48MHz\r\n");#endif putLabeledWord("dram_size: ", dram_size); bootinfo.bt_memend = dram_size; } /* print the opening banner */ print_banner();#define EVAL_PARAMS_BLOCK#ifdef EVAL_PARAMS_BLOCK command_params_eval(0, NULL);#else putstr("not evaluating params\r\n");#endif c = awaitkey(TIMEOUT, NULL); if ((c != '\r') && (c != '\n') && (c != '\0')) { putstr("type \"?\" or \"help\" for help.\r\n"); bootmenu(); /* does not return */ } while (1) { /* default boot */ int my_argc = 1; char *my_argv[128]; my_argv[0] = "boot"; my_argv[1] = NULL; execcmd(commands, my_argc, (const char **)my_argv); /* if default boot fails, drop into the bootmenu */ bootmenu(); }}void print_help_on_commands(struct bootblk_command *commands){ int i = 0; while (commands[i].cmdstr != NULL) { putstr(commands[i].helpstr); putstr("\r\n"); i++; }}/* no arguments */void command_help(int argc, const char **argv){ int i = 0; putstr("Available Commands:\r\n"); if (argc == 2 && (strcmp(argv[1], "help") != 0)) { /* help <command> * invoke <command> with 'help' as an argument */ argv[0] = argv[1]; argv[1] = "help"; argv[2] = NULL; execcmd(commands, argc, argv); return; } print_help_on_commands(commands);}/* can have arguments or not */void command_boot(int argc, const char **argv){ if (argv[1] == NULL) { char *boot_type; get_param_value("boot_type", &boot_type); argv[1] = boot_type; argc++; } putstr("booting "); putstr(argv[1]); putstr("...\r\n"); execcmd(boot_commands,argc-1,argv+1);}/* can have arguments or not */void command_flash_type(int argc, const char **argv){ if (argc == 1) { /* print the available flash types */ btflash_print_types(); } else { /* manually set the flash type */ btflash_set_type(argv[1]); }}/* can have arguments or not */void command_params(int argc, const char **argv){ if (argc == 2) { if (strcmp(argv[1], "reset") == 0) { putstr("setting params to default values\r\n"); memcpy((char*)bootldr_params, (const char*)(((char*)flashword) + (((dword)bootldr_params) - FLASH_BASE)), sizeof(bootldr_params)); return; } } else if (argv[1] == NULL) { argv[1] = "show"; argc++; } execcmd(params_commands,argc-1,argv+1);}void setup_linux_params(long bootimg_dest, long initrd_start, long initrd_size, long memc_ctrl_reg, long mem_fclk_21285, long dram_size, const char *cmdline, int flashroot){ struct param_struct *params = (struct param_struct *)(bootimg_dest + 0x100); int system_rev = get_param("system_rev")->value; long copy_ramdisk = 0; long first_word_of_ramdisk = *(long *)(FLASH_BASE + flashDescriptor->ramdisk.base); int rootdev = 0x00ff; int using_ramdisk = flashroot; get_param_value("copy_ramdisk", ©_ramdisk); putLabeledWord("first_word_of_ramdisk=", first_word_of_ramdisk); if (flashroot && (first_word_of_ramdisk == 0x28cd3d45)) { /* cramfs */ copy_ramdisk = 0; rootdev = 0x3c02; using_ramdisk = 0; } if (!flashroot) { copy_ramdisk = 0; } putLabeledWord("Setting up Linux parameters at address=", (unsigned long)params); memset(params, 0, sizeof(struct param_struct)); params->u1.s.page_size = LINUX_PAGE_SIZE; params->u1.s.nr_pages = (dram_size >> LINUX_PAGE_SHIFT); params->u1.s.ramdisk_size = 0; /* seems to be duplicate of initrd_size */ params->u1.s.rootdev = rootdev; params->u1.s.flags = 0; if (using_ramdisk) { if (copy_ramdisk) { /* virtual address using Linux MMU settings */ params->u1.s.initrd_start = (long)(initrd_start&0x0FFFFFFF) + 0xC0000000; } else { /* virtual flash address using Linux MMU settings */#ifdef CONFIG_SKIFF params->u1.s.initrd_start = 0xf8000000 + flashDescriptor->ramdisk.base + 4; #else params->u1.s.initrd_start = 0xd0000000 + flashDescriptor->ramdisk.base + 4; /* skip past the size word */#endif } params->u1.s.initrd_size = initrd_size; params->u1.s.rd_start = 0; /* seems to be a duplicate of initrd_start */ } putLabeledWord("using_ramdisk=", using_ramdisk); putLabeledWord("initrd_start=", params->u1.s.initrd_start); params->u1.s.system_rev = 0x0200; /* skiff-v2 A */ params->u1.s.system_serial_low = 22; params->u1.s.memc_control_reg = memc_ctrl_reg;#if PARAMS_HAS_FCLK_21285 params->u1.s.mem_fclk_21285 = mem_fclk_21285;#endif memcpy(params->commandline, cmdline, strlen(cmdline)+1); putLabeledWord("dram_size=", dram_size); putLabeledWord("nr_pages=", params->u1.s.nr_pages); putstr("command line is: "); putstr(cmdline); putstr("\r\n");}/* * boot_kernel * root_filesystem_name: * kernel_region_start: virtual address of region holding kernel image * kernel_region_size: size of region holding kernel image * argc: number of arguments in argv (including argv[0], the command name) * argv: argument vector (including argv[0], the command name) */static void boot_kernel(const char *root_filesystem_name, vaddr_t kernel_region_start, size_t kernel_region_size, int argc, const char **argv){ unsigned long boot_magic = *(unsigned long *)(kernel_region_start+0); unsigned long kernel_image_size = *(unsigned long *)(kernel_region_start+4); unsigned long kernel_image_dest = *(unsigned long *)(kernel_region_start+8); vaddr_t kernel_image_start = kernel_region_start + 12; unsigned long kernel_image_first_word = *(dword*)kernel_image_start; unsigned long kernel_image_tenth_word = *(dword*)(kernel_image_start+40); unsigned long kernel_image_maxsize = kernel_region_size; int unzipped = 0; int i; char *os; long bootingLinux = 0; long bootNetBSD = 0; long force_unzip_kernels = 0; long linuxEntryPoint = 0; long unzip_ramdisk = 0; long memc_ctrl_reg = 0x110c; long mem_fclk_21285; long dram_size = 0; long download_kernel = 0; long kernel_in_ram = 0; long copy_ramdisk = 0; get_param_value("dram_size", &dram_size); get_param_value("os", (long*)&os); get_param_value("entry", &linuxEntryPoint); get_param_value("download_kernel", &download_kernel); get_param_value("kernel_in_ram", &kernel_in_ram); get_param_value("copy_ramdisk", ©_ramdisk); if (download_kernel) { putstr("Ready to download kernel to memory for booting\r\n"); kernel_image_start = (vaddr_t)linuxEntryPoint; kernel_image_dest = linuxEntryPoint; kernel_image_size = modem_receive((char*)kernel_image_start, kernel_region_size); boot_magic = KERNELIMG_MAGIC; kernel_image_first_word = *(dword*)kernel_image_start; kernel_image_tenth_word = *(dword*)(kernel_image_start+40); kernel_image_maxsize = kernel_region_size; } else if (kernel_in_ram) { kernel_image_start = (vaddr_t)kernel_in_ram; kernel_image_dest = linuxEntryPoint; kernel_image_size = SZ_2M; boot_magic = KERNELIMG_MAGIC; kernel_image_first_word = *(dword*)kernel_image_start; kernel_image_tenth_word = *(dword*)(kernel_image_start+40); kernel_image_maxsize = kernel_region_size; } if (boot_magic == 0xFFFFFFFFL) { putstr("no boot image in flash\r\n"); return; } if (strncmp(os, "linux", 5) == 0) { putstr("os="), putstr(os); putstr("\r\n"); putstr("expecting to boot a linux kernel\r\n"); bootingLinux = 1; } else if (strncmp(os, "netbsd", 5) == 0) { putstr("os="), putstr(os); putstr("\r\n"); putstr("expecting to boot a netbsd kernel\r\n"); bootingLinux = 1; } putLabeledWord("boot_magic=", boot_magic); putLabeledWord("kernel_image_first_word=", kernel_image_first_word); if (force_unzip_kernels || ( /* NETBSD */ (kernel_image_first_word != 0x0b018f00) && /* LINUX */ (kernel_image_first_word != SKIFF_ZIMAGE_MAGIC) && /* LINUX */ (kernel_image_first_word != SKIFF_IMAGE_MAGIC) && /* CATS-style linux image */ (kernel_image_first_word != CATS_ZIMAGE_MAGIC) )) {#if defined(CONFIG_GZIP) || defined(CONFIG_BZIP) /* initialize the memory allocator */ mmalloc_init((unsigned char *)(HEAP_START), HEAP_SIZE);#endif #ifdef CONFIG_GZIP /* try to unzip kernel */ if (gunzip_region((char*)kernel_image_start, (char*)kernel_image_dest, (long)kernel_image_size, "kernel") == 0) { unzipped = 1; }#endif #ifdef CONFIG_BZIP /* attempt to uncompress */ if (bzBuffToBuffDecompress((char *)kernel_image_dest, &kernel_image_maxsize, (char *)kernel_image_start, kernel_image_size,0,0) == BZ_OK) { unzipped = 1; }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -