1 #include <aros/asmcall.h>
2 #include <aros/kernel.h>
3 #include <aros/symbolsets.h>
4 #include <exec/resident.h>
5 #include <proto/arossupport.h>
6 #include <proto/exec.h>
12 #include LC_LIBDEFS_FILE
14 #include <kernel_debug.h>
15 #include <kernel_memory.h>
17 /* We have own bug(), so don't use aros/debug.h to avoid conflicts */
20 static const UBYTE version
[];
21 extern const char LIBEND
;
23 AROS_UFP3S(struct KernelBase
*, Kernel_Init
,
24 AROS_UFPA(ULONG
, dummy
, D0
),
25 AROS_UFPA(BPTR
, segList
, A0
),
26 AROS_UFPA(struct ExecBase
*, sysBase
, A6
));
28 const struct Resident Kernel_resident
=
31 (struct Resident
*)&Kernel_resident
,
42 static const UBYTE version
[] = VERSION_STRING AROS_ARCHITECTURE
;
45 /* On m68k .data section doesn't exist */
48 #define __data __attribute__((section(".data")))
52 * Some globals we can't live without.
53 * IMPORTANT: BootMsg should survive warm restarts, this is why it's placed in .data.
55 __data
struct TagItem
*BootMsg
;
56 struct KernelBase
*KernelBase
;
58 void __clear_bss(const struct KernelBSS
*bss
)
62 bzero((void*)bss
->addr
, bss
->len
);
67 extern const APTR
GM_UNIQUENAME(FuncTable
)[];
69 THIS_PROGRAM_HANDLES_SYMBOLSETS
73 * Init routine is intentionally written by hands.
74 * It can use kernel's own memory allocator (if implemented) for KernelBase creation.
75 * This allows not to rely on working exec's memory management before kernel.resource
76 * is set up. This can simplify exec.library code on MMU-aware systems.
77 * exec.library catches our AddResource() and sets up its pooled memory manager.
80 AROS_UFH3S(struct KernelBase
*, Kernel_Init
,
81 AROS_UFHA(ULONG
, dummy
, D0
),
82 AROS_UFHA(BPTR
, segList
, A0
),
83 AROS_UFHA(struct ExecBase
*, SysBase
, A6
)
88 int vecsize
= FUNCTIONS_COUNT
* LIB_VECTSIZE
;
92 D(bug("[KRN] Kernel_Init()\n"));
94 vecsize
= ((vecsize
- 1) / sizeof(IPTR
) + 1) * sizeof(IPTR
);
97 * Allocate memory with RW access in user mode
98 * NOTE: The current code suggests that krnAllocMem() clears the allocated memory.
99 * Take care about this when implementing own allocator.
101 mem
= krnAllocMem(vecsize
+ sizeof(struct KernelBase
), MAP_Readable
|MAP_Writable
);
105 /* We set our global KernelBase here */
106 KernelBase
= mem
+ vecsize
;
108 KernelBase
->kb_Node
.ln_Type
= NT_RESOURCE
;
109 KernelBase
->kb_Node
.ln_Pri
= RESIDENTPRI
;
110 KernelBase
->kb_Node
.ln_Name
= MOD_NAME_STRING
;
112 MakeFunctions(KernelBase
, GM_UNIQUENAME(FuncTable
), NULL
);
114 D(bug("[KRN] KernelBase 0x%p\n", KernelBase
));
116 for (i
=0; i
< EXCEPTIONS_COUNT
; i
++)
117 NEWLIST(&KernelBase
->kb_Exceptions
[i
]);
119 for (i
=0; i
< IRQ_COUNT
; i
++)
120 NEWLIST(&KernelBase
->kb_Interrupts
[i
]);
122 /* Call platform-specific init code */
123 if (!set_call_libfuncs(SETNAME(INITLIB
), 1, 1, KernelBase
))
126 /* Everything is ok, add our resource */
127 AddResource(KernelBase
);
130 * exec.library catches our AddResource() and sets up its memory management.
131 * Before AddResource() kernel.resource must be fully functional and be able to
132 * report memory page size and perform page allocations.
133 * Here we can already safely call CreatePool() etc. If needed, a second symbol
134 * set can be added here. However, it's much more perspective to use a slab allocator
135 * being developed by Michal Schulz to handle kernel object allocations.
138 D(bug("[KRN] Kernel_Init() done\n"));