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