added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / arch / all-freebsd / exec / init.c
blob2fa1ad19a935ca432dab84b52237039d5356df9b
1 /*
2 Copyright © 1995-2005, 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>
17 #define _XOPEN_SOURCE 600L
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <termios.h>
23 #include "../../../rom/exec/memory.h"
25 char *malloc_options;
27 extern const struct Resident
28 Expansion_ROMTag,
29 Exec_resident,
30 Utility_ROMTag,
31 Aros_ROMTag,
32 /* BOOPSI_resident,*/
33 OOP_ROMTag,
34 HIDDCl_ROMTag,
35 UXIO_ROMTag,
36 HostLib_ROMTag,
37 Graphics_ROMTag,
38 Layers_ROMTag,
39 Timer_ROMTag,
40 Battclock_ROMTag,
41 Keyboard_ROMTag,
42 Gameport_ROMTag,
43 Keymap_ROMTag,
44 Input_ROMTag,
45 Intuition_ROMTag,
46 Cybergraphics_ROMTag,
47 Console_ROMTag,
48 #if ENABLE_DBUS == 1
49 Dbus_ROMTag,
50 #endif
51 Mathffp_ROMTag,
52 Mathieeesingbas_ROMTag,
53 Workbench_ROMTag,
54 Dos_ROMTag,
55 LDDemon_resident,
56 emul_handler_ROMTag,
57 Packet_ROMTag,
58 UXSer_ROMTag,
59 UXPar_ROMTag,
60 boot_resident,
61 Con_ROMTag,
62 Nil_ROMTag,
63 Ram_ROMTag;
67 /* This list MUST be in the correct order (priority). */
68 static const struct Resident *romtagList[] =
70 &Expansion_ROMTag, /* SingleTask, 110 */
71 &Exec_resident, /* SingleTask, 105 */
72 &Utility_ROMTag, /* ColdStart, 103 */
73 &Aros_ROMTag, /* ColdStart, 102 */
74 &Mathieeesingbas_ROMTag, /* ColdStart, 101 */
75 #if 0
76 &BOOPSI_resident, /* ColdStart, 95 */
77 #endif
78 &OOP_ROMTag, /* ColdStart, 94 */
79 &HIDDCl_ROMTag, /* ColdStart, 92 */
80 &UXIO_ROMTag, /* ColdStart, 91 */
81 &HostLib_ROMTag, /* ColdStart, 91 */
82 &Graphics_ROMTag, /* ColdStart, 65 */
83 &Layers_ROMTag, /* ColdStart, 60 */
84 &Timer_ROMTag, /* ColdStart, 50 */
85 &Battclock_ROMTag, /* ColdStart, 45 */
86 &Keyboard_ROMTag, /* ColdStart, 44 */
87 &Gameport_ROMTag, /* ColdStart, 43 */
88 &Keymap_ROMTag, /* ColdStart, 40 */
89 &Input_ROMTag, /* ColdStart, 30 */
90 &Intuition_ROMTag, /* ColdStart, 10 */
91 &Cybergraphics_ROMTag, /* ColdStart, 8 */
92 &Console_ROMTag, /* ColdStart, 5 */
93 #if ENABLE_DBUS ==1
94 &Dbus_ROMTag, /* ColdStart, 0 */
95 #endif
96 &emul_handler_ROMTag, /* ColdStart, 0 */
97 &Packet_ROMTag, /* ColdStart, 0 */
98 &UXSer_ROMTag, /* ColdStart, 0 */
99 &UXPar_ROMTag, /* ColdStart, 0 */
100 &Workbench_ROMTag, /* ColdStart, -120 */
101 &Mathffp_ROMTag, /* ColdStart, -120 */
104 NOTE: You must not put anything between these two; the code
105 which initialized boot_resident will directly call
106 Dos_resident and anything between the two will be skipped.
108 &boot_resident, /* ColdStart, -50 */
109 &Dos_ROMTag, /* None, -120 */
110 &LDDemon_resident, /* AfterDOS, -125 */
111 &Con_ROMTag, /* AfterDOS, -126 */
112 &Nil_ROMTag, /* AfterDOS, -127 */
113 &Ram_ROMTag, /* AfterDOS, -128 */
115 NULL
118 /* So we can examine the memory */
119 static struct MemHeaderExt mhe;
120 static struct MemHeader *mh = &mhe.mhe_MemHeader;
121 UBYTE *memory, *space;
122 int memSize = 32;
124 extern void InitCore(void);
125 extern struct ExecBase *PrepareExecBase(struct MemHeader *mh);
127 extern char _start, _end;
130 This is where AROS is first called by whatever system loaded it,
131 either some kind of boot loader, or a "parent" operating system.
133 For boot loaded $(ARCH), you don't need to define main() like this,
134 you can have it anyway your bootloader likes.
137 int main(int argc, char **argv)
139 /* Well, if you want you can take in command line arguments here,
140 but that is not necessary, or perhaps rather complex...
142 eg: say you wished to allow people to specify the root directory
143 arosshell --rootdir /usr/local/AROS --memsize 4
145 For an example, you could ask how much memory you want for the
146 system, chip/fast whatever...
149 struct ExecBase *SysBase;
150 struct termios t;
151 int psize = 0;
152 int i = 0, x;
153 BOOL mapSysBase = FALSE;
155 while (i < argc)
157 if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
159 printf("AROS for FreeBSD\n");
160 printf("usage: %s [options]\n",argv[0]);
161 printf(" -h show this page\n");
162 printf(" -m <size> allocate <size> Megabytes of memory for AROS\n");
163 printf(" -M allows programs to read SysBase from Address $4; SysBase is");
164 printf(" found there in big endian format\n");
165 printf(" --help same as '-h'\n");
166 printf(" --memsize <size> same as '-m <size>'\n");
167 printf(" --mapsysbase same as '-M'\n");
168 printf("\nPlease report bugs to the AROS development team. http://www.aros.org\n");
169 return 0;
171 else
172 if (!strcmp(argv[i], "--memsize") || !strcmp(argv[i], "-m"))
174 i++;
175 x = 0;
176 memSize = 0;
177 while ((argv[i])[x] >= '0' && (argv[i])[x] <= '9')
179 memSize = memSize * 10 + (argv[i])[x] - '0';
180 x++;
182 i++;
184 else
185 if (!strcmp(argv[i], "--mapsysbase") || !strcmp(argv[i], "-M"))
187 mapSysBase = TRUE;
188 i++;
190 else
191 i++;
194 First up, set up the memory.
196 If your memory starts at 0 (I think Linux does, FreeBSD doesn't),
197 then you can allocate 4K at that address, and do whatever you want
198 to make that invalid to trap NULL dereference errors.
201 #ifdef __linux__
202 space = malloc(4096);
203 if(space)
205 int size = 4096/sizeof(ULONG);
206 while(--size)
207 *space++ = 0xDEADBEEF;
209 #endif
211 Magic, this makes FreeBSD's malloc() print out lots of extra
212 debugging information, and more to the point, call abort()
213 when something naughty happens.
215 malloc_options = "A";
217 /* We allocate memSize megabytes, plus a little extra */
218 memory = malloc((memSize << 20) + MEMCHUNK_TOTAL);
219 if( !memory )
221 /*fprintf(stderr, "Cannot allocate any memory!\n");*/
222 exit(20);
225 /* Prepare the first mem header */
226 mh->mh_Node.ln_Name = "chip memory";
227 mh->mh_Node.ln_Pri = -5;
228 mh->mh_Attributes = MEMF_CHIP | MEMF_PUBLIC;
229 mh->mh_First = (struct MemChunk *)
230 (((IPTR)memory + MEMCHUNK_TOTAL-1) & ~(MEMCHUNK_TOTAL-1));
231 mh->mh_First->mc_Next = NULL;
232 mh->mh_First->mc_Bytes = memSize << 20;
233 mh->mh_Lower = memory;
234 mh->mh_Upper = memory + MEMCHUNK_TOTAL + mh->mh_First->mc_Bytes;
235 mh->mh_Free = mh->mh_First->mc_Bytes;
238 This will prepare enough of ExecBase to allow us to
239 call functions, it will also set up the memory list.
241 SysBase = PrepareExecBase(mh);
243 if ((mh = (struct MemHeader *)AllocMem(sizeof(struct MemHeader), MEMF_PUBLIC)))
245 /* These symbols are provided by the linker on most platforms */
246 mh->mh_Node.ln_Type = NT_MEMORY;
247 mh->mh_Node.ln_Name = "rom memory";
248 mh->mh_Node.ln_Pri = -128;
249 mh->mh_Attributes = MEMF_KICK;
250 mh->mh_First = NULL;
251 mh->mh_Lower = (APTR)&_start;
252 mh->mh_Upper = (APTR)&_end;
253 mh->mh_Free = 0;
254 Forbid();
255 Enqueue(&SysBase->MemList, &mh->mh_Node);
258 /* Ok, lets start up the kernel, we are probably using the UNIX
259 kernel, or a variant of that (see config/unix).
261 InitCore();
263 /* On Linux/m68k where we can run old Amiga binaries, we should
264 put SysBase at location 4. On other systems, DON'T DO THIS.
266 #if defined(__linux__) && defined(__mc68000__)
267 if( mmap((APTR)0, getpagesize(), PROT_READ|PROT_WRITE,
268 MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0) != (APTR)0 )
270 perror("mmap: Can't map page 0\n");
271 exit(10);
274 *(APTR *)4 = SysBase;
275 if(mprotect((APTR)0,getpagesize(), PROT_READ))
277 perror("mprotect");
278 exit(10);
280 #endif
282 /* We might also be interested in using the BS key instead of the
283 delete key, this will do that
285 tcgetattr(0, &t);
286 t.c_cc[VERASE] = '\b';
287 #ifndef TCSASOFT
288 # define TCSASOFT 0
289 #endif
290 tcsetattr(0, TCSANOW|TCSASOFT, &t);
292 /* There is nothing more system dependant to set up,
293 so lets start that ball rolling...
295 The InitCode() call should never return in a working system.
297 SysBase->ResModules = romtagList;
298 InitCode(RTF_SINGLETASK, 0);
299 fprintf(stderr,"Returned from InitCode()\n");
300 return 1;