aboutsummaryrefslogtreecommitdiff
path: root/core/init.c
diff options
context:
space:
mode:
authorStewart Smith <stewart@linux.vnet.ibm.com>2015-05-06 14:00:47 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-05-07 17:54:17 +1000
commit3a398a21ef51bb27d74bf0205c0e682b227000a5 (patch)
tree6e1f3f6b9a402a4d719e9f9f5bf33711c319c954 /core/init.c
parent909432e62a5616725fe0be97f3e8c858ff758efd (diff)
downloadskiboot-3a398a21ef51bb27d74bf0205c0e682b227000a5.zip
skiboot-3a398a21ef51bb27d74bf0205c0e682b227000a5.tar.gz
skiboot-3a398a21ef51bb27d74bf0205c0e682b227000a5.tar.bz2
Start preload of kernel and initramfs early in boot
This means we will load kernel and initramfs LIDs from FSP/flash as we init PCI, hopefully reducing boot time. Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com> Reviewed-by: Joel Stanley <joel@jms.id.au>
Diffstat (limited to 'core/init.c')
-rw-r--r--core/init.c80
1 files changed, 50 insertions, 30 deletions
diff --git a/core/init.c b/core/init.c
index 445272a..108fc0d 100644
--- a/core/init.c
+++ b/core/init.c
@@ -284,47 +284,72 @@ extern char __builtin_kernel_start[];
extern char __builtin_kernel_end[];
extern uint64_t boot_offset;
-static bool load_kernel(void)
+static size_t kernel_size;
+static size_t initramfs_size;
+
+static bool start_preload_kernel(void)
{
- struct elf_hdr *kh;
- size_t ksize;
int loaded;
- prlog(PR_NOTICE, "INIT: Loading kernel\n");
-
/* Try to load an external kernel payload through the platform hooks */
- ksize = KERNEL_LOAD_SIZE;
+ kernel_size = KERNEL_LOAD_SIZE;
loaded = start_preload_resource(RESOURCE_ID_KERNEL,
RESOURCE_SUBID_NONE,
KERNEL_LOAD_BASE,
- &ksize);
- if (loaded == OPAL_SUCCESS)
- loaded = wait_for_resource_loaded(RESOURCE_ID_KERNEL,
- RESOURCE_SUBID_NONE);
+ &kernel_size);
+ if (loaded != OPAL_SUCCESS) {
+ printf("INIT: platform start load kernel failed\n");
+ kernel_size = 0;
+ return false;
+ }
+ initramfs_size = INITRAMFS_LOAD_SIZE;
+ loaded = start_preload_resource(RESOURCE_ID_INITRAMFS,
+ RESOURCE_SUBID_NONE,
+ INITRAMFS_LOAD_BASE, &initramfs_size);
if (loaded != OPAL_SUCCESS) {
- printf("INIT: platform kernel load failed\n");
- ksize = 0;
+ printf("INIT: platform start load initramfs failed\n");
+ initramfs_size = 0;
+ return false;
+ }
+
+ return true;
+}
+
+static bool load_kernel(void)
+{
+ struct elf_hdr *kh;
+ int loaded;
+
+ prlog(PR_NOTICE, "INIT: Loading kernel\n");
+
+ loaded = wait_for_resource_loaded(RESOURCE_ID_KERNEL,
+ RESOURCE_SUBID_NONE);
+
+ if (loaded != OPAL_SUCCESS) {
+ printf("INIT: platform wait for kernel load failed\n");
+ kernel_size = 0;
}
/* Try embedded kernel payload */
- if (!ksize) {
- ksize = __builtin_kernel_end - __builtin_kernel_start;
- if (ksize) {
+ if (!kernel_size) {
+ kernel_size = __builtin_kernel_end - __builtin_kernel_start;
+ if (kernel_size) {
/* Move the built-in kernel up */
uint64_t builtin_base =
((uint64_t)__builtin_kernel_start) -
SKIBOOT_BASE + boot_offset;
printf("Using built-in kernel\n");
- memmove(KERNEL_LOAD_BASE, (void*)builtin_base, ksize);
+ memmove(KERNEL_LOAD_BASE, (void*)builtin_base,
+ kernel_size);
}
}
- if (!ksize)
+ if (!kernel_size)
printf("Assuming kernel at %p\n", KERNEL_LOAD_BASE);
printf("INIT: Kernel loaded, size: %zu bytes (0 = unknown preload)\n",
- ksize);
+ kernel_size);
kh = (struct elf_hdr *)KERNEL_LOAD_BASE;
if (kh->ei_class == ELF_CLASS_64)
@@ -338,27 +363,20 @@ static bool load_kernel(void)
static void load_initramfs(void)
{
- size_t size;
int loaded;
- size = INITRAMFS_LOAD_SIZE;
- loaded = start_preload_resource(RESOURCE_ID_INITRAMFS,
- RESOURCE_SUBID_NONE,
- INITRAMFS_LOAD_BASE, &size);
-
- if (loaded == OPAL_SUCCESS)
- loaded = wait_for_resource_loaded(RESOURCE_ID_INITRAMFS,
- RESOURCE_SUBID_NONE);
+ loaded = wait_for_resource_loaded(RESOURCE_ID_INITRAMFS,
+ RESOURCE_SUBID_NONE);
- if (loaded != OPAL_SUCCESS || !size)
+ if (loaded != OPAL_SUCCESS || !initramfs_size)
return;
- printf("INIT: Initramfs loaded, size: %zu bytes\n", size);
+ printf("INIT: Initramfs loaded, size: %zu bytes\n", initramfs_size);
dt_add_property_u64(dt_chosen, "linux,initrd-start",
(uint64_t)INITRAMFS_LOAD_BASE);
dt_add_property_u64(dt_chosen, "linux,initrd-end",
- (uint64_t)INITRAMFS_LOAD_BASE + size);
+ (uint64_t)INITRAMFS_LOAD_BASE + initramfs_size);
}
void __noreturn load_and_boot_kernel(bool is_reboot)
@@ -683,6 +701,8 @@ void __noreturn main_cpu_entry(const void *fdt, u32 master_cpu)
/* Read in NVRAM and set it up */
nvram_init();
+ start_preload_kernel();
+
/* NX init */
nx_init();