2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
11 #include <utility/tagitem.h>
12 #include <aros/macros.h>
17 #include "serialdebug.h"
21 asm(" .section .aros.startup \n"
22 " .globl bootstrap \n"
23 " .type bootstrap,%function \n"
25 " movw r0,#:lower16:tmp_stack_ptr\n"
26 " movt r0,#:upper16:tmp_stack_ptr\n"
31 static __used
unsigned char __stack
[BOOT_STACK_SIZE
];
32 static __used
void * tmp_stack_ptr
= &__stack
[BOOT_STACK_SIZE
-16];
34 static struct TagItem tags
[128];
35 static struct TagItem
*tag
= &tags
[0];
36 static unsigned long mem_upper
;
37 static void *pkg_image
;
38 static uint32_t pkg_size
;
40 static void parse_atags(struct tag
*tags
)
44 kprintf("[BOOT] Parsing ATAGS\n");
48 kprintf("[BOOT] %08x: ", t
->hdr
.tag
, t
->hdr
.size
);
52 kprintf("Memory (%08x-%08x)\n", t
->u
.mem
.start
, t
->u
.mem
.size
+ t
->u
.mem
.start
- 1);
53 tag
->ti_Tag
= KRN_MEMLower
;
54 tag
->ti_Data
= t
->u
.mem
.start
;
56 tag
->ti_Tag
= KRN_MEMUpper
;
57 tag
->ti_Data
= t
->u
.mem
.start
+ t
->u
.mem
.size
;
60 mem_upper
= t
->u
.mem
.start
+ t
->u
.mem
.size
;
65 char *cmdline
= malloc(strlen(t
->u
.cmdline
.cmdline
) + 1);
66 strcpy(cmdline
, t
->u
.cmdline
.cmdline
);
67 kprintf("CMDLine: \"%s\"\n", cmdline
);
69 tag
->ti_Tag
= KRN_CmdLine
;
70 tag
->ti_Data
= (intptr_t)cmdline
;
75 kprintf("RAMDISK: (%08x-%08x)\n", t
->u
.initrd
.start
, t
->u
.initrd
.size
+ t
->u
.initrd
.start
- 1);
76 pkg_image
= (void *)t
->u
.initrd
.start
;
77 pkg_size
= t
->u
.initrd
.size
;
86 void boot(uintptr_t dummy
, uintptr_t arch
, struct tag
* atags
)
89 void (*entry
)(struct TagItem
*tags
);
91 /* Enable NEON and VFP */
92 asm volatile ("mrc p15, 0, %0, c1, c0, 2":"=r"(tmp
));
95 asm volatile ("mcr p15, 0, %0, c1, c0, 2"::"r"(tmp
));
97 fmxr(cr8
, fmrx(cr8
) | 1 << 30);
99 kprintf("[BOOT] AROS for EfikaMX bootstrap\n");
101 asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r"(tmp
));
102 kprintf("[BOOT] control register %08x\n", tmp
);
104 asm volatile ("mcr p15, 0, %0, c1, c0, 0"::"r"(tmp
));
106 asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r"(tmp
));
107 kprintf("[BOOT] control register %08x\n", tmp
);
109 tag
->ti_Tag
= KRN_BootLoader
;
110 tag
->ti_Data
= (IPTR
)"Bootstrap/EfikaMX ARM";
115 kprintf("[BOOT] Bootstrap @ %08x-%08x\n", &__bootstrap_start
, &__bootstrap_end
);
116 kprintf("[BOOT] Topmost address for kernel: %p\n", mem_upper
);
120 mem_upper
= mem_upper
& ~4095;
122 unsigned long kernel_phys
= mem_upper
;
123 unsigned long kernel_virt
= kernel_phys
;
125 unsigned long total_size_ro
, total_size_rw
;
126 uint32_t size_ro
, size_rw
;
128 /* Calculate total size of kernel and modules */
130 getElfSize(&_binary_kernel_bin_start
, &size_rw
, &size_ro
);
132 total_size_ro
= size_ro
= (size_ro
+ 4095) & ~4095;
133 total_size_rw
= size_rw
= (size_rw
+ 4095) & ~4095;
135 if (pkg_image
&& pkg_size
)
137 uint8_t *base
= pkg_image
;
139 if (base
[0] == 0x7f && base
[1] == 'E' && base
[2] == 'L' && base
[3] == 'F')
141 kprintf("[BOOT] Kernel image is ELF file\n");
143 getElfSize(base
, &size_rw
, &size_ro
);
145 total_size_ro
+= (size_ro
+ 4095) & ~4095;
146 total_size_rw
+= (size_rw
+ 4095) & ~4095;
148 else if (base
[0] == 'P' && base
[1] == 'K' && base
[2] == 'G' && base
[3] == 0x01)
150 kprintf("[BOOT] Kernel image is a package:\n");
152 uint8_t *file
= base
+4;
153 uint32_t total_length
= AROS_BE2LONG(*(uint32_t*)file
); /* Total length of the module */
154 const uint8_t *file_end
= base
+total_length
;
157 kprintf("[BOOT] Package size: %dKB\n", total_length
>> 10);
161 while(file
< file_end
)
163 const char *filename
= remove_path(file
+4);
165 /* get text length */
166 len
= AROS_BE2LONG(*(uint32_t*)file
);
167 /* display the file name */
168 kprintf("[BOOT] %s ", filename
);
172 len
= AROS_BE2LONG(*(uint32_t *)file
);
176 getElfSize(file
, &size_rw
, &size_ro
);
178 total_size_ro
+= (size_ro
+ 4095) & ~4095;
179 total_size_rw
+= (size_rw
+ 4095) & ~4095;
181 /* go to the next file */
187 kernel_phys
= mem_upper
- total_size_ro
- total_size_rw
;
188 kernel_virt
= kernel_phys
;
190 kprintf("[BOOT] Physical address of kernel: %p\n", kernel_phys
);
191 kprintf("[BOOT] Virtual address of kernel: %p\n", kernel_virt
);
193 entry
= (void (*)(struct TagItem
))kernel_virt
;
195 initAllocator(kernel_phys
, kernel_phys
+ total_size_ro
, kernel_virt
- kernel_phys
);
197 tag
->ti_Tag
= KRN_KernelLowest
;
198 tag
->ti_Data
= kernel_phys
;
201 tag
->ti_Tag
= KRN_KernelHighest
;
202 tag
->ti_Data
= kernel_phys
+ ((total_size_ro
+ 4095) & ~4095) + ((total_size_rw
+ 4095) & ~4095);
205 loadElf(&_binary_kernel_bin_start
);
207 if (pkg_image
&& pkg_size
)
209 uint8_t *base
= pkg_image
;
211 if (base
[0] == 0x7f && base
[1] == 'E' && base
[2] == 'L' && base
[3] == 'F')
213 kprintf("[BOOT] Kernel image is ELF file\n");
215 getElfSize(base
, &size_rw
, &size_ro
);
217 total_size_ro
+= (size_ro
+ 4095) & ~4095;
218 total_size_rw
+= (size_rw
+ 4095) & ~4095;
220 else if (base
[0] == 'P' && base
[1] == 'K' && base
[2] == 'G' && base
[3] == 0x01)
222 kprintf("[BOOT] Kernel image is a package:\n");
224 uint8_t *file
= base
+4;
225 uint32_t total_length
= AROS_BE2LONG(*(uint32_t*)file
); /* Total length of the module */
226 const uint8_t *file_end
= base
+total_length
;
229 kprintf("[BOOT] Package size: %dKB\n", total_length
>> 10);
233 while(file
< file_end
)
235 const char *filename
= remove_path(file
+4);
237 /* get text length */
238 len
= AROS_BE2LONG(*(uint32_t*)file
);
239 /* display the file name */
240 kprintf("[BOOT] %s ", filename
);
244 len
= AROS_BE2LONG(*(uint32_t *)file
);
250 total_size_ro
+= (size_ro
+ 4095) & ~4095;
251 total_size_rw
+= (size_rw
+ 4095) & ~4095;
253 /* go to the next file */
259 arm_flush_cache(kernel_phys
, total_size_ro
+ total_size_rw
);
261 tag
->ti_Tag
= KRN_KernelBss
;
262 tag
->ti_Data
= (IPTR
)tracker
;
266 tag
->ti_Tag
= TAG_DONE
;
269 kprintf("[BOOT] Kernel taglist contains %d entries\n", ((intptr_t)tag
- (intptr_t)tags
)/sizeof(struct TagItem
));
270 kprintf("[BOOT] Bootstrap wasted %d bytes of memory for kernels use\n", mem_used() );
272 kprintf("[BOOT] Heading over to AROS kernel @ %08x\n", entry
);
275 kprintf("[BOOT] Back? Something wrong happened...\n");