void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) { kernel_entry_t kentry; char cmdline[COMMAND_LINE_SIZE]; unsigned long ft_addr = 0; memset(__bss_start, 0, _end - __bss_start); memset(&platform_ops, 0, sizeof(platform_ops)); memset(&dt_ops, 0, sizeof(dt_ops)); memset(&console_ops, 0, sizeof(console_ops)); if (platform_init(promptr, _dtb_start, _dtb_end)) exit(); if (console_ops.open && (console_ops.open() < 0)) exit(); if (platform_ops.fixups) platform_ops.fixups(); printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp); prep_kernel(a1, a2); /* If cmdline came from zimage wrapper or if we can edit the one * in the dt, print it out and edit it, if possible. */ if ((strlen(builtin_cmdline) > 0) || console_ops.edit_cmdline) { get_cmdline(cmdline, COMMAND_LINE_SIZE); printf("\n\rLinux/PowerPC load: %s", cmdline); if (console_ops.edit_cmdline) console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE); printf("\n\r"); set_cmdline(cmdline); } printf("Finalizing device tree..."); if (dt_ops.finalize) ft_addr = dt_ops.finalize(); if (ft_addr) printf(" flat tree at 0x%lx\n\r", ft_addr); else printf(" using OF tree (promptr=%p)\n\r", promptr); if (console_ops.close) console_ops.close(); kentry = (kernel_entry_t) vmlinux.addr; if (ft_addr) kentry(ft_addr, 0, NULL); else /* XXX initrd addr/size should be passed in properties */ kentry(initrd.addr, initrd.size, promptr); /* console closed so printf below may not work */ printf("Error: Linux kernel returned to zImage boot wrapper!\n\r"); exit(); }
// kernel loader void kloader(multiboot_info_t* mbi, unsigned long kernel_stack_bottom) { //call static constructors for(unsigned long* c(&_start_ctors); c < &_end_ctors; ++c) ((void (*) (void)) (*c)) (); //call kernel kentry(mbi, kernel_stack_bottom); //call static destructors for(unsigned long* d(&_start_dtors); d < &_end_dtors; ++d) ((void (*) (void)) (*d)) (); }
__attribute__((section(".text.relocate"))) void relocate() { uart_init(); uart_puts("rpi-uart-boot: copiyng itself to higher address\r\n"); printf("RAM_START %X\r\n", RAM_START); size_t kernel_size = &__end - &__start; uint8_t *new_addr = RAM_START ; printf("new_addr %X\r\nkernel_size %d=%X\r\n", new_addr, kernel_size, kernel_size); printf("=%X %X, =%X %X\r\n",&__start, *(&__start), new_addr, *new_addr); memcpy(new_addr, &__start, kernel_size); printf("=%X %X, =%X %X\r\n",&__start, *(&__start), new_addr, *new_addr); printf("end %x", &__end); printf("going to execute relocated code\r\n"); kentry_t kentry = (kentry_t)new_addr; kentry(); }