diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-09 16:04:34 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-30 11:56:30 -0400 |
commit | 6f0142d501b35468d910b9f36b6853dbd8dc5ad5 (patch) | |
tree | 8e1a3dd81b0c0b3107714219a0478c30e2645ed8 /arch/tile/kernel/setup.c | |
parent | b2eca4274c1813c76291eab4859ca3e86e6fd35b (diff) |
tile: allow "initrd" boot argument for kexec
This enables support for "kexec --initrd" for tile.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile/kernel/setup.c')
-rw-r--r-- | arch/tile/kernel/setup.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index b00e156118c3..774e819f6a5f 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c | |||
@@ -694,6 +694,25 @@ static void __init setup_bootmem_allocator(void) | |||
694 | reserve_bootmem(m->addr, m->size, 0); | 694 | reserve_bootmem(m->addr, m->size, 0); |
695 | } | 695 | } |
696 | 696 | ||
697 | #ifdef CONFIG_BLK_DEV_INITRD | ||
698 | if (initrd_start) { | ||
699 | /* Make sure the initrd memory region is not modified. */ | ||
700 | if (reserve_bootmem(initrd_start, initrd_end - initrd_start, | ||
701 | BOOTMEM_EXCLUSIVE)) { | ||
702 | pr_crit("The initrd memory region has been polluted. Disabling it.\n"); | ||
703 | initrd_start = 0; | ||
704 | initrd_end = 0; | ||
705 | } else { | ||
706 | /* | ||
707 | * Translate initrd_start & initrd_end from PA to VA for | ||
708 | * future access. | ||
709 | */ | ||
710 | initrd_start += PAGE_OFFSET; | ||
711 | initrd_end += PAGE_OFFSET; | ||
712 | } | ||
713 | } | ||
714 | #endif | ||
715 | |||
697 | #ifdef CONFIG_KEXEC | 716 | #ifdef CONFIG_KEXEC |
698 | if (crashk_res.start != crashk_res.end) | 717 | if (crashk_res.start != crashk_res.end) |
699 | reserve_bootmem(crashk_res.start, resource_size(&crashk_res), 0); | 718 | reserve_bootmem(crashk_res.start, resource_size(&crashk_res), 0); |
@@ -1095,6 +1114,10 @@ static void __init load_hv_initrd(void) | |||
1095 | int fd, rc; | 1114 | int fd, rc; |
1096 | void *initrd; | 1115 | void *initrd; |
1097 | 1116 | ||
1117 | /* If initrd has already been set, skip initramfs file in hvfs. */ | ||
1118 | if (initrd_start) | ||
1119 | return; | ||
1120 | |||
1098 | fd = hv_fs_findfile((HV_VirtAddr) initramfs_file); | 1121 | fd = hv_fs_findfile((HV_VirtAddr) initramfs_file); |
1099 | if (fd == HV_ENOENT) { | 1122 | if (fd == HV_ENOENT) { |
1100 | if (set_initramfs_file) { | 1123 | if (set_initramfs_file) { |
@@ -1133,6 +1156,25 @@ void __init free_initrd_mem(unsigned long begin, unsigned long end) | |||
1133 | free_bootmem(__pa(begin), end - begin); | 1156 | free_bootmem(__pa(begin), end - begin); |
1134 | } | 1157 | } |
1135 | 1158 | ||
1159 | static int __init setup_initrd(char *str) | ||
1160 | { | ||
1161 | char *endp; | ||
1162 | unsigned long initrd_size; | ||
1163 | |||
1164 | initrd_size = str ? simple_strtoul(str, &endp, 0) : 0; | ||
1165 | if (initrd_size == 0 || *endp != '@') | ||
1166 | return -EINVAL; | ||
1167 | |||
1168 | initrd_start = simple_strtoul(endp+1, &endp, 0); | ||
1169 | if (initrd_start == 0) | ||
1170 | return -EINVAL; | ||
1171 | |||
1172 | initrd_end = initrd_start + initrd_size; | ||
1173 | |||
1174 | return 0; | ||
1175 | } | ||
1176 | early_param("initrd", setup_initrd); | ||
1177 | |||
1136 | #else | 1178 | #else |
1137 | static inline void load_hv_initrd(void) {} | 1179 | static inline void load_hv_initrd(void) {} |
1138 | #endif /* CONFIG_BLK_DEV_INITRD */ | 1180 | #endif /* CONFIG_BLK_DEV_INITRD */ |