aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ppc64/boot/Makefile32
-rw-r--r--arch/ppc64/boot/main.c80
2 files changed, 50 insertions, 62 deletions
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile
index 3c78d72a84bb..d79dfd60d8f8 100644
--- a/arch/ppc64/boot/Makefile
+++ b/arch/ppc64/boot/Makefile
@@ -34,7 +34,7 @@ zliblinuxheader := zlib.h zconf.h zutil.h
34$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) 34$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
35#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h) 35#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
36 36
37src-boot := crt0.S string.S prom.c main.c imagesize.c div64.S 37src-boot := crt0.S string.S prom.c main.c div64.S
38src-boot += $(zlib) 38src-boot += $(zlib)
39src-boot := $(addprefix $(obj)/, $(src-boot)) 39src-boot := $(addprefix $(obj)/, $(src-boot))
40obj-boot := $(addsuffix .o, $(basename $(src-boot))) 40obj-boot := $(addsuffix .o, $(basename $(src-boot)))
@@ -87,7 +87,7 @@ src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
87gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) 87gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
88 88
89hostprogs-y := addnote addRamDisk 89hostprogs-y := addnote addRamDisk
90targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd imagesize.c \ 90targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
91 $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ 91 $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
92 $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ 92 $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
93 $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ 93 $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
@@ -100,9 +100,9 @@ quiet_cmd_ramdisk = RAMDISK $@
100quiet_cmd_stripvm = STRIP $@ 100quiet_cmd_stripvm = STRIP $@
101 cmd_stripvm = $(STRIP) -s $< -o $@ 101 cmd_stripvm = $(STRIP) -s $< -o $@
102 102
103vmlinux.strip: vmlinux FORCE 103vmlinux.strip: vmlinux
104 $(call if_changed,stripvm) 104 $(call if_changed,stripvm)
105$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE 105$(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz
106 $(call if_changed,ramdisk) 106 $(call if_changed,ramdisk)
107 107
108quiet_cmd_addsection = ADDSEC $@ 108quiet_cmd_addsection = ADDSEC $@
@@ -110,48 +110,38 @@ quiet_cmd_addsection = ADDSEC $@
110 --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \ 110 --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \
111 --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS) 111 --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS)
112 112
113quiet_cmd_imagesize = GENSIZE $@
114 cmd_imagesize = ls -l vmlinux.strip | \
115 awk '{printf "/* generated -- do not edit! */\n" "unsigned long vmlinux_filesize = %d;\n", $$5}' \
116 > $(obj)/imagesize.c && \
117 $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \
118 awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> $(obj)/imagesize.c
119
120quiet_cmd_addnote = ADDNOTE $@ 113quiet_cmd_addnote = ADDNOTE $@
121 cmd_addnote = $(obj)/addnote $@ 114 cmd_addnote = $(obj)/addnote $@
122 115
123$(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE 116$(call gz-sec, $(required)): $(obj)/kernel-%.gz: %
124 $(call if_changed,gzip) 117 $(call if_changed,gzip)
125 118
126$(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz 119$(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz
127 cp -f $(obj)/ramdisk.image.gz $@ 120 cp -f $(obj)/ramdisk.image.gz $@
128 121
129$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE 122$(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz
130 @touch $@ 123 @touch $@
131 124
132$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE 125$(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c
133 $(call if_changed_dep,bootcc) 126 $(call if_changed_dep,bootcc)
134 $(call cmd,addsection) 127 $(call cmd,addsection)
135 128
136$(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required)) 129$(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required))
137$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) FORCE 130$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot)
138 $(call cmd,bootld,$(obj-boot)) 131 $(call cmd,bootld,$(obj-boot))
139 132
140$(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd)) 133$(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd))
141$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE 134$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot)
142 $(call cmd,bootld,$(obj-boot)) 135 $(call cmd,bootld,$(obj-boot))
143 136
144$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote FORCE 137$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote
145 @cp -f $< $@ 138 @cp -f $< $@
146 $(call if_changed,addnote) 139 $(call if_changed,addnote)
147 140
148$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote FORCE 141$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote
149 @cp -f $< $@ 142 @cp -f $< $@
150 $(call if_changed,addnote) 143 $(call if_changed,addnote)
151 144
152$(obj)/imagesize.c: vmlinux.strip
153 $(call cmd,imagesize)
154
155install: $(CONFIGURE) $(BOOTIMAGE) 145install: $(CONFIGURE) $(BOOTIMAGE)
156 sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" 146 sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)"
157 147
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
index 0b95ccfb143c..7485dcbf80bc 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -32,8 +32,6 @@ extern char _vmlinux_start[];
32extern char _vmlinux_end[]; 32extern char _vmlinux_end[];
33extern char _initrd_start[]; 33extern char _initrd_start[];
34extern char _initrd_end[]; 34extern char _initrd_end[];
35extern unsigned long vmlinux_filesize;
36extern unsigned long vmlinux_memsize;
37 35
38struct addr_range { 36struct addr_range {
39 unsigned long addr; 37 unsigned long addr;
@@ -45,6 +43,7 @@ static struct addr_range vmlinuz = {0, 0, 0};
45static struct addr_range initrd = {0, 0, 0}; 43static struct addr_range initrd = {0, 0, 0};
46 44
47static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */ 45static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */
46static char elfheader[256];
48 47
49 48
50typedef void (*kernel_entry_t)( unsigned long, 49typedef void (*kernel_entry_t)( unsigned long,
@@ -78,6 +77,7 @@ static unsigned long try_claim(unsigned long size)
78void start(unsigned long a1, unsigned long a2, void *promptr) 77void start(unsigned long a1, unsigned long a2, void *promptr)
79{ 78{
80 unsigned long i; 79 unsigned long i;
80 int len;
81 kernel_entry_t kernel_entry; 81 kernel_entry_t kernel_entry;
82 Elf64_Ehdr *elf64; 82 Elf64_Ehdr *elf64;
83 Elf64_Phdr *elf64ph; 83 Elf64_Phdr *elf64ph;
@@ -113,25 +113,45 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
113 claim_base = PROG_START; 113 claim_base = PROG_START;
114#endif 114#endif
115 115
116 /* 116 vmlinuz.addr = (unsigned long)_vmlinux_start;
117 * Now we try to claim some memory for the kernel itself 117 vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
118 * our "vmlinux_memsize" is the memory footprint in RAM, _HOWEVER_, what 118
119 * our Makefile stuffs in is an image containing all sort of junk including 119 /* gunzip the ELF header of the kernel */
120 * an ELF header. We need to do some calculations here to find the right 120 if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
121 * size... In practice we add 1Mb, that is enough, but we should really 121 len = vmlinuz.size;
122 * consider fixing the Makefile to put a _raw_ kernel in there ! 122 gunzip(elfheader, sizeof(elfheader),
123 */ 123 (unsigned char *)vmlinuz.addr, &len);
124 vmlinux_memsize += ONE_MB; 124 } else
125 printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize); 125 memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader));
126 vmlinux.addr = try_claim(vmlinux_memsize); 126
127 elf64 = (Elf64_Ehdr *)elfheader;
128 if ( elf64->e_ident[EI_MAG0] != ELFMAG0 ||
129 elf64->e_ident[EI_MAG1] != ELFMAG1 ||
130 elf64->e_ident[EI_MAG2] != ELFMAG2 ||
131 elf64->e_ident[EI_MAG3] != ELFMAG3 ||
132 elf64->e_ident[EI_CLASS] != ELFCLASS64 ||
133 elf64->e_ident[EI_DATA] != ELFDATA2MSB ||
134 elf64->e_type != ET_EXEC ||
135 elf64->e_machine != EM_PPC64 )
136 {
137 printf("Error: not a valid PPC64 ELF file!\n\r");
138 exit();
139 }
140
141 elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
142 (unsigned long)elf64->e_phoff);
143 for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) {
144 if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
145 break;
146 }
147 vmlinux.size = (unsigned long)elf64ph->p_filesz;
148 vmlinux.memsize = (unsigned long)elf64ph->p_memsz;
149 printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
150 vmlinux.addr = try_claim(vmlinux.memsize);
127 if (vmlinux.addr == 0) { 151 if (vmlinux.addr == 0) {
128 printf("Can't allocate memory for kernel image !\n\r"); 152 printf("Can't allocate memory for kernel image !\n\r");
129 exit(); 153 exit();
130 } 154 }
131 vmlinuz.addr = (unsigned long)_vmlinux_start;
132 vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
133 vmlinux.size = PAGE_ALIGN(vmlinux_filesize);
134 vmlinux.memsize = vmlinux_memsize;
135 155
136 /* 156 /*
137 * Now we try to claim memory for the initrd (and copy it there) 157 * Now we try to claim memory for the initrd (and copy it there)
@@ -155,11 +175,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
155 175
156 /* Eventually gunzip the kernel */ 176 /* Eventually gunzip the kernel */
157 if (*(unsigned short *)vmlinuz.addr == 0x1f8b) { 177 if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
158 int len;
159 printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...", 178 printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...",
160 vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size); 179 vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size);
161 len = vmlinuz.size; 180 len = vmlinuz.size;
162 gunzip((void *)vmlinux.addr, vmlinux.size, 181 gunzip((void *)vmlinux.addr, vmlinux.memsize,
163 (unsigned char *)vmlinuz.addr, &len); 182 (unsigned char *)vmlinuz.addr, &len);
164 printf("done 0x%lx bytes\n\r", len); 183 printf("done 0x%lx bytes\n\r", len);
165 } else { 184 } else {
@@ -167,32 +186,11 @@ void start(unsigned long a1, unsigned long a2, void *promptr)
167 } 186 }
168 187
169 /* Skip over the ELF header */ 188 /* Skip over the ELF header */
170 elf64 = (Elf64_Ehdr *)vmlinux.addr;
171 if ( elf64->e_ident[EI_MAG0] != ELFMAG0 ||
172 elf64->e_ident[EI_MAG1] != ELFMAG1 ||
173 elf64->e_ident[EI_MAG2] != ELFMAG2 ||
174 elf64->e_ident[EI_MAG3] != ELFMAG3 ||
175 elf64->e_ident[EI_CLASS] != ELFCLASS64 ||
176 elf64->e_ident[EI_DATA] != ELFDATA2MSB ||
177 elf64->e_type != ET_EXEC ||
178 elf64->e_machine != EM_PPC64 )
179 {
180 printf("Error: not a valid PPC64 ELF file!\n\r");
181 exit();
182 }
183
184 elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
185 (unsigned long)elf64->e_phoff);
186 for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) {
187 if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
188 break;
189 }
190#ifdef DEBUG 189#ifdef DEBUG
191 printf("... skipping 0x%lx bytes of ELF header\n\r", 190 printf("... skipping 0x%lx bytes of ELF header\n\r",
192 (unsigned long)elf64ph->p_offset); 191 (unsigned long)elf64ph->p_offset);
193#endif 192#endif
194 vmlinux.addr += (unsigned long)elf64ph->p_offset; 193 vmlinux.addr += (unsigned long)elf64ph->p_offset;
195 vmlinux.size -= (unsigned long)elf64ph->p_offset;
196 194
197 flush_cache((void *)vmlinux.addr, vmlinux.size); 195 flush_cache((void *)vmlinux.addr, vmlinux.size);
198 196
@@ -263,7 +261,7 @@ static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
263 s.avail_in = *lenp - i; 261 s.avail_in = *lenp - i;
264 s.next_out = dst; 262 s.next_out = dst;
265 s.avail_out = dstlen; 263 s.avail_out = dstlen;
266 r = zlib_inflate(&s, Z_FINISH); 264 r = zlib_inflate(&s, Z_FULL_FLUSH);
267 if (r != Z_OK && r != Z_STREAM_END) { 265 if (r != Z_OK && r != Z_STREAM_END) {
268 printf("inflate returned %d msg: %s\n\r", r, s.msg); 266 printf("inflate returned %d msg: %s\n\r", r, s.msg);
269 exit(); 267 exit();