loadbsd.c revision 1.1.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
14 struct ExpansionBase *ExpansionBase;
15
16 #undef __LDPGSZ
17 #define __LDPGSZ 8192
18
19 void get_mem_config (void **fastmem_start, u_long *fastmem_size, u_long *chipmem_size);
20
21 int
22 main (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
107 void
108 get_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
161 asm ("
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
173 start_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
203 nott:
204
205 movew #(1<<9),0xdff096 | disable DMA
206
207 L0:
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
218 nullrp: .long 0x7fff0001
219 zero: .long 0
220
221
222 ");
223
224