Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / arch / all-freebsd / exec / init.c
blob611c7f5767637913740fd7dfac2f9e5bc1845fef
1 /*
2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: $(ARCH) init code for emulated (Unix) systems.
6 Lang: english
7 */
9 #include <exec/types.h>
10 #include <exec/memory.h>
11 #include <exec/memheaderext.h>
12 #include <exec/resident.h>
13 #include <exec/execbase.h>
15 #include <proto/exec.h>
16 #include <aros/debug.h>
18 #define _XOPEN_SOURCE 600L
19 #include <sys/param.h>
20 #include <sys/stat.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <termios.h>
25 #include <unistd.h>
27 #include "../../../rom/exec/memory.h"
29 char *malloc_options;
31 extern const struct Resident
32 Expansion_ROMTag,
33 Exec_resident,
34 Utility_ROMTag,
35 Aros_ROMTag,
36 Bootloader_ROMTag,
37 OOP_ROMTag,
38 HIDDCl_ROMTag,
39 UXIO_ROMTag,
40 HostLib_ROMTag,
41 Graphics_ROMTag,
42 Layers_ROMTag,
43 Timer_ROMTag,
44 Battclock_ROMTag,
45 Keyboard_ROMTag,
46 Gameport_ROMTag,
47 Keymap_ROMTag,
48 Input_ROMTag,
49 Intuition_ROMTag,
50 Cybergraphics_ROMTag,
51 Console_ROMTag,
52 #if ENABLE_DBUS == 1
53 Dbus_ROMTag,
54 #endif
55 Mathffp_ROMTag,
56 Mathieeesingbas_ROMTag,
57 Workbench_ROMTag,
58 Dos_ROMTag,
59 LDDemon_resident,
60 emul_handler_ROMTag,
61 Packet_ROMTag,
62 UXSer_ROMTag,
63 UXPar_ROMTag,
64 boot_resident,
65 Con_ROMTag,
66 Nil_ROMTag,
67 Ram_ROMTag,
68 Dosboot_ROMTag,
69 GFX_ROMTag,
70 #if ENABLE_X11 == 1
71 X11Cl_ROMTag,
72 #endif
73 Bootmenu_ROMTag;
75 /* This list MUST be in the correct order (priority). */
76 static const struct Resident *romtagList[] =
78 &Expansion_ROMTag, /* SingleTask, 110 */
79 &Exec_resident, /* SingleTask, 126 */
80 &Utility_ROMTag, /* ColdStart, 103 */
81 &Aros_ROMTag, /* ColdStart, 102 */
82 &Bootloader_ROMTag, /* ColdStart, 100 */
83 &OOP_ROMTag, /* ColdStart, 94 */
84 &HIDDCl_ROMTag, /* ColdStart, 92 */
85 &UXIO_ROMTag, /* ColdStart, 91 */
86 &HostLib_ROMTag, /* ColdStart, 91 */
87 &Graphics_ROMTag, /* ColdStart, 65 */
88 &Layers_ROMTag, /* ColdStart, 60 */
89 &Timer_ROMTag, /* ColdStart, 50 */
90 &Battclock_ROMTag, /* ColdStart, 45 */
91 &Keyboard_ROMTag, /* ColdStart, 44 */
92 &Gameport_ROMTag, /* ColdStart, 44 */
93 &Keymap_ROMTag, /* ColdStart, 40 */
94 &Input_ROMTag, /* ColdStart, 30 */
95 &Intuition_ROMTag, /* ColdStart, 15 */
96 &GFX_ROMTag, /* ColdStart, 10 */
97 #if ENABLE_X11 == 1
98 &X11Cl_ROMTag, /* ColdStart, 9 */
99 #endif
100 &Cybergraphics_ROMTag, /* ColdStart, 8 */
101 &Console_ROMTag, /* ColdStart, 5 */
102 #if ENABLE_DBUS == 1
103 &Dbus_ROMTag, /* ColdStart, 0 */
104 #endif
105 &emul_handler_ROMTag, /* ColdStart, 0 */
106 &UXSer_ROMTag, /* ColdStart, 0 */
107 &UXPar_ROMTag, /* ColdStart, 0 */
110 NOTE: You must not put anything between these two; the code
111 which initialized boot_resident will directly call
112 Dos_resident and anything between the two will be skipped.
114 &boot_resident, /* ColdStart, -50 */
115 &Dos_ROMTag, /* None, -120 */
116 &LDDemon_resident, /* AfterDOS, -123 */
117 &Con_ROMTag, /* AfterDOS, -124 */
118 &Packet_ROMTag, /* AfterDOS, -124 */
119 &Nil_ROMTag, /* AfterDOS, -125 */
120 &Ram_ROMTag, /* AfterDOS, -125 */
121 &Bootmenu_ROMTag, /* AfterDOS, -127 */
122 &Dosboot_ROMTag, /* AfterDOS, -128 */
123 NULL
126 /* So we can examine the memory */
127 static struct MemHeaderExt mhe;
128 static struct MemHeader *mh = &mhe.mhe_MemHeader;
129 UBYTE *memory, *space;
130 int memSize = 32;
132 extern void InitCore(void);
133 extern struct ExecBase *PrepareExecBase(struct MemHeader *mh);
135 char *join_string(int argc, char **argv)
137 char *str, *s;
138 int j;
139 int x = 0;
141 for (j = 0; j < argc; j++)
142 x += (strlen(argv[j]) + 1);
143 D(printf("[Init] Allocating %lu bytes for string\n", x));
144 str = malloc(x);
145 if (str) {
146 s = str;
147 for (j = 0; j < argc; j++) {
148 strcpy(s, argv[j]);
149 s += strlen(s);
150 *s++ = ' ';
152 s[-1] = 0;
153 D(printf("[Init] Joined line: %s\n", str));
155 return str;
158 extern char _start, _end;
159 char bootstrapdir[PATH_MAX];
160 char *BootLoader_Name = "FreeBSD";
161 char *Kernel_Args = NULL;
162 char **Kernel_ArgV;
165 This is where AROS is first called by whatever system loaded it,
166 either some kind of boot loader, or a "parent" operating system.
168 For boot loaded $(ARCH), you don't need to define main() like this,
169 you can have it anyway your bootloader likes.
172 int main(int argc, char **argv)
174 struct ExecBase *SysBase;
175 struct termios t;
176 int psize = 0;
177 int i = 0, x;
178 BOOL mapSysBase = FALSE;
179 struct stat st;
181 getcwd(bootstrapdir, PATH_MAX);
183 while (i < argc)
185 if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
187 printf("AROS for FreeBSD\n");
188 printf("usage: %s [options] [kernel arguments]\n",argv[0]);
189 printf("Availible options:\n");
190 printf(" -h show this page\n");
191 printf(" -m <size> allocate <size> Megabytes of memory for AROS\n");
192 printf(" -M allows programs to read SysBase from Address $4; SysBase is");
193 printf(" found there in big endian format\n");
194 printf(" --help same as '-h'\n");
195 printf(" --memsize <size> same as '-m <size>'\n");
196 printf(" --mapsysbase same as '-M'\n");
197 printf("\nPlease report bugs to the AROS development team. http://www.aros.org\n");
198 return 0;
200 else
201 if (!strcmp(argv[i], "--memsize") || !strcmp(argv[i], "-m"))
203 i++;
204 x = 0;
205 memSize = 0;
206 while ((argv[i])[x] >= '0' && (argv[i])[x] <= '9')
208 memSize = memSize * 10 + (argv[i])[x] - '0';
209 x++;
211 i++;
213 else
214 if (!strcmp(argv[i], "--mapsysbase") || !strcmp(argv[i], "-M"))
216 mapSysBase = TRUE;
217 i++;
219 else
220 break;
223 if (i < argc)
224 Kernel_Args = join_string(argc - i, &argv[i]);
225 Kernel_ArgV = argv;
227 if (!stat("../AROS.boot", &st))
228 chdir("..");
230 First up, set up the memory.
232 If your memory starts at 0 (I think Linux does, FreeBSD doesn't),
233 then you can allocate 4K at that address, and do whatever you want
234 to make that invalid to trap NULL dereference errors.
237 #ifdef __linux__
238 space = malloc(4096);
239 if(space)
241 int size = 4096/sizeof(ULONG);
242 while(--size)
243 *space++ = 0xDEADBEEF;
245 #endif
247 Magic, this makes FreeBSD's malloc() print out lots of extra
248 debugging information, and more to the point, call abort()
249 when something naughty happens.
251 malloc_options = "A";
253 /* We allocate memSize megabytes, plus a little extra */
254 memory = malloc((memSize << 20) + MEMCHUNK_TOTAL);
255 if( !memory )
257 /*fprintf(stderr, "Cannot allocate any memory!\n");*/
258 exit(20);
261 /* Prepare the first mem header */
262 mh->mh_Node.ln_Name = "chip memory";
263 mh->mh_Node.ln_Pri = -5;
264 mh->mh_Attributes = MEMF_CHIP | MEMF_PUBLIC;
265 mh->mh_First = (struct MemChunk *)
266 (((IPTR)memory + MEMCHUNK_TOTAL-1) & ~(MEMCHUNK_TOTAL-1));
267 mh->mh_First->mc_Next = NULL;
268 mh->mh_First->mc_Bytes = memSize << 20;
269 mh->mh_Lower = memory;
270 mh->mh_Upper = memory + MEMCHUNK_TOTAL + mh->mh_First->mc_Bytes;
271 mh->mh_Free = mh->mh_First->mc_Bytes;
274 This will prepare enough of ExecBase to allow us to
275 call functions, it will also set up the memory list.
277 SysBase = PrepareExecBase(mh);
279 if ((mh = (struct MemHeader *)AllocMem(sizeof(struct MemHeader), MEMF_PUBLIC)))
281 /* These symbols are provided by the linker on most platforms */
282 mh->mh_Node.ln_Type = NT_MEMORY;
283 mh->mh_Node.ln_Name = "rom memory";
284 mh->mh_Node.ln_Pri = -128;
285 mh->mh_Attributes = MEMF_KICK;
286 mh->mh_First = NULL;
287 mh->mh_Lower = (APTR)&_start;
288 mh->mh_Upper = (APTR)&_end;
289 mh->mh_Free = 0;
290 Forbid();
291 Enqueue(&SysBase->MemList, &mh->mh_Node);
294 /* Ok, lets start up the kernel, we are probably using the UNIX
295 kernel, or a variant of that (see config/unix).
297 InitCore();
299 /* On Linux/m68k where we can run old Amiga binaries, we should
300 put SysBase at location 4. On other systems, DON'T DO THIS.
302 #if defined(__linux__) && defined(__mc68000__)
303 if( mmap((APTR)0, getpagesize(), PROT_READ|PROT_WRITE,
304 MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0) != (APTR)0 )
306 perror("mmap: Can't map page 0\n");
307 exit(10);
310 *(APTR *)4 = SysBase;
311 if(mprotect((APTR)0,getpagesize(), PROT_READ))
313 perror("mprotect");
314 exit(10);
316 #endif
318 /* We might also be interested in using the BS key instead of the
319 delete key, this will do that
321 tcgetattr(0, &t);
322 t.c_cc[VERASE] = '\b';
323 #ifndef TCSASOFT
324 # define TCSASOFT 0
325 #endif
326 tcsetattr(0, TCSANOW|TCSASOFT, &t);
328 /* There is nothing more system dependant to set up,
329 so lets start that ball rolling...
331 The InitCode() call should never return in a working system.
333 SysBase->ResModules = romtagList;
334 InitCode(RTF_SINGLETASK, 0);
335 fprintf(stderr,"Returned from InitCode()\n");
336 return 1;