1 #include <sys/types.h> 2 #include <a.out.h> 3 #include <stdio.h> 4 5 #include <exec/types.h> 6 #include <exec/execbase.h> 7 #include <exec/memory.h> 8 #include <libraries/configregs.h> 9 #include <libraries/expansionbase.h> 10 11 #include <inline/exec.h> 12 #include <inline/expansion.h> 13 14 /* Get definitions for boothowto */ 15 #include "reboot.h" 16 17 struct ExpansionBase *ExpansionBase; 18 19 #undef __LDPGSZ 20 #define __LDPGSZ 8192 21 22 void get_mem_config (void **fastmem_start, u_long *fastmem_size, u_long *chipmem_size); 23 24 int 25 main (int argc, char *argv[]) 26 { 27 struct exec e; 28 int fd; 29 int boothowto = RB_SINGLE; 30 31 if (argc >= 2) 32 { 33 if ((fd = open (argv[1], 0)) >= 0) 34 { 35 if (read (fd, &e, sizeof (e)) == sizeof (e)) 36 { 37 if (e.a_magic == NMAGIC) 38 { 39 u_char *kernel; 40 int text_size; 41 struct ConfigDev *cd; 42 int num_cd; 43 44 ExpansionBase= (struct ExpansionBase *) OpenLibrary ("expansion.library", 0); 45 if (! ExpansionBase) /* not supposed to fail... */ 46 abort(); 47 for (cd = 0, num_cd = 0; cd = FindConfigDev (cd, -1, -1); num_cd++) ; 48 49 text_size = (e.a_text + __LDPGSZ - 1) & (-__LDPGSZ); 50 kernel = (u_char *) malloc (text_size + e.a_data + e.a_bss 51 + num_cd*sizeof(*cd) + 4); 52 53 if (kernel) 54 { 55 if (read (fd, kernel, e.a_text) == e.a_text 56 && read (fd, kernel + text_size, e.a_data) == e.a_data) 57 { 58 int *knum_cd; 59 struct ConfigDev *kcd; 60 void *fastmem_start; 61 u_long fastmem_size, chipmem_size; 62 63 get_mem_config (&fastmem_start, &fastmem_size, &chipmem_size); 64 65 if (argc >= 3 && (!strcmp (argv[2], "-k") 66 || !strcmp (argv[3], "-k")) ) 67 { 68 fastmem_start += 4*1024*1024; 69 fastmem_size -= 4*1024*1024; 70 } 71 72 if (argc >= 3 && (!strcmp (argv[2], "-a") 73 || !strcmp (argv[3], "-a")) ) 74 { 75 printf("Autobooting..."); 76 boothowto = RB_AUTOBOOT; 77 } 78 79 printf ("Using %dM FASTMEM at 0x%x, %dM CHIPMEM\n", 80 fastmem_size>>20, fastmem_start, chipmem_size>>20); 81 /* give them a chance to read the information... */ 82 sleep(2); 83 84 bzero (kernel + text_size + e.a_data, e.a_bss); 85 knum_cd = (int *) (kernel + text_size + e.a_data + e.a_bss); 86 *knum_cd = num_cd; 87 if (num_cd) 88 for (kcd = (struct ConfigDev *) (knum_cd+1); 89 cd = FindConfigDev (cd, -1, -1); 90 *kcd++ = *cd) ; 91 startit (kernel, 92 text_size + e.a_data + e.a_bss + num_cd*sizeof(*cd) + 4, 93 e.a_entry, fastmem_start, 94 fastmem_size, chipmem_size, 95 boothowto ); 96 } 97 else 98 fprintf (stderr, "Executable corrupt!\n"); 99 } 100 else 101 fprintf (stderr, "Out of memory! (%d)\n", text_size + e.a_data + e.a_bss 102 + num_cd*sizeof(*cd) + 4); 103 } 104 else 105 fprintf (stderr, "Unsupported executable: %o\n", e.a_magic); 106 } 107 else 108 fprintf (stderr, "Can't read header of %s\n", argv[1]); 109 110 close (fd); 111 } 112 else 113 perror ("open"); 114 } 115 else 116 fprintf (stderr, "%s some-vmunix [-a] [-k]\n", argv[0]); 117 } 118 119 120 void 121 get_mem_config (void **fastmem_start, u_long *fastmem_size, u_long *chipmem_size) 122 { 123 extern struct ExecBase *SysBase; 124 struct MemHeader *mh, *nmh; 125 126 *fastmem_size = 0; 127 *chipmem_size = 0; 128 129 /* walk thru the exec memory list */ 130 Forbid (); 131 for (mh = (struct MemHeader *) SysBase->MemList.lh_Head; 132 nmh = (struct MemHeader *) mh->mh_Node.ln_Succ; 133 mh = nmh) 134 { 135 if (mh->mh_Attributes & MEMF_CHIP) 136 { 137 /* there should hardly be more than one entry for chip mem, but 138 handle it the same nevertheless */ 139 if ((u_int)mh->mh_Upper - (u_int)mh->mh_Lower > *chipmem_size) 140 { 141 *chipmem_size = (u_int)mh->mh_Upper - (u_int)mh->mh_Lower; 142 /* round to multiple of 512K */ 143 *chipmem_size = (*chipmem_size + 512*1024 - 1) & -(512*1024); 144 145 /* chipmem always starts at 0, so don't remember start 146 address */ 147 } 148 } 149 else 150 { 151 if ((u_int)mh->mh_Upper - (u_int)mh->mh_Lower > *fastmem_size) 152 { 153 u_int start = (u_int) mh->mh_Lower; 154 u_int end = (u_int) mh->mh_Upper; 155 156 /* some heuristics.. */ 157 start &= -__LDPGSZ; 158 /* get the mem back stolen by incore kickstart on A3000 with 159 V36 bootrom. */ 160 if (end == 0x07f80000) 161 end = 0x08000000; 162 163 *fastmem_size = end - start; 164 *fastmem_start = (void *)start; 165 } 166 } 167 } 168 Permit(); 169 } 170 171 172 173 174 asm (" 175 .set ABSEXECBASE,4 176 177 .text 178 .globl _startit 179 180 _startit: 181 movel sp,a3 182 movel 4:w,a6 183 lea pc@(start_super-.+2),a5 184 jmp a6@(-0x1e) | supervisor-call 185 186 start_super: 187 movew #0x2700,sr 188 189 | the BSD kernel wants values into the following registers: 190 | a0: fastmem-start 191 | d0: fastmem-size 192 | d1: chipmem-size 193 | d7: boothowto 194 195 movel a3@(4),a1 | loaded kernel 196 movel a3@(8),d2 | length of loaded kernel 197 movel a3@(12),a2 | entry point 198 movel a3@(16),a0 | fastmem-start 199 movel a3@(20),d0 | fastmem-size 200 movel a3@(24),d1 | chipmem-size 201 movel a3@(28),d7 | boothowto 202 subl a4,a4 | target, load to 0 203 204 lea pc@(zero-.+2),a3 205 pmove a3@,tc | Turn off MMU 206 lea pc@(nullrp-.+2),a3 207 pmove a3@,crp | Turn off MMU some more 208 pmove a3@,srp | Really, really, turn off MMU 209 210 | Turn off 68030 TT registers 211 212 btst #2,(ABSEXECBASE)@(0x129) | AFB_68030,SysBase->AttnFlags 213 beq nott | Skip TT registers if not 68030 214 lea pc@(zero-.+2),a3 215 .word 0xf013,0x0800 | pmove a3@,tt0 (gas only knows about 68851 ops..) 216 .word 0xf013,0x0c00 | pmove a3@,tt1 (gas only knows about 68851 ops..) 217 218 nott: 219 220 movew #(1<<9),0xdff096 | disable DMA 221 222 L0: 223 moveb a1@+,a4@+ 224 subl #1,d2 225 bcc L0 226 227 228 jmp a2@ 229 230 231 | A do-nothing MMU root pointer (includes the following long as well) 232 233 nullrp: .long 0x7fff0001 234 zero: .long 0 235 236 237 "); 238 239