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