diff options
Diffstat (limited to 'arch/powerpc/boot/main.c')
-rw-r--r-- | arch/powerpc/boot/main.c | 57 |
1 files changed, 28 insertions, 29 deletions
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index d719bb9333d1..6f6b50d238b6 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c | |||
@@ -27,6 +27,8 @@ extern char _vmlinux_start[]; | |||
27 | extern char _vmlinux_end[]; | 27 | extern char _vmlinux_end[]; |
28 | extern char _initrd_start[]; | 28 | extern char _initrd_start[]; |
29 | extern char _initrd_end[]; | 29 | extern char _initrd_end[]; |
30 | extern char _dtb_start[]; | ||
31 | extern char _dtb_end[]; | ||
30 | 32 | ||
31 | struct addr_range { | 33 | struct addr_range { |
32 | unsigned long addr; | 34 | unsigned long addr; |
@@ -167,7 +169,7 @@ static int is_elf32(void *hdr) | |||
167 | return 1; | 169 | return 1; |
168 | } | 170 | } |
169 | 171 | ||
170 | static void prep_kernel(unsigned long *a1, unsigned long *a2) | 172 | static void prep_kernel(unsigned long a1, unsigned long a2) |
171 | { | 173 | { |
172 | int len; | 174 | int len; |
173 | 175 | ||
@@ -203,11 +205,14 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2) | |||
203 | } | 205 | } |
204 | 206 | ||
205 | /* | 207 | /* |
206 | * Now we try to alloc memory for the initrd (and copy it there) | 208 | * Now find the initrd |
209 | * | ||
210 | * First see if we have an image attached to us. If so | ||
211 | * allocate memory for it and copy it there. | ||
207 | */ | 212 | */ |
208 | initrd.size = (unsigned long)(_initrd_end - _initrd_start); | 213 | initrd.size = (unsigned long)(_initrd_end - _initrd_start); |
209 | initrd.memsize = initrd.size; | 214 | initrd.memsize = initrd.size; |
210 | if ( initrd.size > 0 ) { | 215 | if (initrd.size > 0) { |
211 | printf("Allocating 0x%lx bytes for initrd ...\n\r", | 216 | printf("Allocating 0x%lx bytes for initrd ...\n\r", |
212 | initrd.size); | 217 | initrd.size); |
213 | initrd.addr = (unsigned long)malloc((u32)initrd.size); | 218 | initrd.addr = (unsigned long)malloc((u32)initrd.size); |
@@ -216,8 +221,6 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2) | |||
216 | "ramdisk !\n\r"); | 221 | "ramdisk !\n\r"); |
217 | exit(); | 222 | exit(); |
218 | } | 223 | } |
219 | *a1 = initrd.addr; | ||
220 | *a2 = initrd.size; | ||
221 | printf("initial ramdisk moving 0x%lx <- 0x%lx " | 224 | printf("initial ramdisk moving 0x%lx <- 0x%lx " |
222 | "(0x%lx bytes)\n\r", initrd.addr, | 225 | "(0x%lx bytes)\n\r", initrd.addr, |
223 | (unsigned long)_initrd_start, initrd.size); | 226 | (unsigned long)_initrd_start, initrd.size); |
@@ -225,6 +228,12 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2) | |||
225 | initrd.size); | 228 | initrd.size); |
226 | printf("initrd head: 0x%lx\n\r", | 229 | printf("initrd head: 0x%lx\n\r", |
227 | *((unsigned long *)initrd.addr)); | 230 | *((unsigned long *)initrd.addr)); |
231 | } else if (a2 != 0) { | ||
232 | /* Otherwise, see if yaboot or another loader gave us an initrd */ | ||
233 | initrd.addr = a1; | ||
234 | initrd.memsize = initrd.size = a2; | ||
235 | printf("Using loader supplied initrd at 0x%lx (0x%lx bytes)\n\r", | ||
236 | initrd.addr, initrd.size); | ||
228 | } | 237 | } |
229 | 238 | ||
230 | /* Eventually gunzip the kernel */ | 239 | /* Eventually gunzip the kernel */ |
@@ -250,10 +259,6 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2) | |||
250 | flush_cache((void *)vmlinux.addr, vmlinux.size); | 259 | flush_cache((void *)vmlinux.addr, vmlinux.size); |
251 | } | 260 | } |
252 | 261 | ||
253 | void __attribute__ ((weak)) ft_init(void *dt_blob) | ||
254 | { | ||
255 | } | ||
256 | |||
257 | /* A buffer that may be edited by tools operating on a zImage binary so as to | 262 | /* A buffer that may be edited by tools operating on a zImage binary so as to |
258 | * edit the command line passed to vmlinux (by setting /chosen/bootargs). | 263 | * edit the command line passed to vmlinux (by setting /chosen/bootargs). |
259 | * The buffer is put in it's own section so that tools may locate it easier. | 264 | * The buffer is put in it's own section so that tools may locate it easier. |
@@ -285,36 +290,22 @@ static void set_cmdline(char *buf) | |||
285 | setprop(devp, "bootargs", buf, strlen(buf) + 1); | 290 | setprop(devp, "bootargs", buf, strlen(buf) + 1); |
286 | } | 291 | } |
287 | 292 | ||
288 | /* Section where ft can be tacked on after zImage is built */ | ||
289 | union blobspace { | ||
290 | struct boot_param_header hdr; | ||
291 | char space[8*1024]; | ||
292 | } dt_blob __attribute__((__section__("__builtin_ft"))); | ||
293 | |||
294 | struct platform_ops platform_ops; | 293 | struct platform_ops platform_ops; |
295 | struct dt_ops dt_ops; | 294 | struct dt_ops dt_ops; |
296 | struct console_ops console_ops; | 295 | struct console_ops console_ops; |
297 | 296 | ||
298 | void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) | 297 | void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) |
299 | { | 298 | { |
300 | int have_dt = 0; | ||
301 | kernel_entry_t kentry; | 299 | kernel_entry_t kentry; |
302 | char cmdline[COMMAND_LINE_SIZE]; | 300 | char cmdline[COMMAND_LINE_SIZE]; |
301 | unsigned long ft_addr = 0; | ||
303 | 302 | ||
304 | memset(__bss_start, 0, _end - __bss_start); | 303 | memset(__bss_start, 0, _end - __bss_start); |
305 | memset(&platform_ops, 0, sizeof(platform_ops)); | 304 | memset(&platform_ops, 0, sizeof(platform_ops)); |
306 | memset(&dt_ops, 0, sizeof(dt_ops)); | 305 | memset(&dt_ops, 0, sizeof(dt_ops)); |
307 | memset(&console_ops, 0, sizeof(console_ops)); | 306 | memset(&console_ops, 0, sizeof(console_ops)); |
308 | 307 | ||
309 | /* Override the dt_ops and device tree if there was an flat dev | 308 | if (platform_init(promptr, _dtb_start, _dtb_end)) |
310 | * tree attached to the zImage. | ||
311 | */ | ||
312 | if (dt_blob.hdr.magic == OF_DT_HEADER) { | ||
313 | have_dt = 1; | ||
314 | ft_init(&dt_blob); | ||
315 | } | ||
316 | |||
317 | if (platform_init(promptr)) | ||
318 | exit(); | 309 | exit(); |
319 | if (console_ops.open && (console_ops.open() < 0)) | 310 | if (console_ops.open && (console_ops.open() < 0)) |
320 | exit(); | 311 | exit(); |
@@ -324,7 +315,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) | |||
324 | printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", | 315 | printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", |
325 | _start, sp); | 316 | _start, sp); |
326 | 317 | ||
327 | prep_kernel(&a1, &a2); | 318 | prep_kernel(a1, a2); |
328 | 319 | ||
329 | /* If cmdline came from zimage wrapper or if we can edit the one | 320 | /* If cmdline came from zimage wrapper or if we can edit the one |
330 | * in the dt, print it out and edit it, if possible. | 321 | * in the dt, print it out and edit it, if possible. |
@@ -338,15 +329,23 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) | |||
338 | set_cmdline(cmdline); | 329 | set_cmdline(cmdline); |
339 | } | 330 | } |
340 | 331 | ||
332 | printf("Finalizing device tree..."); | ||
333 | if (dt_ops.finalize) | ||
334 | ft_addr = dt_ops.finalize(); | ||
335 | if (ft_addr) | ||
336 | printf(" flat tree at 0x%lx\n\r", ft_addr); | ||
337 | else | ||
338 | printf(" using OF tree (promptr=%p)\n\r", promptr); | ||
339 | |||
341 | if (console_ops.close) | 340 | if (console_ops.close) |
342 | console_ops.close(); | 341 | console_ops.close(); |
343 | 342 | ||
344 | kentry = (kernel_entry_t) vmlinux.addr; | 343 | kentry = (kernel_entry_t) vmlinux.addr; |
345 | if (have_dt) | 344 | if (ft_addr) |
346 | kentry(dt_ops.ft_addr(), 0, NULL); | 345 | kentry(ft_addr, 0, NULL); |
347 | else | 346 | else |
348 | /* XXX initrd addr/size should be passed in properties */ | 347 | /* XXX initrd addr/size should be passed in properties */ |
349 | kentry(a1, a2, promptr); | 348 | kentry(initrd.addr, initrd.size, promptr); |
350 | 349 | ||
351 | /* console closed so printf below may not work */ | 350 | /* console closed so printf below may not work */ |
352 | printf("Error: Linux kernel returned to zImage boot wrapper!\n\r"); | 351 | printf("Error: Linux kernel returned to zImage boot wrapper!\n\r"); |