1 /* 2 * Initialize machine setup information 3 * 4 * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com> 5 * 6 * This work is licensed under the terms of the GNU LGPL, version 2. 7 */ 8 #include "libcflat.h" 9 #include "fwcfg.h" 10 #include "alloc_phys.h" 11 #include "argv.h" 12 13 extern char edata; 14 15 struct mbi_bootinfo { 16 u32 flags; 17 u32 mem_lower; 18 u32 mem_upper; 19 u32 boot_device; 20 u32 cmdline; 21 u32 mods_count; 22 u32 mods_addr; 23 u32 reserved[5]; /* 28-47 */ 24 u32 mmap_addr; 25 u32 reserved0[3]; /* 52-63 */ 26 u32 bootloader; 27 u32 reserved1[5]; /* 68-87 */ 28 u32 size; 29 }; 30 31 struct mbi_module { 32 u32 start, end; 33 u32 cmdline; 34 u32 unused; 35 }; 36 37 #define ENV_SIZE 16384 38 39 void setup_env(char *env, int size); 40 void setup_multiboot(struct mbi_bootinfo *bootinfo); 41 void setup_libcflat(void); 42 43 char *initrd; 44 u32 initrd_size; 45 46 static char env[ENV_SIZE]; 47 48 void setup_multiboot(struct mbi_bootinfo *bootinfo) 49 { 50 struct mbi_module *mods; 51 52 /* TODO: use e820 */ 53 u64 end_of_memory = bootinfo->mem_upper * 1024ull; 54 phys_alloc_init((uintptr_t) &edata, end_of_memory - (uintptr_t) &edata); 55 56 if (bootinfo->mods_count != 1) 57 return; 58 59 mods = (struct mbi_module *)(uintptr_t) bootinfo->mods_addr; 60 61 initrd = (char *)(uintptr_t) mods->start; 62 initrd_size = mods->end - mods->start; 63 } 64 65 void setup_libcflat(void) 66 { 67 if (initrd) { 68 /* environ is currently the only file in the initrd */ 69 u32 size = MIN(initrd_size, ENV_SIZE); 70 const char *str; 71 72 memcpy(env, initrd, size); 73 setup_env(env, size); 74 if ((str = getenv("BOOTLOADER")) && atol(str) != 0) 75 add_setup_arg("bootloader"); 76 } 77 } 78