/* static method, ( pos.d ih -- flag? ) */ static void grubfs_files_probe( grubfs_info_t *dummy ) { ihandle_t ih = POP_ih(); long long offs = DPOP(); int i; curfs->dev_fd = open_ih(ih); if (curfs->dev_fd == -1) { RET( -1 ); } curfs->offset = offs; for (i = 0; i < sizeof(fsys_table)/sizeof(fsys_table[0]); i++) { #ifdef CONFIG_DEBUG_FS printk("Probing for %s\n", fsys_table[i].name); #endif if (fsys_table[i].mount_func()) { RET( -1 ); } } #ifdef CONFIG_DEBUG_FS printk("Unknown filesystem type\n"); #endif close_io(curfs->dev_fd); RET ( 0 ); }
/* ( -- success? ) */ static void grubfs_files_open( grubfs_info_t *mi ) { int fd, i; char *path = my_args_copy(); char *s; fd = open_ih( my_parent() ); if ( fd == -1 ) { free( path ); RET( 0 ); } mi->gfs = &dummy_fs; for (i = 0; i < sizeof(fsys_table)/sizeof(fsys_table[0]); i++) { #ifdef CONFIG_DEBUG_FS printk("Trying %s\n", fsys_table[i].name); #endif if (fsys_table[i].mount_func()) { const fsys_entry_t *fsys = &fsys_table[i]; #ifdef CONFIG_DEBUG_FS printk("Mounted %s\n", fsys->name); #endif mi->gfs = malloc(sizeof(grubfs_t)); mi->gfs->fsys = fsys; mi->gfs->dev_fd = fd; mi->gfs->offset = 0; s = path; while (*s) { if(*s=='\\') *s='/'; s++; } #ifdef CONFIG_DEBUG_FS printk("Path=%s\n",path); #endif if (!mi->gfs->fsys->dir_func((char *) path)) { forth_printf("File not found\n"); RET( 0 ); } mi->gfs->fd = malloc(sizeof(grubfile_t)); mi->gfs->fd->pos = filepos; mi->gfs->fd->len = filemax; mi->gfs->fd->path = strdup(path); RET( -1 ); } } #ifdef CONFIG_DEBUG_FS printk("Unknown filesystem type\n"); #endif RET( 0 ); }
int bootcode_load(ihandle_t dev) { int retval = -1, count = 0, fd; unsigned long bootcode, loadbase, offset; /* Mark the saved-program-state as invalid */ feval("0 state-valid !"); fd = open_ih(dev); if (fd == -1) { goto out; } /* Default to loading at load-base */ fword("load-base"); loadbase = POP(); #ifdef CONFIG_PPC /* However Old World Macs need to load to a different address */ if (is_oldworld()) { loadbase = OLDWORLD_BOOTCODE_BASEADDR; } #endif bootcode = loadbase; offset = 0; while(1) { if (seek_io(fd, offset) == -1) break; count = read_io(fd, (void *)bootcode, 512); offset += count; bootcode += count; } /* If we didn't read anything then exit */ if (!count) { goto out; } /* Initialise saved-program-state */ PUSH(loadbase); feval("saved-program-state >sps.entry !"); PUSH(offset); feval("saved-program-state >sps.file-size !"); feval("bootcode saved-program-state >sps.file-type !"); feval("-1 state-valid !"); out: close_io(fd); return retval; }
/* ( -- success? ) */ static void hfsp_files_open( hfsp_info_t *mi ) { int fd; char *path = my_args_copy(); if ( ! path ) RET( 0 ); fd = open_ih( my_parent() ); if ( fd == -1 ) { free( path ); RET( 0 ); } mi->vol = malloc( sizeof(volume) ); if (volume_open(mi->vol, fd)) { free( path ); close_io( fd ); RET( 0 ); } mi->hfspfile = malloc( sizeof(hfsp_file_t) ); /* Leading \\ means system folder. The finder info block has * the following meaning. * * [0] Prefered boot directory ID * [3] MacOS 9 boot directory ID * [5] MacOS X boot directory ID */ if( !strncmp(path, "\\\\", 2) ) { int *p = (int*)&(mi->vol)->vol.finder_info[0]; int cnid = p[0]; /* printk(" p[0] = %x, p[3] = %x, p[5] = %x\n", p[0], p[3], p[5] ); */ if( p[0] == p[5] && p[3] ) cnid = p[3]; if( record_init_cnid(&(mi->hfspfile->rec), &(mi->vol)->catalog, cnid) ) RET ( 0 ); path += 2; } else { record_init_root( &(mi->hfspfile->rec), &(mi->vol)->catalog ); } if( !search_files(&(mi->hfspfile->rec), 0, match_path, path, mi->hfspfile ) ) RET ( -1 ); RET ( -1 ); }
/* ( -- cstr|0 ) */ static void hfsp_files_volume_name( hfsp_info_t *mi ) { int fd; char *volname = malloc(VOLNAME_SIZE); fd = open_ih(my_self()); if (fd >= 0) { get_hfs_vol_name(fd, volname, VOLNAME_SIZE); close_io(fd); } else { volname[0] = '\0'; } PUSH(pointer2cell(volname)); }
/* static method, ( pos.d ih -- flag? ) */ static void hfsp_files_probe( hfsp_info_t *dummy ) { ihandle_t ih = POP_ih(); long long offs = DPOP(); int fd, ret = 0; fd = open_ih(ih); if (fd >= 0) { if (volume_probe(fd, offs)) { ret = -1; } close_io(fd); } else { ret = -1; } RET (ret); }
int fcode_load(ihandle_t dev) { int retval = -1; uint8_t fcode_header[8]; unsigned long start, size; unsigned int offset; /* Mark the saved-program-state as invalid */ feval("0 state-valid !"); fd = open_ih(dev); if (fd == -1) { goto out; } for (offset = 0; offset < 16 * 512; offset += 512) { seek_io(fd, offset); if (read_io(fd, &fcode_header, sizeof(fcode_header)) != sizeof(fcode_header)) { debug("Can't read FCode header from ihandle " FMT_ucellx "\n", dev); retval = LOADER_NOT_SUPPORT; goto out; } if (is_fcode(fcode_header)) goto found; } debug("Not a bootable FCode image\n"); retval = LOADER_NOT_SUPPORT; goto out; found: size = (fcode_header[4] << 24) | (fcode_header[5] << 16) | (fcode_header[6] << 8) | fcode_header[7]; fword("load-base"); start = POP(); printf("\nLoading FCode image...\n"); seek_io(fd, offset); if ((size_t)read_io(fd, (void *)start, size) != size) { printf("Can't read file (size 0x%lx)\n", size); goto out; } debug("Loaded %lu bytes\n", size); debug("entry point is %#lx\n", start); // Initialise load-state PUSH(size); feval("load-state >ls.file-size !"); feval("fcode load-state >ls.file-type !"); out: close_io(fd); return retval; }
int aout_load(struct sys_info *info, ihandle_t dev) { int retval = -1; struct exec ehdr; unsigned long start, size; unsigned int offset; image_name = image_version = NULL; /* Mark the saved-program-state as invalid */ feval("0 state-valid !"); fd = open_ih(dev); if (fd == -1) { goto out; } for (offset = 0; offset < 16 * 512; offset += 512) { seek_io(fd, offset); if (read_io(fd, &ehdr, sizeof ehdr) != sizeof ehdr) { debug("Can't read a.out header\n"); retval = LOADER_NOT_SUPPORT; goto out; } if (is_aout(&ehdr)) break; } if (!is_aout(&ehdr)) { debug("Not a bootable a.out image\n"); retval = LOADER_NOT_SUPPORT; goto out; } if (ehdr.a_text == 0x30800007) ehdr.a_text=64*1024; if (N_MAGIC(ehdr) == NMAGIC) { size = addr_fixup(N_DATADDR(ehdr)) + addr_fixup(ehdr.a_data); } else { size = addr_fixup(ehdr.a_text) + addr_fixup(ehdr.a_data); } if (size < 7680) size = 7680; fword("load-base"); start = POP(); // N_TXTADDR(ehdr); memcpy((void *)start, &ehdr, sizeof(ehdr)); if (!check_mem_ranges(info, start, size)) goto out; printf("Loading a.out %s...\n", image_name ? image_name : "image"); seek_io(fd, offset + N_TXTOFF(ehdr)); if (N_MAGIC(ehdr) == NMAGIC) { if ((size_t)read_io(fd, (void *)(start + N_TXTOFF(ehdr)), ehdr.a_text) != ehdr.a_text) { printf("Can't read program text segment (size 0x" FMT_aout_ehdr ")\n", ehdr.a_text); goto out; } if ((size_t)read_io(fd, (void *)(start + N_DATADDR(ehdr)), ehdr.a_data) != ehdr.a_data) { printf("Can't read program data segment (size 0x" FMT_aout_ehdr ")\n", ehdr.a_data); goto out; } } else { if ((size_t)read_io(fd, (void *)(start + N_TXTOFF(ehdr)), size) != size) { printf("Can't read program (size 0x" FMT_sizet ")\n", size); goto out; } } debug("Loaded %lu bytes\n", size); debug("entry point is %#lx\n", start); // Initialise saved-program-state PUSH(size); feval("load-state >ls.file-size !"); feval("aout load-state >ls.file-type !"); out: close_io(fd); return retval; }
int xcoff_load(ihandle_t dev) { COFF_filehdr_t fhdr; COFF_aouthdr_t ahdr; COFF_scnhdr_t shdr; uint32_t offset; size_t total_size = 0; int fd, i; int retval = -1; /* Mark the saved-program-state as invalid */ feval("0 state-valid !"); fd = open_ih(dev); if (fd == -1) { retval = LOADER_NOT_SUPPORT; goto out; } for (offset = 0; offset < 16 * 512; offset += 512) { seek_io(fd, offset); if (read_io(fd, &fhdr, sizeof fhdr) != sizeof fhdr) { DPRINTF("Can't read XCOFF header\n"); retval = LOADER_NOT_SUPPORT; goto out; } if (is_xcoff(&fhdr)) break; } /* Is it executable ? */ if (fhdr.f_magic != 0x01DF && (fhdr.f_flags & COFF_F_EXEC) == 0) { DPRINTF("Not an executable XCOFF file %02x\n", fhdr.f_flags); return LOADER_NOT_SUPPORT; } /* Optional header is a.out ? */ if (fhdr.f_opthdr != sizeof(COFF_aouthdr_t)) { DPRINTF("AOUT optional error size mismatch in XCOFF file\n"); return LOADER_NOT_SUPPORT; } seek_io(fd, sizeof(COFF_filehdr_t)); read_io(fd, &ahdr, sizeof(COFF_aouthdr_t)); /* check a.out magic number */ if (ahdr.magic != AOUT_MAGIC) { DPRINTF("Invalid AOUT optional header\n"); return LOADER_NOT_SUPPORT; } offset = sizeof(COFF_filehdr_t) + sizeof(COFF_aouthdr_t); DPRINTF("XCOFF file with %d sections\n", fhdr.f_nscns); for (i = 0; i < fhdr.f_nscns; i++) { DPRINTF("Read header at offset %0x\n", offset); seek_io(fd, offset); read_io(fd, &shdr, sizeof(COFF_scnhdr_t)); DPRINTF("Initializing '%s' section from %0x %0x to %0x (%0x)\n", shdr.s_name, offset, shdr.s_scnptr, shdr.s_vaddr, shdr.s_size); if (strcmp(shdr.s_name, ".text") == 0) { read_io(fd, (void *)shdr.s_vaddr, shdr.s_size); total_size += shdr.s_size; #ifdef CONFIG_PPC flush_icache_range((char*)(uintptr_t)shdr.s_vaddr, (char*)(uintptr_t)(shdr.s_vaddr + shdr.s_size)); #endif } else if (strcmp(shdr.s_name, ".data") == 0) { read_io(fd, (void *)shdr.s_vaddr, shdr.s_size); total_size += shdr.s_size; } else if (strcmp(shdr.s_name, ".bss") == 0) { memset((void *)(uintptr_t)shdr.s_vaddr, 0, shdr.s_size); total_size += shdr.s_size; } else { DPRINTF(" Skip '%s' section\n", shdr.s_name); } offset += sizeof(COFF_scnhdr_t); } DPRINTF("XCOFF entry point: %x\n", *(uint32_t*)ahdr.entry); // Initialise load-state PUSH(total_size); feval("load-state >ls.file-size !"); feval("xcoff load-state >ls.file-type !"); out: close_io(fd); return retval; }
int elf_load(struct sys_info *info, ihandle_t dev, const char *cmdline, void **boot_notes) { Elf_ehdr ehdr; Elf_phdr *phdr = NULL; unsigned long checksum_offset, file_size; unsigned short checksum = 0; int retval = -1; unsigned int offset; image_name = image_version = NULL; /* Mark the saved-program-state as invalid */ feval("0 state-valid !"); fd = open_ih(dev); if (fd == -1) { goto out; } offset = find_elf(&ehdr); if (!offset) { retval = LOADER_NOT_SUPPORT; goto out; } #if DEBUG printk("ELF header:\n"); printk(" ehdr.e_type = %d\n", (int)ehdr.e_type); printk(" ehdr.e_machine = %d\n", (int)ehdr.e_machine); printk(" ehdr.e_version = %d\n", (int)ehdr.e_version); printk(" ehdr.e_entry = 0x%08x\n", (int)ehdr.e_entry); printk(" ehdr.e_phoff = 0x%08x\n", (int)ehdr.e_phoff); printk(" ehdr.e_shoff = 0x%08x\n", (int)ehdr.e_shoff); printk(" ehdr.e_flags = %d\n", (int)ehdr.e_flags); printk(" ehdr.e_ehsize = 0x%08x\n", (int)ehdr.e_ehsize); printk(" ehdr.e_phentsize = 0x%08x\n", (int)ehdr.e_phentsize); printk(" ehdr.e_phnum = %d\n", (int)ehdr.e_phnum); #endif if (ehdr.e_phnum > MAX_HEADERS) { printk ("elfload: too many program headers (MAX_HEADERS)\n"); retval = 0; goto out; } phdr = elf_readhdrs(offset, &ehdr); if (!phdr) goto out; if (!check_mem_ranges(info, phdr, ehdr.e_phnum)) goto out; checksum_offset = process_image_notes(phdr, ehdr.e_phnum, &checksum, offset); printf("Loading %s", image_name ? image_name : "image"); if (image_version) printf(" version %s", image_version); printf("...\n"); if (!load_segments(phdr, ehdr.e_phnum, checksum_offset, offset, &file_size)) goto out; if (checksum_offset) { if (!verify_image(&ehdr, phdr, ehdr.e_phnum, checksum)) goto out; } /* If we are attempting an ELF boot image, we pass a non-NULL pointer into boot_notes and mark the image as elf-boot rather than standard ELF */ if (boot_notes) { *boot_notes = (void *)virt_to_phys(build_boot_notes(info, cmdline)); feval("elf-boot saved-program-state >sps.file-type !"); } else { feval("elf saved-program-state >sps.file-type !"); } //debug("current time: %lu\n", currticks()); debug("entry point is " FMT_elf "\n", addr_fixup(ehdr.e_entry)); // Initialise saved-program-state PUSH(addr_fixup(ehdr.e_entry)); feval("saved-program-state >sps.entry !"); PUSH(file_size); feval("saved-program-state >sps.file-size !"); feval("-1 state-valid !"); out: close_io(fd); if (phdr) free(phdr); if (image_name) free(image_name); if (image_version) free(image_version); return retval; }