|
|
1.1 ! root 1: /* ! 2: * ! 3: */ ! 4: #undef BOOTSTRAP ! 5: #include "config.h" ! 6: #include "libopenbios/bindings.h" ! 7: #include "arch/common/nvram.h" ! 8: #include "drivers/drivers.h" ! 9: #include "libc/diskio.h" ! 10: #include "libc/vsprintf.h" ! 11: #include "libopenbios/sys_info.h" ! 12: #include "openprom.h" ! 13: #include "boot.h" ! 14: #include "context.h" ! 15: ! 16: uint32_t kernel_image; ! 17: uint32_t kernel_size; ! 18: uint32_t qemu_cmdline; ! 19: uint32_t cmdline_size; ! 20: char boot_device; ! 21: const void *romvec; ! 22: ! 23: void go(void) ! 24: { ! 25: ucell address, type, size; ! 26: int image_retval = 0, proplen, unit, part; ! 27: phandle_t chosen; ! 28: char *prop, *id, bootid; ! 29: static char bootpathbuf[128], bootargsbuf[128], buf[128]; ! 30: ! 31: /* Get the entry point and the type (see forth/debugging/client.fs) */ ! 32: feval("saved-program-state >sps.entry @"); ! 33: address = POP(); ! 34: feval("saved-program-state >sps.file-type @"); ! 35: type = POP(); ! 36: feval("saved-program-state >sps.file-size @"); ! 37: size = POP(); ! 38: ! 39: /* SPARC32 is slightly unusual in that before invoking any loaders, a romvec array ! 40: needs to be set up to pass certain parameters using a C struct. Hence this section ! 41: extracts the relevant boot information and places it in obp_arg. */ ! 42: ! 43: /* Get the name of the selected boot device, along with the device and unit number */ ! 44: chosen = find_dev("/chosen"); ! 45: prop = get_property(chosen, "bootpath", &proplen); ! 46: strncpy(bootpathbuf, prop, proplen); ! 47: prop = get_property(chosen, "bootargs", &proplen); ! 48: strncpy(bootargsbuf, prop, proplen); ! 49: ! 50: /* Set bootpath pointer used in romvec table to the bootpath */ ! 51: push_str(bootpathbuf); ! 52: fword("pathres-resolve-aliases"); ! 53: bootpath = pop_fstr_copy(); ! 54: printk("bootpath: %s\n", bootpath); ! 55: ! 56: if (!strncmp(bootpathbuf, "cd", 2) || !strncmp(bootpathbuf, "disk", 4)) { ! 57: ! 58: /* Controller currently always 0 */ ! 59: obp_arg.boot_dev_ctrl = 0; ! 60: ! 61: /* Grab the device and unit number string (in form unit,partition) */ ! 62: push_str(bootpathbuf); ! 63: feval("pathres-resolve-aliases ascii @ right-split 2drop"); ! 64: id = pop_fstr_copy(); ! 65: ! 66: /* A bit hacky, but we have no atoi() function */ ! 67: unit = id[0] - '0'; ! 68: part = id[2] - '0'; ! 69: ! 70: obp_arg.boot_dev_unit = unit; ! 71: obp_arg.dev_partition = part; ! 72: ! 73: /* Generate the "oldpath" ! 74: FIXME: hardcoding this looks almost definitely wrong. ! 75: With sd(0,2,0):b we get to see the solaris kernel though */ ! 76: if (!strncmp(bootpathbuf, "disk", 4)) { ! 77: bootid = 'd'; ! 78: } else { ! 79: bootid = 'b'; ! 80: } ! 81: ! 82: snprintf(buf, sizeof(buf), "sd(0,%d,%d):%c", unit, part, bootid); ! 83: ! 84: obp_arg.boot_dev[0] = buf[0]; ! 85: obp_arg.boot_dev[1] = buf[1]; ! 86: obp_arg.argv[0] = buf; ! 87: obp_arg.argv[1] = bootargsbuf; ! 88: ! 89: } else if (!strncmp(bootpathbuf, "floppy", 6)) { ! 90: ! 91: obp_arg.boot_dev_ctrl = 0; ! 92: obp_arg.boot_dev_unit = 0; ! 93: obp_arg.dev_partition = 0; ! 94: ! 95: strcpy(buf, "fd()"); ! 96: ! 97: obp_arg.boot_dev[0] = buf[0]; ! 98: obp_arg.boot_dev[1] = buf[1]; ! 99: obp_arg.argv[0] = buf; ! 100: obp_arg.argv[1] = bootargsbuf; ! 101: ! 102: } else if (!strncmp(bootpathbuf, "net", 3)) { ! 103: ! 104: obp_arg.boot_dev_ctrl = 0; ! 105: obp_arg.boot_dev_unit = 0; ! 106: obp_arg.dev_partition = 0; ! 107: ! 108: strcpy(buf, "le()"); ! 109: ! 110: obp_arg.boot_dev[0] = buf[0]; ! 111: obp_arg.boot_dev[1] = buf[1]; ! 112: obp_arg.argv[0] = buf; ! 113: obp_arg.argv[1] = bootargsbuf; ! 114: ! 115: } ! 116: ! 117: printk("\nJumping to entry point " FMT_ucellx " for type " FMT_ucellx "...\n", address, type); ! 118: ! 119: switch (type) { ! 120: case 0x0: ! 121: /* Start ELF boot image */ ! 122: image_retval = start_elf((unsigned long)address, ! 123: (unsigned long)romvec); ! 124: ! 125: break; ! 126: ! 127: case 0x1: ! 128: /* Start ELF image */ ! 129: image_retval = start_elf((unsigned long)address, ! 130: (unsigned long)romvec); ! 131: ! 132: break; ! 133: ! 134: case 0x5: ! 135: /* Start a.out image */ ! 136: image_retval = start_elf((unsigned long)address, ! 137: (unsigned long)romvec); ! 138: ! 139: break; ! 140: ! 141: case 0x10: ! 142: /* Start Fcode image */ ! 143: printk("Evaluating FCode...\n"); ! 144: PUSH(address); ! 145: PUSH(1); ! 146: fword("byte-load"); ! 147: image_retval = 0; ! 148: break; ! 149: ! 150: case 0x11: ! 151: /* Start Forth image */ ! 152: PUSH(address); ! 153: PUSH(size); ! 154: fword("eval2"); ! 155: image_retval = 0; ! 156: break; ! 157: } ! 158: ! 159: printk("Image returned with return value %#x\n", image_retval); ! 160: } ! 161: ! 162: ! 163: void boot(void) ! 164: { ! 165: /* Boot preloaded kernel */ ! 166: if (kernel_size) { ! 167: printk("[sparc] Kernel already loaded\n"); ! 168: start_elf(kernel_image, (unsigned long)romvec); ! 169: } ! 170: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.