📄 bootldr.c
字号:
if (unzipped) kernel_image_first_word = *(unsigned long *)kernel_image_dest; } if (kernel_image_first_word == SKIFF_ZIMAGE_MAGIC || kernel_image_first_word == SKIFF_IMAGE_MAGIC || kernel_image_first_word == CATS_ZIMAGE_MAGIC || bootingLinux) { unsigned long compressed_rd_start = FLASH_BASE + flashDescriptor->ramdisk.base + 4; unsigned long compressed_rd_size = *(unsigned long *)(FLASH_BASE + flashDescriptor->ramdisk.base); unsigned long initrd_size = SZ_8M; unsigned long initrd_start = STACK_BASE - initrd_size; unsigned long kernel_image_offset = 0x0; /* CATS-style Linux zImage gets loaded to physaddr 0 */ if (unzipped) kernel_image_dest = 0x0; if ( kernel_image_first_word == SKIFF_ZIMAGE_MAGIC || kernel_image_first_word == SKIFF_IMAGE_MAGIC || kernel_image_tenth_word == LINUX_ZIMAGE_MAGIC ) { /* standard Linux zImage gets loaded to phyasaddr 0x8000 */ kernel_image_offset = 0x8000; linuxEntryPoint += 0x8000; } putstr("Linux ELF flash_imgstart="); putHexInt32((long)kernel_image_start); putstr(" size="); putHexInt32(kernel_image_size); putstr(" dest="); putHexInt32(kernel_image_dest); putstr(" offset="); putHexInt32(kernel_image_offset); putstr("\r\n"); enable_caches(0, 0); /* also flushes caches */ putLabeledWord("MMU Control=", readCPR1()); if (!unzipped && ((void *)kernel_image_dest != (void *)kernel_image_start)) { putstr("copying Linux kernel ... "); memcpy((void*)(kernel_image_dest + kernel_image_offset), (void*)kernel_image_start, kernel_image_size); putstr("done\r\n"); } putLabeledWord("linuxEntryPoint: ", linuxEntryPoint); putLabeledWord("kernel_image_dest: ", kernel_image_dest); putLabeledWord("kernel_image_offset: ", kernel_image_offset); for (i = 0; i < 40; i += 4) { /* we still have the MMU on, kernel_image_dest gets us to the right virtual address */ putHexInt32(kernel_image_dest + kernel_image_offset + i); putstr(": "); putHexInt32(*(unsigned long *)(kernel_image_dest + kernel_image_offset +i)); putstr("\r\n"); }#ifdef CONFIG_GZIP if (unzip_ramdisk) { /* initialize the memory allocator */ mmalloc_init((unsigned char *)(HEAP_START), HEAP_SIZE); putLabeledWord("compressed ramdisk size is ", compressed_rd_size); putstr("unpacking ramdisk from "); putHexInt32(compressed_rd_start); putstr(" to "); putHexInt32(initrd_start); putstr(" ... "); if (compressed_rd_start != 0) { if (gunzip_region((char*)compressed_rd_start, (char*)initrd_start, (long)compressed_rd_size, "ramdisk") == 0) { putstr("done.\r\n"); } else { putstr("failed.\r\n"); return; } } } else {#endif /* CONFIG_GZIP */ if (copy_ramdisk && compressed_rd_size != -1) { putstr("Copying compressed ramdisk from "); putHexInt32(compressed_rd_start); putstr(" to "); putHexInt32(initrd_start); putstr("..."); memcpy((char*)initrd_start,(char*)compressed_rd_start,compressed_rd_size); putstr("Done \r\n"); } else if (compressed_rd_size != -1) { initrd_start = compressed_rd_start; }#ifdef CONFIG_GZIP }#endif /* CONFIG_GZIP */ if (1) { char boot_args[1024]; char *linuxargs = NULL; int flashroot = 0; if (strcmp(root_filesystem_name, "ramdisk") == 0) { flashroot = 1; } putstr("root_filesystem_name="); putstr(root_filesystem_name); putstr("\r\n"); memset(boot_args, 0, 1024); get_param_value("linuxargs", &linuxargs); if (linuxargs != NULL) strcat(boot_args, linuxargs); putLabeledWord("argc=", argc); if (argc > 2) { unparseargs(boot_args, argc-1, argv+1); } putstr("args="); putstr(boot_args); putstr("\r\n"); putstr("setting boot parameters\r\n"); setup_linux_params(kernel_image_dest, initrd_start, compressed_rd_size, memc_ctrl_reg, mem_fclk_21285, dram_size, boot_args, flashroot); } putLabeledWord("linuxEntryPoint=", linuxEntryPoint); putstr("Booting Linux image\r\n"); bootLinux(&bootinfo,#ifdef CONFIG_SKIFF MACH_TYPE_PERSONAL_SERVER,#else MACH_TYPE_BITSY,#endif#ifdef CONFIG_SKIFF /* hack -- linux entry point virtual address is 0x10008000, physaddr is 0x00008000 */ /* after we disable the MMU we have to use the physical address */ linuxEntryPoint&0x00FFFFFF#else linuxEntryPoint#endif); } else if (boot_magic == KERNELIMG_MAGIC) { char boot_args[1024]; if (!unzipped) { putstr("copying NetBSD kernel ... "); memcpy((void*)kernel_image_dest, (void*)kernel_image_start, kernel_image_size); putstr("done\r\n"); } /*bootinfo.bt_memavail = ROUNDUP(kernel_image_size, SZ_1M);*/ bootinfo.bt_memavail = SZ_2M+SZ_1M; /*putLabeledWord("bt_memavail = ",bootinfo.bt_memavail);*/ boot_args[0] = 0; strcat(boot_args, "netbsd "); if (argc > 1) { unparseargs(boot_args, argc-1, argv+1); } bootinfo.bt_args = boot_args; bootinfo.bt_vargp = (u_int32_t)boot_args & PAGE_MASK; bootinfo.bt_pargp = (u_int32_t)boot_args & PAGE_MASK; putstr("done!\r\nJumping to 0xF0000020..\r\n"); flush_caches(); boot(&bootinfo,0xF0000020); } else { putstr("Corrupt kernel image\r\n"); return; }}/* can have arguments or not */void command_boot_flash(int argc, const char **argv){ const char *ipaddr = NULL; const char *serveraddr = NULL; const char *gatewayaddr = NULL; const char *netmask = NULL; const char *hostname = NULL; const char *nfsroot = NULL; char bootargs[2048]; get_param_value("ipaddr", &ipaddr); get_param_value("nfs_server_address", &serveraddr); get_param_value("gateway", &gatewayaddr); get_param_value("netmask", &netmask); get_param_value("hostname", &hostname); get_param_value("nfsroot", &nfsroot); if (nfsroot != NULL) { strcat(bootargs, " nfsroot="); strcat(bootargs, nfsroot); } if ((ipaddr != NULL) || (serveraddr != NULL) || (gatewayaddr != NULL) || (netmask != NULL) || (hostname != NULL)) { strcat(bootargs, " ip="); strcat(bootargs, (ipaddr != NULL) ? ipaddr : ""); strcat(bootargs, ":"); strcat(bootargs, (serveraddr != NULL) ? serveraddr : ""); strcat(bootargs, ":"); strcat(bootargs, (gatewayaddr != NULL) ? gatewayaddr : ""); strcat(bootargs, ":"); strcat(bootargs, (netmask != NULL) ? netmask : ""); strcat(bootargs, ":"); strcat(bootargs, (hostname != NULL) ? hostname : ""); strcat(bootargs, ":eth0 "); } argv[argc++] = bootargs; argv[argc] = NULL; boot_kernel("ramdisk", (vaddr_t)(UNCACHED_FLASH_BASE + flashDescriptor->kernel.base), flashDescriptor->kernel.size, argc, argv);}#ifdef BOOT_ALTKERNEL/* can have arguments or not */void command_boot_altkernel(int argc, const char **argv){ const char *ipaddr = NULL; const char *serveraddr = NULL; const char *gatewayaddr = NULL; const char *netmask = NULL; const char *hostname = NULL; const char *nfsroot = NULL; char bootargs[2048]; get_param_value("ipaddr", &ipaddr); get_param_value("nfs_server_address", &serveraddr); get_param_value("gateway", &gatewayaddr); get_param_value("netmask", &netmask); get_param_value("hostname", &hostname); get_param_value("nfsroot", &nfsroot); if (nfsroot != NULL) { strcat(bootargs, " nfsroot="); strcat(bootargs, nfsroot); } strcat(bootargs, " ip="); strcat(bootargs, (ipaddr != NULL) ? ipaddr : ""); strcat(bootargs, ":"); strcat(bootargs, (serveraddr != NULL) ? serveraddr : ""); strcat(bootargs, ":"); strcat(bootargs, (gatewayaddr != NULL) ? gatewayaddr : ""); strcat(bootargs, ":"); strcat(bootargs, (netmask != NULL) ? netmask : ""); strcat(bootargs, ":"); strcat(bootargs, (hostname != NULL) ? hostname : ""); strcat(bootargs, ":eth0 "); argv[argc++] = bootargs; argv[argc] = NULL; boot_kernel("ramdisk", (vaddr_t)(UNCACHED_FLASH_BASE + flashDescriptor->altkernel.base), flashDescriptor->altkernel.size, argc, argv);}#endif/* can have arguments or not */void command_boot_nfsroot(int argc, const char **argv){ const char *ipaddr = NULL; const char *serveraddr = NULL; const char *gatewayaddr = NULL; const char *netmask = NULL; const char *hostname = NULL; const char *nfsroot = NULL; char bootargs[2048]; get_param_value("ipaddr", &ipaddr); get_param_value("nfs_server_address", &serveraddr); get_param_value("gateway", &gatewayaddr); get_param_value("netmask", &netmask); get_param_value("hostname", &hostname); get_param_value("nfsroot", &nfsroot); strcat(bootargs, " noinitrd root=/dev/nfs"); if (nfsroot != NULL) { strcat(bootargs, " nfsroot="); strcat(bootargs, nfsroot); } strcat(bootargs, " ip="); strcat(bootargs, (ipaddr != NULL) ? ipaddr : ""); strcat(bootargs, ":"); strcat(bootargs, (serveraddr != NULL) ? serveraddr : ""); strcat(bootargs, ":"); strcat(bootargs, (gatewayaddr != NULL) ? gatewayaddr : ""); strcat(bootargs, ":"); strcat(bootargs, (netmask != NULL) ? netmask : ""); strcat(bootargs, ":"); strcat(bootargs, (hostname != NULL) ? hostname : ""); strcat(bootargs, ":eth0 "); argv[argc++] = bootargs; argv[argc] = NULL; boot_kernel("nfsroot", (vaddr_t)(UNCACHED_FLASH_BASE + flashDescriptor->kernel.base), flashDescriptor->kernel.size, argc, argv);}/* requires arguments */void command_load(int argc, const char **argv){ execcmd(load_commands,argc-1,argv+1);}/* requires arguments */void command_load_flash(int argc, const char **argv){ unsigned long offset; unsigned long img_size = 0; unsigned long flash_dest = 0; unsigned long i; int override; get_param_value("override", &override); /* loading flash is different.. because writing flash is slow, we do not load it directly from the serial port. So we receive into memory first, and then program the flash... */ if (argc < 2) { /* default to first command */ putstr("usage: load flash <flashaddr>\r\n"); } else { flash_dest = strtoul(argv[1], NULL, 0); if (strtoul_err) { putstr("error parsing flash_dest\r\n"); return; } if (flash_dest < flashDescriptor->bootldr.size && !override) { putstr("That is bootloader space! Use load bootldr. Operation canceled\r\n"); return; } command_load_flash_region("flash", flash_dest, flash_size, 0); }}void command_load_ram(int argc, const char **argv){ unsigned long offset; unsigned long img_size = 0; unsigned long img_dest = 0; if (argc < 3) { /* default to first command */ putstr("usage: load ram <ramaddr> <length>\r\n"); } else { /* parse the command line to fill img_size and img_dest */ img_dest = strtoul(argv[1], NULL, 0); if (strtoul_err) { putstr("error parsing img_dest\r\n"); return; } img_size = strtoul(argv[2], NULL, 0); img_size = modem_receive((char*)img_dest, img_size); /* in case this is a kernel download, update bt_memavail */ bootinfo.bt_memavail = ROUNDUP(img_size, SZ_1M); putHexInt32(img_size); putLabeledWord(" bytes loaded to ",img_dest); putstr("\r\n"); }}/** * does the work for command_load_bootldr, etc. */static void program_flash_region(const char *regionName, unsigned long regionBase, size_t regionSize, unsigned long src, size_t img_size, int flags){ unsigned long hdr_size = 0; /* size of header */ unsigned long i; int remaining_bytes; long noerase; get_param_value("noerase", &noerase); if (flags & LFR_PATCH_BOOTLDR) { unsigned int bsd_sum; /* check here that it's really a bootldr, otherwise print a message and exit */ if (*(long *)(src + 0x20) != BOOTLDR_MAGIC) { putstr("Not loading bootldr into flash\r\n"); putLabeledWord("Downloaded image does not have BOOTLDR_MAGIC: ", BOOTLDR_MAGIC); putLabeledWord("Instead found: ", *(long *)(src + 0x20)); return; } /* check here to be certain that the BSD sum value is zero */ bsd_sum = bsd_sum_memory( src, img_size); putLabeledWord("BSD sum value is: ", bsd_sum); if (bsd_sum != 0) { putstr("BSD sum nonzero -- corrupt bootldr, not programming flash.\r\n"); return; } } if (flags & LFR_SIZE_PREFIX) { hdr_size += 4; src -= 4; *(long *)src = img_size; img_size += hdr_size; } if (img_size > regionSize) { putLabeledWord("img_size is too large for region: ", regionSize); return; } putstr("\r\nprogramming flash..."); SET_VPPEN(); if (!noerase) { putstr("erasing ...\r\n"); if (eraseFlashRange(regionBase,img_size+hdr_size)) { putstr("erase error!\r\n"); goto clear_VPPEN; } } /* the magic number.. */ putstr("writing flash..\r\n"); i = 0; remaining_bytes = img_size; while(remaining_bytes > 0) { int bytes_programmed = 0; if ((i % SZ_64K) == 0) { putstr("addr: "); putHexInt32(regionBase+i); putstr(" data: "); putHexInt32(*(unsigned long *)(src+i)); putstr("\r\n"); } if (((i % 64) == 0) && (remaining_bytes > 64)) { /* program a block */ if (programFlashBlock(regionBase+i, (unsigned long*)(src+i), 64)) { putstr("error while copying to flash!\r\n"); goto clear_VPPEN; break; } bytes_programmed = 64; } else { if (programFlashWord(regionBase+i, *(unsigned long *)(src+i))) { putstr("error while copying to flash!\r\n"); goto clear_VPPEN; break; } bytes_programmed = 4; } i += bytes_programmed; remaining_bytes -= bytes_programmed; } putstr("verifying ... "); { int i; int nwords = (img_size >> 2); unsigned long *srcwords = (unsigned long *)src; unsigned long *dstwords = (unsigned long *)&flashword[regionBase >> 2]; for (i = 0; i < nwords; i++) { if (srcwords[i] != dstwords[i]) { putLabeledWord("error programming flash at offset=", i << 2); putLabeledWord(" src=", srcwords[i]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -