| /* |
| * Initialize machine setup information |
| * |
| * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com> |
| * |
| * This work is licensed under the terms of the GNU LGPL, version 2. |
| */ |
| #include "libcflat.h" |
| #include "fwcfg.h" |
| #include "alloc_phys.h" |
| #include "argv.h" |
| |
| extern char edata; |
| |
| struct mbi_bootinfo { |
| u32 flags; |
| u32 mem_lower; |
| u32 mem_upper; |
| u32 boot_device; |
| u32 cmdline; |
| u32 mods_count; |
| u32 mods_addr; |
| u32 reserved[5]; /* 28-47 */ |
| u32 mmap_addr; |
| u32 reserved0[3]; /* 52-63 */ |
| u32 bootloader; |
| u32 reserved1[5]; /* 68-87 */ |
| u32 size; |
| }; |
| |
| struct mbi_module { |
| u32 start, end; |
| u32 cmdline; |
| u32 unused; |
| }; |
| |
| #define ENV_SIZE 16384 |
| |
| void setup_env(char *env, int size); |
| void setup_multiboot(struct mbi_bootinfo *bootinfo); |
| void setup_libcflat(void); |
| |
| char *initrd; |
| u32 initrd_size; |
| |
| static char env[ENV_SIZE]; |
| |
| void setup_multiboot(struct mbi_bootinfo *bootinfo) |
| { |
| struct mbi_module *mods; |
| |
| /* TODO: use e820 */ |
| u64 end_of_memory = bootinfo->mem_upper * 1024ull; |
| phys_alloc_init((uintptr_t) &edata, end_of_memory - (uintptr_t) &edata); |
| |
| if (bootinfo->mods_count != 1) |
| return; |
| |
| mods = (struct mbi_module *)(uintptr_t) bootinfo->mods_addr; |
| |
| initrd = (char *)(uintptr_t) mods->start; |
| initrd_size = mods->end - mods->start; |
| } |
| |
| void setup_libcflat(void) |
| { |
| if (initrd) { |
| /* environ is currently the only file in the initrd */ |
| u32 size = MIN(initrd_size, ENV_SIZE); |
| const char *str; |
| |
| memcpy(env, initrd, size); |
| setup_env(env, size); |
| if ((str = getenv("BOOTLOADER")) && atol(str) != 0) |
| add_setup_arg("bootloader"); |
| } |
| } |