2 Copyright © 2010-2011, The AROS Development Team. All rights reserved.
5 Desc: Native AROS softkicker for Windows CE
16 #include <hardware/vbe.h>
17 #include <elfloader.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!
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>
36 #include "bootstrap.h"
38 #include "filesystem.h"
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
))
57 /* Skip option name */
60 /* First character must be space */
63 /* Skip the rest of spaces */
70 int main(int argc
, char **argv
)
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
;
81 ULONG_PTR boot_phys
, bss_phys
, vmode_phys
, taglist_phys
;
82 ULONG_PTR cmd_phys
= 0;
83 struct vbe_mode
*vmode
;
86 name
= namepart(argv
[0]);
88 bootstrapdir
= malloc(i
+ 1);
91 DisplayError("Failed to locate home directory!");
94 memcpy(bootstrapdir
, argv
[0], i
);
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
104 boot_phys
= InitBootMem();
107 DisplayError("Failed to initialize bootinfo storage");
111 file
= file_open("CEBoot.conf", "r");
114 DisplayError("Failed to load configuration file!");
118 /* Parse the configuration file */
119 while (fgets(buf
, sizeof(buf
), file
))
121 char *c
= strchr(buf
, '\r');
124 c
= strchr(buf
, '\n');
128 c
= GetConfigArg(buf
, "module");
135 c
= GetConfigArg(buf
, "logfile");
141 DisplayError("Failed to redirect debug output to %s", c
);
144 fprintf(stderr
, "----\n"); /* Separation marker */
147 c
= GetConfigArg(buf
, "arguments");
152 cmd_phys
= bootmem_Phys
;
153 cmd_virt
= AllocBootMem(strlen(c
) + 1);
156 fprintf(stderr
, "Got command line: %s\n", cmd_virt
);
161 if (!GetKernelSize(FirstELF
, &ro_size
, &rw_size
, &bss_size
))
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
);
171 DisplayError("Failed to allocate %u bytes for the kickstart!", rw_size
+ ro_size
);
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
))
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
))
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
);
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.
225 DisplayError("Failed to enter supervisor mode");
229 /* TODO: Write kick()
230 kick(kernel_entry, taglist_phys); */
231 DisplayError("Launching kickstart... Not implemented yet! :)");