Added German translation
[AROS.git] / arch / all-unix / kernel / kernel_startup.c
blob6bd757fc8be922617e056c45f9ae9e6c7fa1f7db
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>
10 #include <sys/mman.h>
12 #include <inttypes.h>
13 #include <string.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"
23 #define D(x)
25 /* This macro is defined in both UNIX and AROS headers. Get rid of warnings. */
26 #undef __const
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)
33 #ifdef HOST_OS_linux
34 #define ARCH_31BIT MEMF_31BIT
35 #endif
36 #endif
37 #ifndef ARCH_31BIT
38 #define ARCH_31BIT 0
39 #endif
41 /* Global HostIFace is needed for krnPutC() to work before KernelBase is set up */
42 struct HostInterface *HostIFace;
44 THIS_PROGRAM_HANDLES_SYMBOLSET(STARTUP)
45 DEFINESET(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;
53 void *hostlib;
54 char *errstr;
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)
64 return -1;
66 while ((tag = LibNextTagItem(&tstate)))
68 switch (tag->ti_Tag)
70 case KRN_KernelLowest:
71 ranges[0] = (UWORD *)tag->ti_Data;
72 break;
74 case KRN_KernelHighest:
75 ranges[1] = (UWORD *)tag->ti_Data;
76 break;
78 case KRN_MMAPAddress:
79 mmap = (struct mb_mmap *)tag->ti_Data;
80 break;
82 case KRN_KernelBss:
83 __clear_bss((struct KernelBSS *)tag->ti_Data);
84 break;
86 case KRN_HostInterface:
87 hif = (struct HostInterface *)tag->ti_Data;
88 break;
92 /* Set globals only AFTER __clear_bss() */
93 BootMsg = msg;
94 HostIFace = hif;
96 /* If there's no proper HostIFace, we can't even say anything */
97 if (!HostIFace)
98 return -1;
100 if (strcmp(HostIFace->System, AROS_ARCHITECTURE))
101 return -1;
103 if (HostIFace->Version < HOSTINTERFACE_VERSION)
104 return -1;
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"
112 "\n"
113 "Kickstart start 0x%p, end 0x%p\n"
114 "Memory map address: 0x%p",
115 ranges[0], ranges[1], mmap);
116 return -1;
119 hostlib = HostIFace->hostlib_Open(LIBC_NAME, &errstr);
120 AROS_HOST_BARRIER
121 if (!hostlib)
123 krnPanic(NULL, "Failed to load %s\n%s", LIBC_NAME, errstr);
124 return -1;
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);
131 AROS_HOST_BARRIER
132 return -1;
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));
139 if (!mm_PageSize)
141 /* krnGetPageSize() panics itself */
142 HostIFace->hostlib_Close(hostlib, NULL);
143 AROS_HOST_BARRIER
144 return -1;
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))
159 SysBase = NULL;
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);
167 AROS_HOST_BARRIER
168 return -1;
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);
195 AROS_HOST_BARRIER
197 return 1;