1 Hack to load PS3 legacy kernels (2.6.16 and fc7 installer) with the 2.6.23
5 kexec/arch/ppc64/fs2dt.c | 47 +++++++++++++++++++++++++++++++++++++
6 kexec/arch/ppc64/kexec-elf-ppc64.c | 44 ++++++++++++++++++++++++++++++++++
7 kexec/arch/ppc64/kexec-ppc64.c | 5 +++
8 kexec/arch/ppc64/kexec-ppc64.h | 2 +
9 4 files changed, 98 insertions(+)
11 --- a/kexec/arch/ppc64/fs2dt.c
12 +++ b/kexec/arch/ppc64/fs2dt.c
13 @@ -262,6 +262,33 @@ static void putprops(char *fn, struct di
14 die("unrecoverable error: could not read \"%s\": %s\n",
15 pathname, strerror(errno));
17 + /* ps3 legacy - Add 'PS3PF' to compatible */
19 + if (ps3_legacy && !strcmp(dp->d_name, "compatible")) {
20 + static const char s[] = "PS3PF";
21 + char *const tmp = (char *)dt + len;
23 + memcpy(tmp, s, sizeof(s));
27 + fprintf(stdout, "ps3 legacy: Changed dt entry "
28 + "/compatible: <%s> -> <%s %s>\n",
29 + (char *)dt, (char *)dt, tmp);
32 + /* ps3 legacy - force memory.reg to 224 MiB */
34 + if (ps3_legacy && !strcmp(dp->d_name, "reg") && len == 16) {
35 + uint64_t tmp = *((uint64_t *)dt + 1);
37 + *((uint64_t *)dt + 1) = 0xe000000ULL;
38 + fprintf(stdout, "ps3 legacy: Changed dt entry "
39 + "/memory/reg: <%llx> -> <%llx>\n",
40 + (unsigned long long)tmp,
41 + *((unsigned long long *)dt + 1));
44 checkprop(fn, dt, len);
47 @@ -360,6 +387,26 @@ static void putnode(void)
48 reserve(initrd_base, initrd_size);
51 + /* ps3 legacy - add entry linux,platform <801> */
53 + if (ps3_legacy && !strcmp(basename,"/chosen/")) {
55 + static const uint32_t data = 0x801UL;
59 + *dt++ = propnum("linux,platform");
61 + if ((len >= 8) && ((unsigned long)dt & 0x4))
64 + memcpy(dt,&data,len);
67 + fprintf(stdout, "ps3 legacy: Added dt entry "
68 + "/chosen/linux,platform = <801>\n");
71 /* Add cmdline to the second kernel. Check to see if the new
72 * cmdline has a root=. If not, use the old root= cmdline. */
73 if (!strcmp(basename,"/chosen/")) {
74 --- a/kexec/arch/ppc64/kexec-elf-ppc64.c
75 +++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
77 uint64_t initrd_base, initrd_size;
78 unsigned char reuse_initrd = 0;
80 +int ps3_legacy = -1; /* default to probe */
82 int create_flatten_tree(struct kexec_info *, unsigned char **, unsigned long *,
84 @@ -76,6 +77,33 @@ void arch_reuse_initrd(void)
89 + * ps3_legacy_probe - Probe kernel version.
92 +static int ps3_legacy_probe(const char *p, off_t len)
94 + static const char d1[] = "linux,platform"; /* legacy 2.6.16 */
95 + static const char d2[] = "2.6.21-1.3194.fc7"; /* fedora 7 installer */
96 + const char *const end = p + len - sizeof(d2);
99 + if (p[0] == d1[0] && !memcmp(p, d1, sizeof(d1) - 1)) {
100 + fprintf(stdout, "ps3 legacy: Legacy kernel found: "
104 + if (p[0] == d2[0] && !memcmp(p, d2, sizeof(d2) - 1)) {
105 + fprintf(stdout, "ps3 legacy: Legacy kernel found: "
115 int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
116 struct kexec_info *info)
118 @@ -102,6 +130,8 @@ int elf_ppc64_load(int argc, char **argv
119 #define OPT_RAMDISK (OPT_ARCH_MAX+1)
120 #define OPT_DEVICETREEBLOB (OPT_ARCH_MAX+2)
121 #define OPT_ARGS_IGNORE (OPT_ARCH_MAX+3)
122 +#define OPT_PS3_LEGACY (OPT_ARCH_MAX+4)
123 +#define OPT_PS3_LEGACY_NO (OPT_ARCH_MAX+5)
125 static const struct option options[] = {
127 @@ -111,6 +141,8 @@ int elf_ppc64_load(int argc, char **argv
128 { "initrd", 1, NULL, OPT_RAMDISK },
129 { "devicetreeblob", 1, NULL, OPT_DEVICETREEBLOB },
130 { "args-linux", 0, NULL, OPT_ARGS_IGNORE },
131 + { "ps3-legacy", 0, NULL, OPT_PS3_LEGACY },
132 + { "ps3-no-legacy", 0, NULL, OPT_PS3_LEGACY_NO },
136 @@ -146,9 +178,18 @@ int elf_ppc64_load(int argc, char **argv
138 case OPT_ARGS_IGNORE:
140 + case OPT_PS3_LEGACY:
143 + case OPT_PS3_LEGACY_NO:
149 + if (ps3_legacy == -1)
150 + ps3_legacy = ps3_legacy_probe(buf, len);
154 cmdline_len = strlen(cmdline) + 1;
155 @@ -158,6 +199,9 @@ int elf_ppc64_load(int argc, char **argv
156 if (ramdisk && reuse_initrd)
157 die("Can't specify --ramdisk or --initrd with --reuseinitrd\n");
159 + if (ps3_legacy && devicetreeblob)
160 + die("Can't specify --devicetreeblob with --ps3-legacy\n");
162 setup_memory_ranges(info->kexec_flags);
164 /* Need to append some command line parameters internally in case of
165 --- a/kexec/arch/ppc64/kexec-ppc64.c
166 +++ b/kexec/arch/ppc64/kexec-ppc64.c
167 @@ -650,6 +650,11 @@ void arch_usage(void)
168 fprintf(stderr, " --initrd=<filename> same as --ramdisk.\n");
169 fprintf(stderr, " --devicetreeblob=<filename> Specify device tree blob file.\n");
170 fprintf(stderr, " --elf64-core-headers Prepare core headers in ELF64 format\n");
171 + fprintf(stderr, " --ps3-legacy Make fixups needed to boot PS3 legacy kernels.\n");
172 + fprintf(stderr, " The default is to probe the kernel type.\n");
173 + fprintf(stderr, " --ps3-no-legacy Do not make fixups needed to boot PS3 legacy\n");
174 + fprintf(stderr, " kernels. The default is to probe the kernel\n");
175 + fprintf(stderr, " type.\n");
178 struct arch_options_t arch_options = {
179 --- a/kexec/arch/ppc64/kexec-ppc64.h
180 +++ b/kexec/arch/ppc64/kexec-ppc64.h
181 @@ -41,4 +41,6 @@ typedef struct mem_rgns {
183 extern mem_rgns_t usablemem_rgns;
185 +extern int ps3_legacy;
187 #endif /* KEXEC_PPC64_H */