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