2 * Copyright (C) 2011, The AROS Development Team. All rights reserved.
4 * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
7 /* This loads relocatable AROS ROM ELF images, and gzipped
8 * image. Use either the aros-amiga-m68k-reloc.elf or
9 * aros.elf.gz images. The fully linked aros-amiga-m68k.elf
10 * image cannot be loaded by this application.
12 * As you can probably guess, you will need at least 1MB of
13 * MEMF_LOCAL RAM to get this to work.
15 * We also use MEMF_KICK, since some MEMF_KICK ram may will
16 * be available after expansion.library processing.
18 * Also - no AROS specific code can go in here! We have to run
23 #include <proto/exec.h>
24 #include <proto/graphics.h>
25 #include <proto/dos.h>
26 #include <exec/resident.h>
27 #include <aros/kernel.h>
28 #include <hardware/cpu/memory.h>
30 #include <stddef.h> /* offsetof */
31 #include <string.h> /* memcpy, memset */
34 #if defined(DEBUG) && DEBUG
35 #define DEFAULT_KERNEL_CMDLINE "sysdebug=InitCode mungwall"
37 #define DEFAULT_KERNEL_CMDLINE "sysdebug=InitCode"
40 #define PROTO_KERNEL_H /* Don't pick up AROS kernel hooks */
41 #define NO_SYSBASE_REMAP
47 static inline void bug(const char *fmt
, ...)
49 static char buff
[256];
53 vsnprintf(buff
, sizeof(buff
), fmt
, args
);
56 Write(Output(), buff
, strlen(buff
));
65 struct DosLibrary
*DOSBase
;
67 static BOOL ROM_Loaded
= FALSE
;
68 static struct List mlist
;
70 /* KS 1.3 (and earlier) don't have a dos.library with
71 * niceties such as VFPrintf nor ReadArgs.
73 * We need to use the BCPL routines to be able
74 * to do these types of operations.
76 #define BCPL_WriteS 73
77 #define BCPL_WriteF 74
78 #define BCPL_RdArgs 78
81 #define Printf __Printf_NOT_AVAILABLE_UNDER_KS1_3
83 #define ReadArgs __ReadArgs_NOT_AVAILABLE_UNDER_KS1_3
85 /* BCPL can trash D5-D7 and A3, evidently.
87 static void bcplWrapper(void)
90 "movem.l %d5-%d7/%a3,%sp@-\n"
92 "movem.l %sp@+,%d5-%d7/%a3\n"
96 static ULONG
doBCPL(int index
, ULONG d1
, ULONG d2
, ULONG d3
, ULONG d4
, const IPTR
*arg
, int args
)
98 struct Process
*pr
= (APTR
)FindTask(NULL
);
100 ULONG
*gv
= pr
->pr_GlobVec
;
102 ULONG
*BCPL_frame
= AllocMem(1500, MEMF_ANY
);
103 if (BCPL_frame
== NULL
)
106 func
= (APTR
)gv
[index
];
109 CopyMem(arg
, &BCPL_frame
[3 + 4], args
* sizeof(ULONG
));
111 ret
= AROS_UFC11(ULONG
, bcplWrapper
,
112 AROS_UFCA(ULONG
, 0, D0
), /* BCPL frame usage (args-3)*/
113 AROS_UFCA(ULONG
, d1
, D1
),
114 AROS_UFCA(ULONG
, d2
, D2
),
115 AROS_UFCA(ULONG
, d3
, D3
),
116 AROS_UFCA(ULONG
, d4
, D4
),
117 AROS_UFCA(ULONG
, 0, A0
), /* System memory base */
118 AROS_UFCA(ULONG
*, &BCPL_frame
[3], A1
),
119 AROS_UFCA(APTR
, gv
, A2
),
120 AROS_UFCA(APTR
, func
, A4
),
121 AROS_UFCA(APTR
, DOSBase
->dl_A5
, A5
),
122 AROS_UFCA(APTR
, DOSBase
->dl_A6
, A6
));
124 FreeMem(BCPL_frame
, 1500);
129 static UBYTE
*ConvertBSTR(BSTR bname
)
131 UBYTE
*name
= BADDR(bname
);
132 UBYTE
*s
= AllocMem(256 + 1, MEMF_CLEAR
);
135 CopyMem(name
+ 1, s
, name
[0]);
139 static void FreeString(UBYTE
*cstr
)
141 FreeMem(cstr
, 256+1);
144 static void _WriteF(BPTR bfmt
, ...)
146 IPTR
*args
= (IPTR
*)&bfmt
;
148 doBCPL(BCPL_WriteF
, bfmt
, args
[1], args
[2], args
[3], &args
[4], 26-3);
151 #define WriteF(fmt, args...) _WriteF(AROS_CONST_BSTR(fmt) ,##args )
153 /* For KS < 2.0, we need to call the BCPL ReadArgs,
154 * since DOS/ReadArgs doesn't exist.
156 static ULONG
RdArgs(BSTR format
, BPTR args
, ULONG max_arg
)
158 return doBCPL(BCPL_RdArgs
, format
, args
, max_arg
, 0, NULL
, 0);
163 struct MemHeader
*mh
;
164 ForeachNode(&SysBase
->MemList
, mh
) {
166 bstr
[0] = strlen(mh
->mh_Node
.ln_Name
) & 0xff;
167 strncpy(&bstr
[1], mh
->mh_Node
.ln_Name
, bstr
[0]);
168 WriteF("@$%X8-$%X8 ATTR $%X4 FREE $%X8 (%S)\n",
169 mh
->mh_Lower
, mh
->mh_Upper
, mh
->mh_Attributes
,
170 mh
->mh_Free
, MKBADDR(bstr
));
174 /* Allocate MMU page aligned memory chunks */
176 #define ALLOCPADDING (sizeof(struct MemChunk) + 2 * sizeof(BPTR))
178 static APTR
AllocPageAligned(ULONG
*psize
, ULONG flags
)
184 size
+= ALLOCPADDING
;
185 ret
= AllocMem(size
+ 2 * PAGE_SIZE
, flags
);
186 D(WriteF("AllocPageAligned: $%X8, %X4 => %X8\n", size
+ 2 * PAGE_SIZE
, flags
, ret
));
190 FreeMem(ret
, size
+ 2 * PAGE_SIZE
);
191 size
= (size
+ PAGE_SIZE
- 1) & PAGE_MASK
;
192 ret
= AllocAbs(size
, (APTR
)(((((ULONG
)ret
) + PAGE_SIZE
- 1) & PAGE_MASK
)));
199 static void FreePageAligned(APTR addr
, ULONG size
)
201 FreeMem(addr
, (size
+ PAGE_SIZE
- 1) & PAGE_MASK
);
204 /* Define these here for zlib so that we don't
205 * pull in arosc.library.
207 * We can't use AllocVec, since it's only
208 * been around since KS v36
210 void *malloc(int size
)
214 size
+= sizeof(ULONG
);
216 vec
= AllocMem(size
, MEMF_ANY
);
218 WriteF("libz: Failed to allocate %N bytes of type %X8\n", size
, MEMF_ANY
);
222 vec
[0] = (ULONG
)size
;
228 ULONG
*vec
= ptr
- sizeof(ULONG
);
229 FreeMem(vec
, vec
[0]);
232 int open(const char *name
, int mode
)
234 return (int)Open(name
, MODE_OLDFILE
);
242 int read(int fd
, void *buff
, size_t len
)
244 return Read((BPTR
)fd
, buff
, (LONG
)len
);
247 off_t
lseek(int fd
, off_t offset
, int whence
)
249 LONG mode
= SEEK_SET
;
253 case SEEK_CUR
: mode
= OFFSET_CURRENT
; break;
254 case SEEK_SET
: mode
= OFFSET_BEGINNING
; break;
255 case SEEK_END
: mode
= OFFSET_END
; break;
259 err
= Seek((BPTR
)fd
, (LONG
)offset
, mode
);
263 return Seek((BPTR
)fd
, 0, OFFSET_CURRENT
);
266 static AROS_UFH4(LONG
, aosRead
,
267 AROS_UFHA(BPTR
, file
, D1
),
268 AROS_UFHA(void *, buf
, D2
),
269 AROS_UFHA(LONG
, size
, D3
),
270 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
274 return Read(file
, buf
, (unsigned)size
);
278 static AROS_UFH4(LONG
, aosSeek
,
279 AROS_UFHA(BPTR
, file
, D1
),
280 AROS_UFHA(LONG
, pos
, D2
),
281 AROS_UFHA(LONG
, mode
, D3
),
282 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
290 case OFFSET_CURRENT
: whence
= SEEK_CUR
; break;
291 case OFFSET_END
: whence
= SEEK_END
; break;
292 case OFFSET_BEGINNING
: whence
= SEEK_SET
; break;
296 oldpos
= (LONG
)Seek(file
, 0, SEEK_CUR
);
298 ret
= (LONG
)Seek(file
, (z_off_t
)pos
, whence
);
307 static APTR
aosAllocMem(ULONG size
, ULONG flags
, struct ExecBase
*SysBase
)
312 /* Clear bits 15-0, we're setting memory class explicitly */
315 if (SysBase
->LibNode
.lib_Version
>= 36) {
316 flags
|= MEMF_LOCAL
| MEMF_REVERSE
;
321 size
+= sizeof(struct MemChunk
) + sizeof(struct MemList
);
322 mem
= AllocMem(size
, flags
);
324 WriteF("AOS: Failed to allocate %N bytes of type %X8\n", size
, flags
);
329 ml
= (struct MemList
*)(mem
+ sizeof(struct MemChunk
));
330 ml
->ml_NumEntries
= 1;
331 ml
->ml_ME
[0].me_Addr
= (APTR
)mem
;
332 ml
->ml_ME
[0].me_Length
= size
;
333 AddTail(&mlist
, (struct Node
*)ml
);
338 static AROS_UFH3(APTR
, aosAlloc
,
339 AROS_UFHA(ULONG
, size
, D0
),
340 AROS_UFHA(ULONG
, flags
, D1
),
341 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
345 return aosAllocMem(size
, flags
, SysBase
);
349 static AROS_UFH3(void, aosFree
,
350 AROS_UFHA(APTR
, addr
, A1
),
351 AROS_UFHA(ULONG
, size
, D0
),
352 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
356 addr
-= sizeof(struct MemList
);
357 Remove((struct Node
*)addr
);
358 addr
-= sizeof(struct MemChunk
);
359 size
+= sizeof(struct MemChunk
) + sizeof(struct MemList
);
365 /* Backcalls for LoadSegment
366 * using the gzip backend.
368 static AROS_UFH4(LONG
, elfRead
,
369 AROS_UFHA(BPTR
, file
, D1
),
370 AROS_UFHA(void *, buf
, D2
),
371 AROS_UFHA(LONG
, size
, D3
),
372 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
376 return gzread((gzFile
)file
, buf
, (unsigned)size
);
380 static AROS_UFH4(LONG
, elfSeek
,
381 AROS_UFHA(BPTR
, file
, D1
),
382 AROS_UFHA(LONG
, pos
, D2
),
383 AROS_UFHA(LONG
, mode
, D3
),
384 AROS_UFHA(struct DosLibrary
*, DOSBase
, A6
))
392 case OFFSET_CURRENT
: whence
= SEEK_CUR
; break;
393 case OFFSET_END
: whence
= SEEK_END
; break;
394 case OFFSET_BEGINNING
: whence
= SEEK_SET
; break;
398 oldpos
= (LONG
)gzseek((gzFile
)file
, 0, SEEK_CUR
);
400 ret
= (LONG
)gzseek((gzFile
)file
, (z_off_t
)pos
, whence
);
409 static AROS_UFH3(APTR
, elfAlloc
,
410 AROS_UFHA(ULONG
, size
, D0
),
411 AROS_UFHA(ULONG
, flags
, D1
),
412 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
418 D(WriteF("ELF: Attempt to allocate %N bytes of type %X8\n", size
, flags
));
419 /* Since we don't know if we need to wrap the memory
420 * with the KickMem wrapper until after allocation,
421 * we always adjust the size as if we have to.
423 size
+= sizeof(struct MemChunk
) + sizeof(struct MemList
);
425 /* If it's MEMF_LOCAL or MEMF_CHIP, our Exec init
426 * will automatically protect it from allocation after reset.
428 if (flags
& MEMF_KICK
) {
429 if (SysBase
->LibNode
.lib_Version
< 39) {
430 /* Ok, can't use MEMF_KICK.
431 * Hope and pray that MEMF_FAST is available
432 * after expansion.library is done.
439 /* Hmm. MEMF_LOCAL is only available on v36 and later.
440 * Use MEMF_CHIP if we have to.
442 if ((flags
& MEMF_LOCAL
) && (SysBase
->LibNode
.lib_Version
< 36)) {
443 flags
&= ~MEMF_LOCAL
;
447 /* MEMF_31BIT is not available on AOS */
448 if ((flags
& MEMF_31BIT
)) {
449 flags
&= ~MEMF_31BIT
;
452 /* If ROM allocation, always allocate from top of memory if possible */
453 if ((flags
& MEMF_PUBLIC
) && SysBase
->LibNode
.lib_Version
>= 36) {
454 flags
|= MEMF_REVERSE
;
457 D(WriteF("ELF: Attempt to allocate %N bytes of type %X8\n", size
, flags
));
458 mem
= AllocPageAligned(&size
, flags
);
460 D(WriteF("ELF: Failed to allocate %N bytes of type %X8\n", size
, flags
));
464 D(WriteF("ELF: Got memory at %X8, size %N\n", (IPTR
)mem
, size
));
466 ml
= (struct MemList
*)(mem
+ sizeof(struct MemChunk
));
467 ml
->ml_NumEntries
= 1;
468 ml
->ml_ME
[0].me_Addr
= (APTR
)mem
;
469 ml
->ml_ME
[0].me_Length
= size
;
471 /* Add to the KickMem list */
472 AddTail(&mlist
, (struct Node
*)ml
);
473 D(WriteF("ELF: Got memory at %X8, size %N\n", (IPTR
)(&ml
[1]), size
));
480 static AROS_UFH3(void, elfFree
,
481 AROS_UFHA(APTR
, addr
, A1
),
482 AROS_UFHA(ULONG
, size
, D0
),
483 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
487 /* If not page aligned, and the offset from the page boundary
488 * is the sizeof(MemChunk) + sizeof(MemList) then we can assume
489 * that it was a KickTag protected allocation
491 D(WriteF("ELF: Free memory at %X8, size %N\n", (IPTR
)addr
, size
));
492 addr
-= sizeof(struct MemList
);
493 Remove((struct Node
*)addr
);
494 addr
-= sizeof(struct MemChunk
);
495 size
+= sizeof(struct MemChunk
) + sizeof(struct MemList
);
496 D(WriteF("ELF: FREE memory at %X8, size %N\n", (IPTR
)addr
, size
));
497 FreePageAligned(addr
, size
);
503 * This routine is called from within libloadseg.a's ELF loader.
504 * In dos.library it's responsible for collecting debug information from the loaded file.
505 * Here it does nothing (FIXME ???)
507 void register_elf(BPTR file
, BPTR hunks
, struct elfheader
*eh
, struct sheader
*sh
, struct DosLibrary
*DOSBase
)
512 static BPTR
ROMLoad(BSTR bfilename
)
517 SIPTR funcarray
[] = {
523 filename
= ConvertBSTR(bfilename
);
527 WriteF("Loading '%S' into RAM...\n", bfilename
);
528 if ((gzf
= gzopen(filename
, "rb"))) {
529 gzbuffer(gzf
, 65536);
531 rom
= LoadSegment((BPTR
)gzf
, BNULL
, funcarray
, NULL
);
533 WriteF("'%S': Can't parse, error %N\n", bfilename
, IoErr());
538 WriteF("'%S': Can't open\n", bfilename
);
540 FreeString(filename
);
544 /* Patch "picasso96/<driver>.chip" -> "<driver>.chip" so that OpenLibrary() finds it */
545 static void RTGPatch(struct Resident
*r
, BPTR seg
)
547 BOOL patched
= FALSE
;
548 WORD len
= strlen(r
->rt_Name
);
549 const UBYTE
*name
= r
->rt_Name
+ len
- 5;
550 if (len
> 5 && (!stricmp(name
, ".card") || !stricmp(name
, ".chip"))) {
553 ULONG
*ptr
= BADDR(seglist
);
554 LONG len
= ptr
[-1] - sizeof(BPTR
);
555 UBYTE
*p
= (UBYTE
*)(ptr
+ 1);
557 if (len
> 16 && !strnicmp(p
, "libs:picasso96/", 15)) {
558 memmove(p
, p
+ 15, strlen(p
+ 15) + 1);
560 } else if (len
> 10 && !strnicmp(p
, "picasso96/", 10)) {
561 memmove(p
, p
+ 10, strlen(p
+ 10) + 1);
567 seglist
= *((BPTR
*)BADDR(seglist
));
571 WriteF("Library path patched\n");
574 #define RESLIST_CHUNK 100
575 #define LRF_NOPATCH (1 << 0) /* If set, don't patch the struct Resident */
577 static struct Resident
**LoadResident(BPTR seg
, struct Resident
**reslist
, ULONG
*resleft
, ULONG flags
)
579 ULONG
*ptr
= BADDR(seg
);
581 LONG len
= ptr
[-1] - sizeof(BPTR
);
583 res
= (UWORD
*)(ptr
+ 1);
584 while (len
>= offsetof(struct Resident
, rt_Init
) + sizeof(APTR
)) {
585 if (*res
== RTC_MATCHWORD
&& ((ULONG
*)(res
+ 1))[0] == (ULONG
)res
) {
586 struct Resident
*r
= (struct Resident
*)res
;
587 if (!(flags
& LRF_NOPATCH
)) {
588 /* Set RTF_COLDSTART if no initialization flags set */
589 if (!(r
->rt_Flags
& (RTF_COLDSTART
| RTF_SINGLETASK
| RTF_AFTERDOS
)))
590 r
->rt_Flags
|= RTF_COLDSTART
;
597 struct Resident
**resnew
;
598 resnew
= aosAllocMem(RESLIST_CHUNK
* sizeof(struct Resident
*), MEMF_CLEAR
, SysBase
);
602 *reslist
= (APTR
)((IPTR
)resnew
| RESLIST_NEXT
);
604 *resleft
= RESLIST_CHUNK
- 1;
606 D(WriteF("Resident structure found @%X8\n", r
));
617 static struct Resident
**LoadResidents(BPTR
*namearray
, struct Resident
**resnext
, ULONG
*resleft
)
620 SIPTR funcarray
[] = {
627 for (i
= 0; namearray
[i
]; i
++) {
630 BPTR seglist
= BNULL
;
634 bname
= namearray
[i
];
635 name
= ConvertBSTR(bname
);
637 handle
= Open(name
, MODE_OLDFILE
);
639 seglist
= LoadSegment(handle
, BNULL
, funcarray
, &stack
);
644 WriteF("Loaded '%S'\n", bname
);
645 for (seg
= seglist
; seg
!= BNULL
; seg
= *((BPTR
*)BADDR(seg
)))
646 resnext
= LoadResident(seg
, resnext
, resleft
, 0);
648 WriteF("Failed to load '%S', error %N\n", bname
, IoErr());
657 #define FAKEBASE 0x200
658 #define FAKEBASESIZE 558
659 #define COLDCAPTURE (FAKEBASE + FAKEBASESIZE + 16)
661 /* Theory of operation:
663 - create fake sysbase in low chip memory (We can't use original because it is not binary compatible with AROS one)
664 - set correct checksum and point ColdCapture to our routine (also in low chip)
665 - reset the system (autoconfig devices disappear, including most expansion RAM and ROM overlay disables chip RAM)
666 - original ROM code now disables ROM overlay and checks KS checksum and jumps to our ColdCapture routine
667 - above step is needed because in worst case ALL RAM disappear at reset and there
668 are also accelerators that reset the CPU completely when reset instruction is executed.
669 - now we have control again, autoconfig devices are still unconfigured but at least we have chip ram.
670 - jump to AROS ROM code entry point which detects romloader mode and automatically reserves RAM used by "ROM" code
671 - AROS ROM creates new proper execbase and copies ColdCapture
676 static UWORD
GetSysBaseChkSum(struct ExecBase
*sysbase
)
679 UWORD
*p
= (UWORD
*)&sysbase
->SoftVer
;
680 while (p
<= &sysbase
->ChkSum
)
685 static ULONG
mySumKickData(struct ExecBase
*sysbase
, BOOL output
)
690 if (sysbase
->KickTagPtr
) {
691 IPTR
*list
= sysbase
->KickTagPtr
;
694 chksum
+= (ULONG
)*list
;
697 WriteF("%X8 %X8\n", list
, *list
);
698 WriteF("CHK %X8\n", chksum
);
702 /* on amiga, if bit 31 is set then this points to another list of
703 * modules rather than pointing to a single module. bit 31 is
704 * inconvenient on architectures where code may be loaded above
705 * 2GB. on these platforms we assume aligned pointers and use bit
708 if(*list
& 0x80000000) { list
= (IPTR
*)(*list
& 0x7fffffff); continue; }
710 if(*list
& 0x1) { list
= (IPTR
*)(*list
& ~(IPTR
)0x1); continue; }
717 if (sysbase
->KickMemPtr
) {
718 struct MemList
*ml
= (struct MemList
*)sysbase
->KickMemPtr
;
721 ULONG
*p
= (ULONG
*)ml
;
722 for (i
= 0; i
< sizeof(struct MemList
) / sizeof(ULONG
); i
++)
727 WriteF("ML %X8 %X8\n", ml
, chksum
);
728 WriteF("NODE0 %X8 %X8\n", p
[0], p
[1]);
729 WriteF("NODE2 %X8 %X8\n", p
[2], p
[3]);
730 WriteF("ADDR %X8 %X8\n", ml
->ml_ME
[0].me_Un
.meu_Addr
, ml
->ml_ME
[0].me_Length
);
731 WriteF("DATA0 %X8 %X8\n", p
[6], p
[7]);
735 ml
= (struct MemList
*)ml
->ml_Node
.ln_Succ
;
739 if (isdata
&& !chksum
)
745 /* reset VBR and switch off MMU */
746 static void setcpu(void)
751 "move.w 296(%a0),%d1\n"
771 "not040: btst #2,%d1\n"
774 "lea zero(%pc),%a0\n"
784 /* This is needed because KS clears ColdCapture before calling it
785 * causing checksum mismatch in AROS exec check
787 void coldcapturecode(void)
790 ".long end - start\n"
793 "nop\n" /* Align to start + 4 */
794 ".long 0x46414b45\n" /* AROS_MAKE_ID('F','A','K','E') */
796 "move.w #0x440,0xdff180\n"
799 "move.l (%a0),0x7c.w\n" // restore NMI
802 "lea start(%pc),%a1\n"
803 "move.l %a1,42(%a0)\n" // ColdCapture
806 "move.l %d0,38(%a0)\n" // ChkBase
810 "chk1: add.w (%a0)+,%d1\n"
813 "move.w %d1,(%a0)\n" // ChkSum
814 "move.l start-4(%pc),%a0\n"
820 /* Official reboot code from HRM
821 * All CPUs have at least 1 word prefetch,
822 * jmp (a0) has been prefetched even if
823 * reset disables all memory
825 static void doreboot(void)
828 "lea 0x01000000,%a0\n"
829 "sub.l %a0@(-0x14),%a0\n"
830 "move.l %a0@(4),%a0\n"
832 ".balign 8\n" /* Workaround for E-UAE emulation bug */
838 APTR entry
, kicktags
;
839 struct TagItem
*kerneltags
;
841 static void supercode(void)
843 ULONG
*fakesys
, *coldcapture
, *coldcapturep
;
844 struct ExecBase
*sysbase
;
848 if ((SysBase
->AttnFlags
& 0xff) != 0)
851 fakesys
= (ULONG
*)FAKEBASE
;
852 coldcapture
= (ULONG
*)COLDCAPTURE
;
853 coldcapture
[-1] = (ULONG
)entry
;
854 coldcapturep
= (ULONG
*)coldcapturecode
;
855 len
= *coldcapturep
++;
856 memcpy (coldcapture
, coldcapturep
, len
);
858 *fakesys
++ = traps
[31]; // Level 7
859 *fakesys
++ = 0x4ef9 | (COLDCAPTURE
>> 16);
860 *fakesys
++ = (COLDCAPTURE
<< 16) | 0x4e75;
861 sysbase
= (struct ExecBase
*)fakesys
;
863 memset(sysbase
, 0, FAKEBASESIZE
);
864 /* Misuse DebugData as a kernel tag pointer,
867 sysbase
->DebugData
= kerneltags
;
870 sysbase
->LibNode
.lib_Node
.ln_Pred
= &sysbase
->LibNode
.lib_Node
;
871 sysbase
->LibNode
.lib_Node
.ln_Succ
= &sysbase
->LibNode
.lib_Node
;
873 /* Set up cold capture */
874 sysbase
->ColdCapture
= coldcapture
;
875 sysbase
->MaxLocMem
= 512 * 1024;
876 sysbase
->ChkBase
=~(IPTR
)sysbase
;
877 sysbase
->ChkSum
= GetSysBaseChkSum(sysbase
) ^ 0xffff;
879 /* Propogate the existing OS's Kick Data */
880 if (mlist
.lh_Head
->ln_Succ
) {
881 sysbase
->KickMemPtr
= (APTR
)mlist
.lh_Head
;
882 mlist
.lh_TailPred
->ln_Succ
= SysBase
->KickMemPtr
;
884 sysbase
->KickMemPtr
= (APTR
)SysBase
->KickMemPtr
;
887 sysbase
->KickTagPtr
= kicktags
;
888 if (SysBase
->KickTagPtr
) {
892 *p
= 0x80000000 | (ULONG
)SysBase
->KickTagPtr
;
895 sysbase
->KickTagPtr
= SysBase
->KickTagPtr
;
897 sysbase
->KickCheckSum
= (APTR
)mySumKickData(sysbase
, FALSE
);
899 traps
[1] = (IPTR
)sysbase
;
900 // TODO: add custom cacheclear, can't call CacheClearU() because it may not work
901 // anymore and KS 1.x does not even have it
905 void BootROM(BPTR romlist
, struct Resident
**reslist
, struct TagItem
*tags
)
909 entry
= BADDR(romlist
)+sizeof(ULONG
);
914 /* Debug testing code */
915 if (mlist
.lh_Head
->ln_Succ
) {
916 SysBase
->KickMemPtr
= (APTR
)mlist
.lh_Head
;
917 mlist
.lh_TailPred
->ln_Succ
= NULL
;
920 SysBase
->KickTagPtr
= kicktags
;
922 mySumKickData(SysBase
, TRUE
);
923 SysBase
->KickTagPtr
= 0;
924 SysBase
->KickMemPtr
= 0;
928 if ((GfxBase
= OpenLibrary("graphics.library", 0))) {
932 CloseLibrary(GfxBase
);
935 /* We're off in the weeds now. */
938 Supervisor((ULONG_FUNC
)supercode
);
941 #define KERNELTAGS_SIZE 10
942 #define CMDLINE_SIZE 512
944 static struct TagItem
*AllocKernelTags(UBYTE
*cmdline
)
946 struct TagItem
*tags
;
949 tags
= aosAllocMem(sizeof(struct TagItem
) * KERNELTAGS_SIZE
+ CMDLINE_SIZE
, MEMF_CLEAR
, SysBase
);
952 cmd
= (UBYTE
*)(tags
+ KERNELTAGS_SIZE
);
953 /* cmdline is a BCPL string! */
954 if (cmdline
&& cmdline
[0])
955 CopyMem(cmdline
+ 1, cmd
, cmdline
[0]);
957 strcpy(cmd
, DEFAULT_KERNEL_CMDLINE
);
958 tags
[0].ti_Tag
= KRN_CmdLine
;
959 tags
[0].ti_Data
= (IPTR
)cmd
;
960 tags
[1].ti_Tag
= TAG_DONE
;
964 __startup
static AROS_ENTRY(int, startup
,
965 AROS_UFHA(char *, argstr
, A0
),
966 AROS_UFHA(ULONG
, argsize
, D0
),
967 struct ExecBase
*, SysBase
)
971 /* See if we're already running on AROS.
973 if (OpenResource("kernel.resource"))
977 DOSBase
= (APTR
)OpenLibrary("dos.library", 0);
978 if (DOSBase
!= NULL
) {
980 BSTR name
= AROS_CONST_BSTR("aros.elf.gz");
981 enum { ARG_ROM
= 16, ARG_CMD
= 17, ARG_MODULES
= 0 };
982 /* It would be nice to use the '/M' switch, but that
983 * is not supported under the AOS BCPL RdArgs routine.
985 * So only 16 modules are supported
987 BSTR format
= AROS_CONST_BSTR(",,,,,,,,,,,,,,,,ROM/K,CMD/K");
988 /* Make sure the args are in .bss, not stack */
989 static ULONG args
[16 + 2 + 256] __attribute__((aligned(4))) = { };
991 WriteF("AROSBootstrap " ADATE
"\n");
994 RdArgs(format
, MKBADDR(args
), sizeof(args
)/sizeof(args
[0]));
996 WriteF("ROM: %S\n", args
[ARG_ROM
]);
997 WriteF("CMD: %S\n", args
[ARG_CMD
]);
998 WriteF("MOD: %S\n", args
[0]);
999 WriteF(" : %S\n", args
[1]);
1000 WriteF(" : %S\n", args
[2]);
1001 WriteF(" : %S\n", args
[3]);
1007 /* Load ROM image */
1008 if (args
[ARG_ROM
] == BNULL
)
1009 args
[ARG_ROM
] = name
;
1011 ROMSegList
= ROMLoad(args
[ARG_ROM
]);
1012 if (ROMSegList
!= BNULL
) {
1014 struct Resident
**ResidentList
;
1015 struct TagItem
*KernelTags
;
1016 WriteF("Successfully loaded ROM\n");
1018 struct Resident
**resnext
, *reshead
= NULL
;
1021 /* Only scan the 2nd section of the ROM segment */
1022 resnext
= LoadResident(*((BPTR
*)BADDR(ROMSegList
)), resnext
, &resleft
, LRF_NOPATCH
);
1023 resnext
= LoadResidents(&args
[ARG_MODULES
], resnext
, &resleft
);
1024 KernelTags
= AllocKernelTags(BADDR(args
[ARG_CMD
]));
1026 WriteF("Booting...\n");
1029 ResidentList
= (APTR
)((IPTR
)reshead
& ~RESLIST_NEXT
);
1030 BootROM(ROMSegList
, ResidentList
, KernelTags
);
1032 UnLoadSeg(ROMSegList
);
1034 WriteF("Can't load ROM ELF file %S\n", args
[ARG_ROM
]);
1037 WriteF("Can't parse arguments, error %N\n", IoErr());
1040 CloseLibrary((APTR
)DOSBase
);