2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Linux init code for emulated (Unix) systems.
9 #include <exec/types.h>
10 #include <exec/memory.h>
11 #include <exec/resident.h>
12 #include <exec/execbase.h>
14 #include <proto/exec.h>
16 #if (AROS_BIG_ENDIAN == 0)
17 #define SWAP(x) ((((ULONG)x >> 24) & 0x000000ff) |\
18 (((ULONG)x >> 8 ) & 0x0000ff00) |\
19 (((ULONG)x << 8 ) & 0x00ff0000) |\
20 (((ULONG)x << 24) & 0xff000000) )
28 #include <memory.h> /* From $(TOP)/rom/exec */
32 #include <sys/termios.h>
34 extern const struct Resident
39 /* BOOPSI_resident, */
53 Cybergraphics_resident
,
56 Mathieeesingbas_resident
,
60 emul_handler_resident
,
66 /* This list MUST be in the correct order (priority). */
67 static const struct Resident
*romtagList
[] =
69 &Expansion_resident
, /* SingleTask, 110 */
70 &Exec_resident
, /* SingleTask, 105 */
71 &Utility_resident
, /* ColdStart, 103 */
72 &Aros_resident
, /* ColdStart, 102 */
73 &Mathieeesingbas_resident
, /* ColdStart, 101 */
75 &BOOPSI_resident
, /* ColdStart, 95 */
77 &OOP_resident
, /* ColdStart, 94 */
78 &HIDD_resident
, /* ColdStart, 92 */
79 &UnixIO_resident
, /* ColdStart, 91 */
80 &Graphics_resident
, /* ColdStart, 65 */
81 &Layers_resident
, /* ColdStart, 60 */
82 &Timer_resident
, /* ColdStart, 50 */
83 &Battclock_resident
, /* ColdStart, 45 */
84 &Keyboard_resident
, /* ColdStart, 44 */
85 &Gameport_resident
, /* ColdStart, 43 */
86 &Keymap_resident
, /* ColdStart, 40 */
87 &Input_resident
, /* ColdStart, 30 */
88 &Intuition_resident
, /* ColdStart, 10 */
89 &X11Hidd_resident
, /* ColdStart, 9 */
90 &Cybergraphics_resident
, /* ColdStart, 8 */
91 &Console_resident
, /* ColdStart, 5 */
92 &emul_handler_resident
, /* ColdStart, 0 */
93 &Workbench_resident
, /* ColdStart, -120 */
94 &Mathffp_resident
, /* ColdStart, -120 */
97 NOTE: You must not put anything between these two; the code which
98 initialized boot_resident will directly call Dos_resident and
99 anything between the two will be skipped.
101 &boot_resident
, /* ColdStart, -50 */
102 &Dos_resident
, /* None, -120 */
103 &LDDemon_resident
, /* AfterDOS, -125 */
104 &con_handler_resident
, /* AfterDOS, -126 */
109 /* So we can examine the memory */
110 struct MemHeader
*mh
;
111 UBYTE
*memory
, *space
;
114 extern void InitCore(void);
115 extern struct ExecBase
*PrepareExecBase(struct MemHeader
*mh
);
118 This is where AROS is first called by whatever system loaded it,
119 either some kind of boot loader, or a "parent" operating system.
121 For boot loaded $(ARCH), you don't need to define main() like this,
122 you can have it anyway your bootloader likes.
125 int main(int argc
, char **argv
)
127 /* Well, if you want you can take in command line arguments here,
128 but that is not necessary, or perhaps rather complex...
130 eg: say you wished to allow people to specify the root directory
131 arosshell --rootdir /usr/local/AROS --memsize 4
133 For an example, you could ask how much memory you want for the
134 system, chip/fast whatever...
137 struct ExecBase
*SysBase
;
141 BOOL mapSysBase
= FALSE
;
145 if (!strcmp(argv
[i
], "--help") || !strcmp(argv
[i
], "-h"))
147 printf("AROS for Linux\n");
148 printf("usage: %s [options]\n",argv
[0]);
149 printf(" -h show this page\n");
150 printf(" -m <size> allocate <size> Megabytes of memory for AROS\n");
151 printf(" -M allows programs to read SysBase from Address $4; SysBase is");
152 printf(" found there in big endian format\n");
153 printf(" --help same as '-h'\n");
154 printf(" --memsize <size> same as '-m <size>'\n");
155 printf(" --mapsysbase same as '-M'\n");
156 printf("\nPlease report bugs to the AROS development team. http://www.aros.org\n");
160 if (!strcmp(argv
[i
], "--memsize") || !strcmp(argv
[i
], "-m"))
165 while ((argv
[i
])[x
] >= '0' && (argv
[i
])[x
] <= '9')
167 memSize
= memSize
* 10 + (argv
[i
])[x
] - '0';
173 if (!strcmp(argv
[i
], "--mapsysbase") || !strcmp(argv
[i
], "-M"))
183 First up, set up the memory.
185 If your memory starts at 0 (I think Linux does, FreeBSD doesn't),
186 then you can allocate 4K at that address, and do whatever you want
187 to make that invalid to trap NULL dereference errors.
191 if (TRUE
== mapSysBase
)
193 psize
= getpagesize();
194 space
= mmap((APTR
)0, (memSize
<< 20), PROT_READ
|PROT_WRITE
,
195 MAP_ANON
|MAP_PRIVATE
|MAP_FIXED
, -1, 0);
196 if (space
!= (UBYTE
*)-1)
198 int size
= psize
/sizeof(ULONG
);
199 memory
= (UBYTE
*)((ULONG
)space
+ psize
);
201 *((ULONG
*)space
)++ = 0xDEADBEEF;
211 /* We allocate memSize megabytes */
212 memory
= malloc((memSize
<< 20));
215 /*fprintf(stderr, "Cannot allocate any memory!\n");*/
220 /* Prepare the first mem header */
221 mh
= (struct MemHeader
*)memory
;
222 mh
->mh_Node
.ln_Type
= NT_MEMORY
;
223 mh
->mh_Node
.ln_Name
= "chip memory";
224 mh
->mh_Node
.ln_Pri
= -5;
225 mh
->mh_Attributes
= MEMF_CHIP
| MEMF_PUBLIC
| MEMF_LOCAL
|
226 MEMF_24BITDMA
| MEMF_KICK
;
227 mh
->mh_First
= (struct MemChunk
*)((UBYTE
*)mh
+MEMHEADER_TOTAL
);
228 mh
->mh_First
->mc_Next
= NULL
;
229 mh
->mh_First
->mc_Bytes
= (memSize
<< 20) - MEMHEADER_TOTAL
- psize
;
230 mh
->mh_Lower
= mh
->mh_First
;
231 mh
->mh_Upper
= (APTR
)(memory
+ (memSize
<< 20) - psize
);
232 mh
->mh_Free
= mh
->mh_First
->mc_Bytes
;
235 This will prepare enough of ExecBase to allow us to
236 call functions, it will also set up the memory list.
238 SysBase
= PrepareExecBase(mh
);
240 /* ROM memory header. This special memory header covers all ROM code and data sections
241 * so that TypeOfMem() will not return 0 for addresses pointing into the kernel.
243 if ((mh
= (struct MemHeader
*)AllocMem(sizeof(struct MemHeader
), MEMF_PUBLIC
)))
245 /* These symbols are provided by the linker on most platforms */
246 extern char _start
, _end
;
248 mh
->mh_Node
.ln_Type
= NT_MEMORY
;
249 mh
->mh_Node
.ln_Name
= "rom memory";
250 mh
->mh_Node
.ln_Pri
= -128;
251 mh
->mh_Attributes
= MEMF_KICK
;
253 mh
->mh_Lower
= (APTR
)&_start
;
254 mh
->mh_Upper
= (APTR
)&_end
;
255 mh
->mh_Free
= 0; /* Never allocate from this chunk! */
257 Enqueue(&SysBase
->MemList
, &mh
->mh_Node
);
260 /* Ok, lets start up the kernel, we are probably using the UNIX
261 kernel, or a variant of that (see config/unix).
265 /* On Linux/m68k where we can run old Amiga binaries, we should
266 put SysBase at location 4. On other systems, DON'T DO THIS.
268 if (TRUE
== mapSysBase
)
270 *(APTR
*)4 = SWAP(SysBase
);
271 if (mprotect((APTR
)0, psize
, PROT_READ
))
277 /* We might also be interested in using the BS key instead of the
278 delete key, this will do that
281 t
.c_cc
[VERASE
] = '\b';
285 tcsetattr(0, TCSANOW
|TCSASOFT
, &t
);
287 /* There is nothing more system dependant to set up,
288 so lets start that ball rolling...
290 The InitCode() call should never return in a working system.
292 SysBase
->ResModules
= romtagList
;
293 InitCode(RTF_SINGLETASK
, 0);
294 fprintf(stderr
,"Returned from InitCode()\n");