Fixed gfx.hidd dependency name for PPC targets
[AROS.git] / arch / arm-native / ceboot / bootstrap.c
blob0710edecd7ba8b5a86fcfd99037ed1e588de9bbc
1 /*
2 Copyright © 2010-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Native AROS softkicker for Windows CE
6 Lang: english
7 */
9 #include <ctype.h>
10 #include <stdarg.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <windows.h>
16 #include <hardware/vbe.h>
17 #include <elfloader.h>
18 #include <runtime.h>
21 * These tricks prevent conflicts between Windows types and exec/types.h
22 * WARNING!!! After this WORD and BYTE become unsigned, and BOOL becomes 32-bit!
23 * Use with care!
25 #define __typedef_LONG
26 #define __typedef_WORD
27 #define __typedef_BYTE
28 #define __typedef_BOOL
30 typedef unsigned short UWORD;
31 typedef unsigned char UBYTE;
33 #include <aros/kernel.h>
35 #include "bootmem.h"
36 #include "bootstrap.h"
37 #include "elf_io.h"
38 #include "filesystem.h"
39 #include "hardware.h"
40 #include "winapi.h"
42 #define D(x) x
44 char *bootstrapdir;
45 char buf[BUFFER_SIZE];
47 static const char version[] = "$VER: CEBoot v1.0 (" ADATE ")";
49 static char *GetConfigArg(char *str, char *option)
51 size_t l = strlen(option);
53 /* First check option name */
54 if (strncasecmp(str, option, l))
55 return NULL;
57 /* Skip option name */
58 str += l;
60 /* First character must be space */
61 if (!isspace(*str++))
62 return NULL;
63 /* Skip the rest of spaces */
64 while(isspace(*str))
65 str++;
67 return str;
70 int main(int argc, char **argv)
72 char *name;
73 int i;
74 FILE *file;
75 unsigned long ro_size, rw_size, bss_size;
76 void *ro_addr, *rw_addr, *bss_addr;
77 kernel_entry_fun_t kernel_entry;
78 struct ELF_ModuleInfo *Debug_KickList;
79 unsigned long physbase;
80 void *phys_end;
81 ULONG_PTR boot_phys, bss_phys, vmode_phys, taglist_phys;
82 ULONG_PTR cmd_phys = 0;
83 struct vbe_mode *vmode;
84 struct TagItem *tag;
86 name = namepart(argv[0]);
87 i = name - argv[0];
88 bootstrapdir = malloc(i + 1);
89 if (!bootstrapdir)
91 DisplayError("Failed to locate home directory!");
92 return -1;
94 memcpy(bootstrapdir, argv[0], i);
95 bootstrapdir[i] = 0;
98 * Now prepare memory for boot information.
99 * Our bootinfo is allocated in a specific way because we need to know both virtual
100 * and physical addresses. All pointers inside it must be physical.
101 * This will be a single contiguous chunk, so we won't force the kernel to copy boot information
102 * once more.
104 boot_phys = InitBootMem();
105 if (!boot_phys)
107 DisplayError("Failed to initialize bootinfo storage");
108 return -1;
111 file = file_open("CEBoot.conf", "r");
112 if (!file)
114 DisplayError("Failed to load configuration file!");
115 return -1;
118 /* Parse the configuration file */
119 while (fgets(buf, sizeof(buf), file))
121 char *c = strchr(buf, '\r');
123 if (!c)
124 c = strchr(buf, '\n');
125 if (c)
126 *c = 0;
128 c = GetConfigArg(buf, "module");
129 if (c)
131 AddKernelFile(c);
132 continue;
135 c = GetConfigArg(buf, "logfile");
136 if (c)
138 i = SetLog(c);
139 if (i)
141 DisplayError("Failed to redirect debug output to %s", c);
142 return -1;
144 fprintf(stderr, "----\n"); /* Separation marker */
147 c = GetConfigArg(buf, "arguments");
148 if (c)
150 char *cmd_virt;
152 cmd_phys = bootmem_Phys;
153 cmd_virt = AllocBootMem(strlen(c) + 1);
155 strcpy(cmd_virt, c);
156 fprintf(stderr, "Got command line: %s\n", cmd_virt);
159 fclose(file);
161 if (!GetKernelSize(FirstELF, &ro_size, &rw_size, &bss_size))
162 return -1;
164 /* Page-align rw_size to assist furure memory protection */
165 rw_size = AROS_ROUNDUP2(rw_size, PAGE_SIZE);
167 /* Allocate the memory in a single chunk. Read-only region follows read-write. */
168 rw_addr = AllocPhysMem(rw_size + ro_size, PAGE_READWRITE, 0, 0, &physbase);
169 if (!rw_addr)
171 DisplayError("Failed to allocate %u bytes for the kickstart!", rw_size + ro_size);
172 return -1;
175 bss_phys = bootmem_Phys;
176 bss_addr = AllocBootMem(bss_size);
178 ro_addr = rw_addr + rw_size;
179 D(fprintf(stderr, "[Boot] Logical : Read-write %p, Read-only %p BSS %p\n", rw_addr, ro_addr, bss_addr));
180 D(fprintf(stderr, "[Boot] Physical: Read-write %p, Read-only %p BSS %p\n", (void *)physbase, (void *)physbase + rw_size, (void *)bss_phys));
183 * kernel_entry and Debug_KickList are returned as PHYSICAL POINTERS!!!
184 * TODO: Actually implement this, as well as ELF relocation based upon virtual addressing.
186 if (!LoadKernel(FirstELF, ro_addr, rw_addr, bss_addr, 4, &phys_end, &kernel_entry, &Debug_KickList))
187 return -1;
189 FreeKernelList();
190 D(fprintf(stderr, "[Boot] Physical: Entry %p, Debug info %p\n", kernel_entry, Debug_KickList));
192 /* Get framebuffer information */
193 vmode_phys = bootmem_Phys;
194 vmode = AllocBootMem(sizeof(struct vbe_mode));
196 if (GetFBInfo(vmode))
197 return -1;
199 /* Remember beginning of the taglist */
200 taglist_phys = bootmem_Phys;
202 AddTag(KRN_KernelLowest , physbase);
203 AddTag(KRN_KernelBase , physbase + rw_size);
204 AddTag(KRN_KernelHighest, (ULONG_PTR)phys_end);
205 AddTag(KRN_KernelBss , bss_phys);
206 AddTag(KRN_DebugInfo , (ULONG_PTR)Debug_KickList);
207 if (cmd_phys)
208 AddTag(KRN_CmdLine, cmd_phys);
210 AddTag(KRN_ProtAreaStart, boot_phys);
211 tag = AddTag(KRN_ProtAreaEnd, 0);
212 AddTag(TAG_DONE , 0);
214 /* Set the end of protected area */
215 tag->ti_Data = bootmem_Phys;
216 D(fprintf(stderr, "[Boot] Bootinfo physical %p - %p, taglist %p\n", (void *)boot_phys, (void *)bootmem_Phys, (void *)taglist_phys));
219 * Become a supervisor.
220 * SetKMode() returns original state, we use the second call to check result of the first one.
222 SetKMode(TRUE);
223 if (!SetKMode(TRUE))
225 DisplayError("Failed to enter supervisor mode");
226 return -1;
229 /* TODO: Write kick()
230 kick(kernel_entry, taglist_phys); */
231 DisplayError("Launching kickstart... Not implemented yet! :)");
233 return 0;