aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlaf Hering <olh@suse.de>2005-10-28 20:46:40 -0400
committerPaul Mackerras <paulus@samba.org>2005-10-29 01:05:10 -0400
commit8a76baf02006c945fa4a2a01a58848cb38777697 (patch)
tree774795179b55f94823e71f48f79cc7975d74a6fd
parent7054036fc526b741ba90ff1d077ac900362f30ed (diff)
[PATCH] ppc64 boot: remove need for imagesize.c
Compute the vmlinux size at runtime. Use Z_FULL_FLUSH instead of Z_FINISH, to extract only the ELF header and ELF program header. ->p_memsz is the required memory range for the executable, including bss ->p_filesz is the size of .text, .data and other runtime sections These values must be used for the claim call. All additional memory needed by the kernel is claimed in prom_init, remove the extra Mb. Pass the full memsize as target area to gunzip, otherwise not everything will be uncompressed. flush_cache has to flush all runtime sections, do not reduce the memrange by the ->p_offset value because its just that: an offset. Remove the Makefile code to produce an imagesize.c, its not needed anymore. Remove all FORCE flags, to not rebuild the zImage if vmlinux was not changed. Signed-off-by: Olaf Hering <olh@suse.de> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Anton Blanchard <anton@samba.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
-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();