|
|
1.1 ! root 1: /* a.out boot loader ! 2: * As we have seek, this implementation can be straightforward. ! 3: * 2003-07 by SONE Takeshi ! 4: */ ! 5: ! 6: #include "config.h" ! 7: #include "kernel/kernel.h" ! 8: ! 9: #ifdef CONFIG_SPARC64 ! 10: #define CONFIG_SPARC64_PAGE_SIZE_8KB ! 11: #endif ! 12: ! 13: #include "libopenbios/sys_info.h" ! 14: #include "libopenbios/bindings.h" ! 15: #include "libopenbios/aout_load.h" ! 16: #include "libc/diskio.h" ! 17: #define printf printk ! 18: #define debug printk ! 19: ! 20: #define addr_fixup(addr) ((addr) & 0x00ffffff) ! 21: ! 22: static char *image_name, *image_version; ! 23: static int fd; ! 24: ! 25: static int ! 26: check_mem_ranges(struct sys_info *info, ! 27: unsigned long start, ! 28: unsigned long size) ! 29: { ! 30: int j; ! 31: unsigned long end; ! 32: unsigned long prog_start, prog_end; ! 33: struct memrange *mem; ! 34: ! 35: prog_start = virt_to_phys(&_start); ! 36: prog_end = virt_to_phys(&_end); ! 37: ! 38: end = start + size; ! 39: ! 40: if (start < prog_start && end > prog_start) ! 41: goto conflict; ! 42: if (start < prog_end && end > prog_end) ! 43: goto conflict; ! 44: mem = info->memrange; ! 45: for (j = 0; j < info->n_memranges; j++) { ! 46: if (mem[j].base <= start && mem[j].base + mem[j].size >= end) ! 47: break; ! 48: } ! 49: if (j >= info->n_memranges) ! 50: goto badseg; ! 51: return 1; ! 52: ! 53: conflict: ! 54: printf("%s occupies [%#lx-%#lx]\n", program_name, prog_start, prog_end); ! 55: ! 56: badseg: ! 57: printf("A.out file [%#lx-%#lx] doesn't fit into memory\n", start, end - 1); ! 58: return 0; ! 59: } ! 60: ! 61: int ! 62: is_aout(struct exec *ehdr) ! 63: { ! 64: return ((ehdr->a_info & 0xffff) == OMAGIC ! 65: || (ehdr->a_info & 0xffff) == NMAGIC ! 66: || (ehdr->a_info & 0xffff) == ZMAGIC ! 67: || (ehdr->a_info & 0xffff) == QMAGIC); ! 68: } ! 69: ! 70: int ! 71: aout_load(struct sys_info *info, ihandle_t dev) ! 72: { ! 73: int retval = -1; ! 74: struct exec ehdr; ! 75: unsigned long start, size; ! 76: unsigned int offset; ! 77: ! 78: image_name = image_version = NULL; ! 79: ! 80: /* Mark the saved-program-state as invalid */ ! 81: feval("0 state-valid !"); ! 82: ! 83: fd = open_ih(dev); ! 84: if (fd == -1) { ! 85: goto out; ! 86: } ! 87: ! 88: for (offset = 0; offset < 16 * 512; offset += 512) { ! 89: seek_io(fd, offset); ! 90: if (read_io(fd, &ehdr, sizeof ehdr) != sizeof ehdr) { ! 91: debug("Can't read a.out header\n"); ! 92: retval = LOADER_NOT_SUPPORT; ! 93: goto out; ! 94: } ! 95: if (is_aout(&ehdr)) ! 96: break; ! 97: } ! 98: ! 99: if (!is_aout(&ehdr)) { ! 100: debug("Not a bootable a.out image\n"); ! 101: retval = LOADER_NOT_SUPPORT; ! 102: goto out; ! 103: } ! 104: ! 105: if (ehdr.a_text == 0x30800007) ! 106: ehdr.a_text=64*1024; ! 107: ! 108: if (N_MAGIC(ehdr) == NMAGIC) { ! 109: size = addr_fixup(N_DATADDR(ehdr)) + addr_fixup(ehdr.a_data); ! 110: } else { ! 111: size = addr_fixup(ehdr.a_text) + addr_fixup(ehdr.a_data); ! 112: } ! 113: ! 114: if (size < 7680) ! 115: size = 7680; ! 116: ! 117: fword("load-base"); ! 118: start = POP(); // N_TXTADDR(ehdr); ! 119: ! 120: if (!check_mem_ranges(info, start, size)) ! 121: goto out; ! 122: ! 123: printf("Loading a.out %s...\n", image_name ? image_name : "image"); ! 124: ! 125: seek_io(fd, offset + N_TXTOFF(ehdr)); ! 126: ! 127: if (N_MAGIC(ehdr) == NMAGIC) { ! 128: if ((size_t)read_io(fd, (void *)start, ehdr.a_text) != ehdr.a_text) { ! 129: printf("Can't read program text segment (size 0x" FMT_aout_ehdr ")\n", ehdr.a_text); ! 130: goto out; ! 131: } ! 132: if ((size_t)read_io(fd, (void *)(start + N_DATADDR(ehdr)), ehdr.a_data) != ehdr.a_data) { ! 133: printf("Can't read program data segment (size 0x" FMT_aout_ehdr ")\n", ehdr.a_data); ! 134: goto out; ! 135: } ! 136: } else { ! 137: if ((size_t)read_io(fd, (void *)start, size) != size) { ! 138: printf("Can't read program (size 0x" FMT_sizet ")\n", size); ! 139: goto out; ! 140: } ! 141: } ! 142: ! 143: debug("Loaded %lu bytes\n", size); ! 144: debug("entry point is %#lx\n", start); ! 145: ! 146: // Initialise saved-program-state ! 147: PUSH(addr_fixup(start)); ! 148: feval("saved-program-state >sps.entry !"); ! 149: PUSH(size); ! 150: feval("saved-program-state >sps.file-size !"); ! 151: feval("aout saved-program-state >sps.file-type !"); ! 152: ! 153: feval("-1 state-valid !"); ! 154: ! 155: out: ! 156: close_io(fd); ! 157: return retval; ! 158: } ! 159: ! 160: void ! 161: aout_init_program(void) ! 162: { ! 163: // Currently not implemented ! 164: feval("0 state-valid !"); ! 165: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.