1 /*- 2 * Copyright (C) 1999 T.Horiuchi(Brains, Corp.) and SAITOH Masanobu. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <sys/exec_coff.h> 31 #include <sys/param.h> 32 #include <sys/gmon.h> 33 #include <sys/stat.h> 34 #include <sys/sysctl.h> 35 #include <sys/socket.h> 36 #include <sys/file.h> 37 #include <uvm/uvm_param.h> 38 #include <machine/cpu.h> 39 40 #define vm_page_size (NBPG) 41 42 char *netbsd = "/netbsd"; 43 struct coff_filehdr FileHdr; 44 struct coff_aouthdr AoutHdr; 45 46 static int coff_find_section __P((FILE *, struct coff_filehdr *, 47 struct coff_scnhdr *, int)); 48 49 void LoadAndReset __P((char *)); 50 int main __P((int, char **)); 51 52 static int 53 coff_find_section(fd, fp, sh, s_type) 54 FILE *fd; 55 struct coff_filehdr *fp; 56 struct coff_scnhdr *sh; 57 int s_type; 58 { 59 int i, pos, siz; 60 61 pos = COFF_HDR_SIZE; 62 for (i = 0; i < fp->f_nscns; i++, pos += sizeof(struct coff_scnhdr)) { 63 siz = sizeof(struct coff_scnhdr); 64 if (fread(sh, 1, siz, fd) != siz) { 65 perror("osloader"); 66 exit(1); 67 } 68 69 if (sh->s_flags == s_type) 70 return (0); 71 } 72 return (-1); 73 } 74 75 void 76 LoadAndReset(osimage) 77 char *osimage; 78 { 79 int mib[2]; 80 u_long val; 81 int len; 82 83 mib[0] = CTL_MACHDEP; 84 mib[1] = CPU_LOADANDRESET; 85 val = (u_long)osimage; 86 len = sizeof(val); 87 88 sysctl(mib, 2, NULL, NULL, &val, len); 89 } 90 91 int 92 main(argc, argv) 93 int argc; 94 char *argv[]; 95 { 96 FILE *fp; 97 int error; 98 long dsize; 99 struct coff_scnhdr sh; 100 u_long ep_taddr; 101 u_long ep_tsize; 102 u_long toffset; 103 u_long ep_daddr; 104 u_long ep_dsize; 105 u_long doffset; 106 char *osimage; 107 char *p; 108 int i; 109 u_long cksum; 110 u_long size; 111 112 fp = fopen(netbsd, "r"); 113 if (fp == NULL) { 114 perror("osloader"); 115 exit(1); 116 } 117 118 if (fread(&FileHdr, 1, sizeof(FileHdr), fp) != sizeof(FileHdr)) { 119 perror("osloader"); 120 exit(1); 121 } 122 123 if (fread(&AoutHdr, 1, sizeof(AoutHdr), fp) != sizeof(AoutHdr)) { 124 perror("osloader"); 125 exit(1); 126 } 127 128 /* set up command for text segment */ 129 error = coff_find_section(fp, &FileHdr, &sh, COFF_STYP_TEXT); 130 if (error) { 131 printf("can't find text section: %d\n", error); 132 exit(1); 133 } 134 135 ep_taddr = COFF_ALIGN(sh.s_vaddr); 136 toffset = sh.s_scnptr - (sh.s_vaddr - ep_taddr); 137 ep_tsize = sh.s_size + (sh.s_vaddr - ep_taddr); 138 139 printf("addr %lx size 0x%lx offset 0x%lx\n", ep_taddr, 140 ep_tsize, toffset); 141 142 /* set up command for data segment */ 143 error = coff_find_section(fp, &FileHdr, &sh, COFF_STYP_DATA); 144 if (error) { 145 printf("can't find data section: %d\n", error); 146 exit(1); 147 } 148 149 ep_daddr = COFF_ALIGN(sh.s_vaddr); 150 doffset = sh.s_scnptr - (sh.s_vaddr - ep_daddr); 151 dsize = sh.s_size + (sh.s_vaddr - ep_daddr); 152 ep_dsize = round_page(dsize) + AoutHdr.a_bsize; 153 154 printf("addr 0x%lx size 0x%lx offset 0x%lx\n", ep_daddr, 155 dsize, doffset); 156 157 osimage = malloc(ep_tsize+dsize+sizeof(u_long) * 2); 158 if (osimage == NULL) { 159 printf("osloader:no memory\n"); 160 exit(1); 161 } 162 163 *(u_long *)osimage = ep_tsize+dsize; 164 p = osimage + 2 * sizeof(u_long); 165 166 /* load text area */ 167 fseek(fp, toffset, SEEK_SET); 168 if (fread(p, 1, ep_tsize, fp) != ep_tsize) { 169 perror("osloader:"); 170 exit(1); 171 } 172 173 /* load data area */ 174 fseek(fp, doffset, SEEK_SET); 175 if (fread(p + ep_daddr - ep_taddr, 1, dsize, fp) != dsize) { 176 perror("osloader:"); 177 exit(1); 178 } 179 180 fclose(fp); 181 182 cksum = 0; 183 size = (ep_tsize + dsize) >> 2; 184 185 for(i = 0; i < size; i++) { 186 cksum += *(u_long *)p; 187 p += sizeof(u_long); 188 } 189 190 *(u_long *)(osimage+sizeof(u_long)) = cksum; 191 192 LoadAndReset(osimage); 193 194 return (0); /* NOTREACHED */ 195 } 196