void boot(void) { char *path, *param; /* Copy the incoming path */ fword("2dup"); path = pop_fstr_copy(); /* Boot preloaded kernel */ if (kernel_size) { void (*entry)(unsigned long p1, unsigned long p2, unsigned long p3, unsigned long p4, unsigned long p5); printk("[sparc64] Kernel already loaded\n"); entry = (void *) (unsigned long)kernel_image; entry(0, 0, 0, 0, (unsigned long)&sparc64_of_client_interface); } /* Invoke Linux directly -- probably not supported */ if(!path) { /* No path specified, so grab defaults from /chosen */ push_str("bootpath"); push_str("/chosen"); fword("(find-dev)"); POP(); fword("get-package-property"); POP(); /* Update our local copy of path as well as the one on the stack */ fword("2dup"); path = pop_fstr_copy(); } if (path) { param = strchr(path, ' '); if(param) { *param = '\0'; param++; } else if (cmdline_size) { param = (char *)qemu_cmdline; } else { push_str("boot-args"); push_str("/options"); fword("(find-dev)"); POP(); fword("get-package-property"); POP(); param = pop_fstr_copy(); } /* Invoke platform-specific Linux loader */ linux_load(&sys_info, path, param); free(path); } }
static void ob_sd_open(ATTRIBUTE_UNUSEDsd_private_t **sd) { int ret = 1, id; phandle_t ph; fword("my-unit"); id = POP(); POP(); // unit id is 2 ints but we only need one. *sd = &global_esp->sd[id]; #ifdef CONFIG_DEBUG_ESP { char *args; fword("my-args"); args = pop_fstr_copy(); DPRINTF("opening drive %d args %s\n", id, args); free(args); } #endif selfword("open-deblocker"); /* interpose disk-label */ ph = find_dev("/packages/disk-label"); fword("my-args"); PUSH_ph( ph ); fword("interpose"); RET ( -ret ); }
void boot(void) { char *path=pop_fstr_copy(), *param; // char *param="root=/dev/hda2 console=ttyS0,115200n8 console=tty0"; if(!path) { printk("[x86] Booting default not supported.\n"); return; } param = strchr(path, ' '); if(param) { *param = '\0'; param++; } printk("[x86] Booting file '%s' with parameters '%s'\n",path, param); if (elf_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) if (linux_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) printk("Unsupported image format\n"); free(path); }
void boot( void ) { char *path; void *entry; /* Copy the incoming path */ fword("2dup"); path = pop_fstr_copy(); if(!path) { printk("[unix] Booting default not supported.\n"); return; } printk("[unix] Booting '%s'\n",path); entry=load_elf(path); if(entry) printk("successfully loaded client at %llx.\n", (unsigned long long)(ucell)entry); else printk("failed.\n"); }
/* ( open -- flag ) */ static void macparts_open( macparts_info_t *di ) { char *str = my_args_copy(); char *parstr = NULL, *argstr = NULL; char *tmpstr; int bs, parnum=-1, apple_parnum=-1; int parlist[2], parlist_size = 0; desc_map_t dmap; part_entry_t par; int ret = 0, i = 0, j = 0; int want_bootcode = 0; phandle_t ph; ducell offs = 0, size = -1; DPRINTF("macparts_open '%s'\n", str ); /* Arguments that we accept: id: [0-7] [(id)][,][filespec] */ if ( str && strlen(str) ) { /* Detect the arguments */ if ((*str >= '0' && *str <= '9') || (*str == ',')) { push_str(str); PUSH(','); fword("left-parse-string"); parstr = pop_fstr_copy(); argstr = pop_fstr_copy(); } else { argstr = str; } /* Make sure argstr is not null */ if (argstr == NULL) argstr = strdup(""); /* Convert the id to a partition number */ if (parstr && strlen(parstr)) parnum = atol(parstr); /* Detect if we are looking for the bootcode */ if (strcmp(argstr, "%BOOT") == 0) { want_bootcode = 1; } } DPRINTF("parstr: %s argstr: %s parnum: %d\n", parstr, argstr, parnum); DPRINTF("want_bootcode %d\n", want_bootcode); DPRINTF("macparts_open %d\n", parnum); di->filesystem_ph = 0; di->read_xt = find_parent_method("read"); di->seek_xt = find_parent_method("seek"); SEEK( 0 ); if( READ(&dmap, sizeof(dmap)) != sizeof(dmap) ) goto out; /* partition maps might support multiple block sizes; in this case, * pmPyPartStart is typically given in terms of 512 byte blocks. */ bs = __be16_to_cpu(dmap.sbBlockSize); if( bs != 512 ) { SEEK( 512 ); READ( &par, sizeof(par) ); if( __be16_to_cpu(par.pmSig) == DESC_PART_SIGNATURE ) bs = 512; } SEEK( bs ); if( READ(&par, sizeof(par)) != sizeof(par) ) goto out; if (__be16_to_cpu(par.pmSig) != DESC_PART_SIGNATURE) goto out; /* * Implement partition selection as per the PowerPC Microprocessor CHRP bindings */ if (argstr == NULL || parnum == 0) { /* According to the spec, partition 0 as well as no arguments means the whole disk */ offs = (long long)0; size = (long long)__be32_to_cpu(dmap.sbBlkCount) * bs; di->blocksize = (unsigned int)bs; di->offs_hi = offs >> BITS; di->offs_lo = offs & (ucell) -1; di->size_hi = size >> BITS; di->size_lo = size & (ucell) -1; ret = -1; goto out; } else if (parnum == -1) {
static void ob_pci_decode_unit(int *idx) { ucell hi, mid, lo; const char *arg = pop_fstr_copy(); int dev, fn, reg, ss, n, p, t; int bus = 0; /* no information */ char *ptr; PCI_DPRINTF("ob_pci_decode_unit idx=%p\n", idx); fn = 0; reg = 0; n = 0; p = 0; t = 0; ptr = (char*)arg; if (*ptr == 'n') { n = IS_NOT_RELOCATABLE; ptr++; } if (*ptr == 'i') { ss = IO_SPACE; ptr++; if (*ptr == 't') { t = IS_ALIASED; ptr++; } /* DD,F,RR,NNNNNNNN */ dev = strtol(ptr, &ptr, 16); ptr++; fn = strtol(ptr, &ptr, 16); ptr++; reg = strtol(ptr, &ptr, 16); ptr++; lo = strtol(ptr, &ptr, 16); mid = 0; } else if (*ptr == 'm') { ss = MEMORY_SPACE_32; ptr++; if (*ptr == 't') { t = IS_ALIASED; ptr++; } if (*ptr == 'p') { p = IS_PREFETCHABLE; ptr++; } /* DD,F,RR,NNNNNNNN */ dev = strtol(ptr, &ptr, 16); ptr++; fn = strtol(ptr, &ptr, 16); ptr++; reg = strtol(ptr, &ptr, 16); ptr++; lo = strtol(ptr, &ptr, 16); mid = 0; } else if (*ptr == 'x') { unsigned long long addr64; ss = MEMORY_SPACE_64; ptr++; if (*ptr == 'p') { p = IS_PREFETCHABLE; ptr++; } /* DD,F,RR,NNNNNNNNNNNNNNNN */ dev = strtol(ptr, &ptr, 16); ptr++; fn = strtol(ptr, &ptr, 16); ptr++; reg = strtol(ptr, &ptr, 16); ptr++; addr64 = strtoll(ptr, &ptr, 16); lo = (ucell)addr64; mid = addr64 >> 32; } else {
void setup_romvec(void) { /* SPARC32 is slightly unusual in that before invoking any loaders, a romvec array needs to be set up to pass certain parameters using a C struct. Hence this function extracts the relevant boot information and places it in obp_arg. */ int intprop, proplen, target, device, i; unsigned int *intprop_ptr; phandle_t chosen; char *prop, *id, *name; static char bootpathbuf[128], bootargsbuf[128], buf[128]; struct linux_mlist_v0 **pp; /* Get the stdin and stdout paths */ chosen = find_dev("/chosen"); intprop = get_int_property(chosen, "stdin", &proplen); PUSH(intprop); fword("get-instance-path"); ((struct linux_romvec *)romvec)->pv_stdin = pop_fstr_copy(); intprop = get_int_property(chosen, "stdout", &proplen); PUSH(intprop); fword("get-instance-path"); ((struct linux_romvec *)romvec)->pv_stdout = pop_fstr_copy(); /* Get the name of the selected boot device, along with the device and unit number */ prop = get_property(chosen, "bootpath", &proplen); strncpy(bootpathbuf, prop, proplen); prop = get_property(chosen, "bootargs", &proplen); strncpy(bootargsbuf, prop, proplen); /* Set bootpath pointer used in romvec table to the bootpath */ push_str(bootpathbuf); fword("pathres-resolve-aliases"); bootpath = pop_fstr_copy(); printk("bootpath: %s\n", bootpath); /* Now do some work to get hold of the target, partition etc. */ push_str(bootpathbuf); feval("open-dev"); feval("ihandle>boot-device-handle drop to my-self"); push_str("name"); fword("get-my-property"); POP(); name = pop_fstr_copy(); if (!strncmp(name, "sd", 2)) { /* Old-style SunOS disk paths are given in the form: sd(c,t,d):s where: c = controller (Nth controller in system, usually 0) t = target (my-unit phys.hi) d = device/LUN (my-unit phys.lo) s = slice/partition (my-args) */ /* Controller currently always 0 */ obp_arg.boot_dev_ctrl = 0; /* Get the target, device and slice */ fword("my-unit"); target = POP(); device = POP(); fword("my-args"); id = pop_fstr_copy(); if (id != NULL) { snprintf(buf, sizeof(buf), "sd(0,%d,%d):%c", target, device, id[0]); obp_arg.dev_partition = id[0] - 'a'; } else { snprintf(buf, sizeof(buf), "sd(0,%d,%d)", target, device); obp_arg.dev_partition = 0; } obp_arg.boot_dev_unit = target; obp_arg.boot_dev[0] = buf[0]; obp_arg.boot_dev[1] = buf[1]; obp_arg.argv[0] = buf; obp_arg.argv[1] = bootargsbuf; } else if (!strncmp(name, "SUNW,fdtwo", 10)) { obp_arg.boot_dev_ctrl = 0; obp_arg.boot_dev_unit = 0; obp_arg.dev_partition = 0; strcpy(buf, "fd()"); obp_arg.boot_dev[0] = buf[0]; obp_arg.boot_dev[1] = buf[1]; obp_arg.argv[0] = buf; obp_arg.argv[1] = bootargsbuf; } else if (!strncmp(name, "le", 2)) { obp_arg.boot_dev_ctrl = 0; obp_arg.boot_dev_unit = 0; obp_arg.dev_partition = 0; strcpy(buf, "le()"); obp_arg.boot_dev[0] = buf[0]; obp_arg.boot_dev[1] = buf[1]; obp_arg.argv[0] = buf; obp_arg.argv[1] = bootargsbuf; } /* Generate the totphys (total memory available) list */ prop = get_property(s_phandle_memory, "reg", &proplen); intprop_ptr = (unsigned int *)prop; for (pp = &totphyslist, i = 0; i < (proplen / sizeof(int)); pp = &(**pp).theres_more, i+=3) { *pp = (struct linux_mlist_v0 *)malloc(sizeof(struct linux_mlist_v0)); (**pp).theres_more = NULL; (**pp).start_adr = (char *)intprop_ptr[1]; (**pp).num_bytes = intprop_ptr[2]; intprop_ptr += 3; } /* Generate the avail (physical memory available) list */ prop = get_property(s_phandle_memory, "available", &proplen); intprop_ptr = (unsigned int *)prop; for (pp = &availlist, i = 0; i < (proplen / sizeof(int)); pp = &(**pp).theres_more, i+=3) { *pp = (struct linux_mlist_v0 *)malloc(sizeof(struct linux_mlist_v0)); (**pp).theres_more = NULL; (**pp).start_adr = (char *)intprop_ptr[1]; (**pp).num_bytes = intprop_ptr[2]; intprop_ptr += 3; } /* Generate the prommap (taken virtual memory) list from inverse of available */ prop = get_property(s_phandle_mmu, "available", &proplen); intprop_ptr = (unsigned int *)prop; for (pp = &prommaplist, i = 0; i < (proplen / sizeof(int)); pp = &(**pp).theres_more, i+=3) { *pp = (struct linux_mlist_v0 *)malloc(sizeof(struct linux_mlist_v0)); (**pp).theres_more = NULL; (**pp).start_adr = (char *)(intprop_ptr[1] + intprop_ptr[2]); if (i + 3 < (proplen / sizeof(int))) { /* Size from next entry */ (**pp).num_bytes = (intprop_ptr[4] + intprop_ptr[5]) - (intprop_ptr[1] + intprop_ptr[2]); } else { /* Tail (size from top of virtual memory) */ (**pp).num_bytes = ofmem_arch_get_virt_top() - 1 - (intprop_ptr[1] + intprop_ptr[2]) + 1; } intprop_ptr += 3; } /* Finally set the memory properties */ ((struct linux_romvec *)romvec)->pv_v0mem.v0_totphys = &totphyslist; ((struct linux_romvec *)romvec)->pv_v0mem.v0_available = &availlist; ((struct linux_romvec *)romvec)->pv_v0mem.v0_prommap = &prommaplist; }
void load(ihandle_t dev) { /* Invoke the loaders on the specified device */ char *param; ucell valid; #ifdef CONFIG_LOADER_ELF /* Grab the boot arguments */ push_str("bootargs"); push_str("/chosen"); fword("(find-dev)"); POP(); fword("get-package-property"); POP(); param = pop_fstr_copy(); elf_load(&sys_info, dev, param, &elf_boot_notes); feval("state-valid @"); valid = POP(); if (valid) { return; } #endif #ifdef CONFIG_LOADER_AOUT aout_load(&sys_info, dev); feval("state-valid @"); valid = POP(); if (valid) { return; } #endif #ifdef CONFIG_LOADER_FCODE fcode_load(dev); feval("state-valid @"); valid = POP(); if (valid) { return; } #endif #ifdef CONFIG_LOADER_FORTH forth_load(dev); feval("state-valid @"); valid = POP(); if (valid) { return; } #endif #ifdef CONFIG_LOADER_BOOTCODE /* Check for a "raw" %BOOT bootcode payload */ feval("want-bootcode @"); valid = POP(); if (valid) { bootcode_load(dev); } #endif }
/* ( open -- flag ) */ static void pcparts_open( pcparts_info_t *di ) { char *str = my_args_copy(); char *argstr = strdup(""); char *parstr = strdup(""); int bs, parnum=-1; int found = 0; phandle_t ph; ducell offs, size; /* Layout of PC partition table */ struct pc_partition { unsigned char boot; unsigned char head; unsigned char sector; unsigned char cyl; unsigned char type; unsigned char e_head; unsigned char e_sector; unsigned char e_cyl; u32 start_sect; /* unaligned little endian */ u32 nr_sects; /* ditto */ } *p, *partition; unsigned char buf[512]; DPRINTF("pcparts_open '%s'\n", str ); /* Arguments that we accept: id: [0-7] [(id)][,][filespec] */ if ( strlen(str) ) { /* Detect the arguments */ if ((*str >= '0' && *str <= '7') || (*str == ',')) { push_str(str); PUSH(','); fword("left-parse-string"); parstr = pop_fstr_copy(); argstr = pop_fstr_copy(); } else { argstr = str; } /* Convert the id to a partition number */ if (parstr && strlen(parstr)) parnum = atol(parstr); } /* Make sure argstr is not null */ if (argstr == NULL) argstr = strdup(""); DPRINTF("parstr: %s argstr: %s parnum: %d\n", parstr, argstr, parnum); free(parstr); if( parnum < 0 ) parnum = 0; di->filesystem_ph = 0; di->read_xt = find_parent_method("read"); di->seek_xt = find_parent_method("seek"); SEEK( 0 ); if( READ(buf, 512) != 512 ) RET(0); /* Check Magic */ if (!has_pc_part_magic(buf)) { DPRINTF("pc partition magic not found.\n"); RET(0); } /* Actual partition data */ partition = (struct pc_partition *) (buf + 0x1be); /* Make sure we use a copy accessible from an aligned pointer (some archs e.g. SPARC will crash otherwise) */ p = malloc(sizeof(struct pc_partition)); bs = 512; if (parnum < 4) { /* primary partition */ partition += parnum; memcpy(p, partition, sizeof(struct pc_partition)); if (p->type == 0 || is_pc_extended_part(p->type)) { DPRINTF("partition %d does not exist\n", parnum+1 ); RET( 0 ); } offs = (long long)(__le32_to_cpu(p->start_sect)) * bs; di->offs_hi = offs >> BITS; di->offs_lo = offs & (ucell) -1; size = (long long)(__le32_to_cpu(p->nr_sects)) * bs; di->size_hi = size >> BITS; di->size_lo = size & (ucell) -1; DPRINTF("Primary partition at sector %x\n", __le32_to_cpu(p->start_sect)); /* If PReP boot partition, exit immediately with no filesystem probe */ if (p->type == 0x41) { RET(-1); } found = 1; } else {