1 #include <aros/kernel.h>
2 #include <aros/multiboot.h>
3 #include <aros/symbolsets.h>
4 #include <exec/execbase.h>
5 #include <exec/resident.h>
6 #include <utility/tagitem.h>
7 #include <proto/arossupport.h>
8 #include <proto/exec.h>
15 #include "hostinterface.h"
16 #include "kernel_base.h"
17 #include "kernel_debug.h"
18 #include "kernel_globals.h"
19 #include "kernel_intern.h"
20 #include "kernel_romtags.h"
21 #include "kernel_unix.h"
25 /* This macro is defined in both UNIX and AROS headers. Get rid of warnings. */
29 * On 64 bit Linux bootloaded gives us RAM region below 2GB.
30 * On other 64-bit unices we have no control over it.
32 #if (__WORDSIZE == 64)
34 #define ARCH_31BIT MEMF_31BIT
41 /* Global HostIFace is needed for krnPutC() to work before KernelBase is set up */
42 struct HostInterface
*HostIFace
;
44 THIS_PROGRAM_HANDLES_SYMBOLSET(STARTUP
)
48 * Kickstart entry point. Note that our code area is already made read-only by the bootstrap.
50 int __startup
startup(struct TagItem
*msg
, ULONG magic
)
52 void* _stack
= AROS_GET_SP
;
55 unsigned int mm_PageSize
;
56 struct MemHeader
*bootmh
;
57 struct TagItem
*tag
, *tstate
= msg
;
58 struct HostInterface
*hif
= NULL
;
59 struct mb_mmap
*mmap
= NULL
;
60 UWORD
*ranges
[] = {NULL
, NULL
, (UWORD
*)-1};
62 /* This bails out if the user started us from within AROS command line, as common executable */
63 if (magic
!= AROS_BOOT_MAGIC
)
66 while ((tag
= LibNextTagItem(&tstate
)))
70 case KRN_KernelLowest
:
71 ranges
[0] = (UWORD
*)tag
->ti_Data
;
74 case KRN_KernelHighest
:
75 ranges
[1] = (UWORD
*)tag
->ti_Data
;
79 mmap
= (struct mb_mmap
*)tag
->ti_Data
;
83 __clear_bss((struct KernelBSS
*)tag
->ti_Data
);
86 case KRN_HostInterface
:
87 hif
= (struct HostInterface
*)tag
->ti_Data
;
92 /* Set globals only AFTER __clear_bss() */
96 /* If there's no proper HostIFace, we can't even say anything */
100 if (strcmp(HostIFace
->System
, AROS_ARCHITECTURE
))
103 if (HostIFace
->Version
< HOSTINTERFACE_VERSION
)
106 /* Host interface is okay. We have working krnPutC() and can talk now. */
107 D(nbug("[Kernel] Starting up...\n"));
109 if ((!ranges
[0]) || (!ranges
[1]) || (!mmap
))
111 krnPanic(NULL
, "Not enough information from the bootstrap\n"
113 "Kickstart start 0x%p, end 0x%p\n"
114 "Memory map address: 0x%p",
115 ranges
[0], ranges
[1], mmap
);
119 hostlib
= HostIFace
->hostlib_Open(LIBC_NAME
, &errstr
);
123 krnPanic(NULL
, "Failed to load %s\n%s", LIBC_NAME
, errstr
);
127 /* Here we can add some variant-specific things. Android and iOS ports use this. */
128 if (!set_call_libfuncs(SETNAME(STARTUP
), 1, 1, hostlib
))
130 HostIFace
->hostlib_Close(hostlib
, NULL
);
135 /* Now query memory page size. We need in order to get our memory manager functional. */
136 mm_PageSize
= krnGetPageSize(hostlib
);
137 D(nbug("[KRN] Memory page size is %u\n", mm_PageSize
));
141 /* krnGetPageSize() panics itself */
142 HostIFace
->hostlib_Close(hostlib
, NULL
);
147 /* We know that memory map has only one RAM element */
148 bootmh
= (struct MemHeader
*)(IPTR
)mmap
->addr
;
150 /* Prepare the first mem header */
151 D(nbug("[Kernel] preparing first mem header at 0x%p (%u bytes)\n", bootmh
, mmap
->len
));
152 krnCreateMemHeader("Normal RAM", 0, bootmh
, mmap
->len
, MEMF_CHIP
|MEMF_PUBLIC
|MEMF_LOCAL
|MEMF_KICK
|ARCH_31BIT
);
155 * SysBase pre-validation after a warm restart.
156 * This makes sure that it points to a valid accessible memory region.
158 if (((IPTR
)SysBase
< mmap
->addr
) || ((IPTR
)SysBase
+ sizeof(struct ExecBase
) > mmap
->addr
+ mmap
->len
))
161 /* Create SysBase. After this we can use basic exec services, like memory allocation, lists, etc */
162 D(nbug("[Kernel] calling krnPrepareExecBase(), mh_First = %p\n", bootmh
->mh_First
));
163 if (!krnPrepareExecBase(ranges
, bootmh
, msg
))
165 /* Hosted krnPanic() returns, allowing us to drop back into bootstrap */
166 HostIFace
->hostlib_Close(hostlib
, NULL
);
171 D(nbug("[Kernel] SysBase=%p, mh_First=%p\n", SysBase
, bootmh
->mh_First
));
174 * ROM memory header. This special memory header covers all ROM code and data sections
175 * so that TypeOfMem() will not return 0 for addresses pointing into the kernel.
177 krnCreateROMHeader("Kickstart ROM", ranges
[0], ranges
[1]);
180 * Stack memory header. This special memory header covers a little part of the programs
181 * stack so that TypeOfMem() will not return 0 for addresses pointing into the stack
182 * during initialization.
184 krnCreateROMHeader("Boot stack", _stack
- AROS_STACKSIZE
, _stack
);
186 /* The following is a typical AROS bootup sequence */
187 InitCode(RTF_SINGLETASK
, 0); /* Initialize early modules. This includes hostlib.resource. */
188 core_Start(hostlib
); /* Got hostlib.resource. Initialize our interrupt mechanism. */
189 InitCode(RTF_COLDSTART
, 0); /* Boot! */
191 /* If we returned here, something went wrong, and dos.library failed to take over */
192 krnPanic(getKernelBase(), "Failed to start up the system");
194 HostIFace
->hostlib_Close(hostlib
, NULL
);