MIPS: fix vmlinuz build for 32bit-only math shells
PATCH v2 1/1 MIPS: fix vmlinuz build for 32bit-only math shells
Counter to the documentation for the dash shell, it seems that on my x86_64 filth under Debian only does 32bit math. As I have configured my lapdog to use 'dash' for non-interactive tasks I run into problems when compiling a compressed kernel.
I play with the AR7 platform, so VMLINUX_LOAD_ADDRESS is 0xffffffff94100000, and for an example 4MiB kernel VMLINUZ_LOAD_ADDRESS is made out to be:
----
alex@berk:~$ bash -c 'printf "%x\n" $((0xffffffff94100000 + 0x400000))' ffffffff94500000 alex@berk:~$ dash -c 'printf "%x\n" $((0xffffffff94100000 + 0x400000))' 80000000003fffff ----
The former is obviously correct whilst the later breaks things royally.
Fortunately working with only the lower 32bit's works for both bash and dash:
----
$ bash -c 'printf "%x\n" $((0x94100000 + 0x400000))' 94500000 $ dash -c 'printf "%x\n" $((0x94100000 + 0x400000))' 94500000 ----
So, we can split the original 64bit string to two parts, and only calculate the low 32bit part, which is big enough (1GiB kernel sizes anyone?) for a normal Linux kernel image file, now, we calculate the VMLINUZ_LOAD_ADDRESS like this:
1. if present, append top 32bit of VMLINUX_LOAD_ADDRESS" as a prefix
2. get the sum of the low 32bit of VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE
This patch fixes vmlinuz kernel builds on systems where only a 32bit-only math shell is available.
Patch Changelog:
Version 2
- simplified method by using 'expr' for 'substr' and making it work with dash once again
Version 1
- Revert the removals of '-n "$(VMLINUX_SIZE)"' to avoid the error of "make clean"
- Consider more cases of the VMLINUX_LOAD_ADDRESS
Version 0
- initial release
--- arch/mips/boot/compressed/Makefile | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-)
arch/mips/boot/compressed/Makefile +5 -2
@@ -14,8 +14,11 @@ # compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE VMLINUX_SIZE := $(shell wc -c $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | cut -d' ' -f1) -VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536)))) -VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" ] && printf %x $$(($(VMLINUX_LOAD_ADDRESS) + $(VMLINUX_SIZE)))) +VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo -n $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536)))) +# VMLINUZ_LOAD_ADDRESS = concat "high32 of VMLINUX_LOAD_ADDRESS" and "(low32 of VMLINUX_LOAD_ADDRESS) + VMLINUX_SIZE" +HIGH32 := $(shell A=$(VMLINUX_LOAD_ADDRESS); [ $${\#A} -gt 10 ] && expr substr "$(VMLINUX_LOAD_ADDRESS)" 3 $$(($${\#A} - 10))) +LOW32 := $(shell [ -n "$(HIGH32)" ] && A=11 || A=3; expr substr "$(VMLINUX_LOAD_ADDRESS)" $${A} 8) +VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" -a -n "$(LOW32)" ] && printf "$(HIGH32)%08x" $$(($(VMLINUX_SIZE) + 0x$(LOW32)))) # set the default size of the mallocing area for decompressing BOOT_HEAP_SIZE := 0x400000
Signature · 1 line
1.6.6
Hi, Ralf
This patch is a bugfix, which is necessary for the users who are using dash(or the other SHELLs not compatible with bash). without it, they will get a broken compressed kernel image(with wrong load address).
Could you please queue it for 2.6.34 and also 2.6.33?
Thanks & Regards,
Wu Zhangjin
Quoted 72 lines · Alexander Clouter
Counter to the documentation for the dash shell, it seems that on my
x86_64filth under Debian only does 32bit math. As I have configured my lapdog to use 'dash' for non-interactive tasks I run into problems when compiling a compressed kernel.I play with the AR7 platform, so
VMLINUX_LOAD_ADDRESSis0xffffffff94100000, and for an example 4MiB kernelVMLINUZ_LOAD_ADDRESSis made out to be:
----alex@berk:~$ bash -c 'printf "%x\n" $((0xffffffff94100000 + 0x400000))' ffffffff94500000 alex@berk:~$ dash -c 'printf "%x\n" $((0xffffffff94100000 + 0x400000))' 80000000003fffff ----The former is obviously correct whilst the later breaks things royally.
Fortunately working with only the lower 32bit's works for both bash and dash:
----$ bash -c 'printf "%x\n" $((0x94100000 + 0x400000))' 94500000 $ dash -c 'printf "%x\n" $((0x94100000 + 0x400000))' 94500000 ----So, we can split the original 64bit string to two parts, and only calculate the low 32bit part, which is big enough (1GiB kernel sizes anyone?) for a normal Linux kernel image file, now, we calculate the
VMLINUZ_LOAD_ADDRESSlike this:1. if present, append top 32bit of
VMLINUX_LOAD_ADDRESS" as a prefix
2. get the sum of the low 32bit ofVMLINUX_LOAD_ADDRESS+VMLINUX_SIZEThis patch fixes vmlinuz kernel builds on systems where only a 32bit-only math shell is available.
Patch Changelog:
Version 2
- simplified method by using 'expr' for 'substr' and making it work with dash once again
Version 1
- Revert the removals of '-n "$(VMLINUX_SIZE)"' to avoid the error of "make clean"
- Consider more cases of theVMLINUX_LOAD_ADDRESS
Version 0
- initial releaseSigned-off-by Alexander Clouter <[email protected]>Acked-by Wu Zhangjin <[email protected]>--- arch/mips/boot/compressed/Makefile | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-)arch/mips/boot/compressed/Makefile +5
-2@@ -14,8 +14,11 @@ # compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE VMLINUX_SIZE := $(shell wc -c $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | cut -d' ' -f1) -VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536)))) -VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" ] && printf %x $$(($(VMLINUX_LOAD_ADDRESS) + $(VMLINUX_SIZE)))) +VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo -n $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536)))) +# VMLINUZ_LOAD_ADDRESS = concat "high32 of VMLINUX_LOAD_ADDRESS" and "(low32 of VMLINUX_LOAD_ADDRESS) + VMLINUX_SIZE" +HIGH32 := $(shell A=$(VMLINUX_LOAD_ADDRESS); [ $${\#A} -gt 10 ] && expr substr "$(VMLINUX_LOAD_ADDRESS)" 3 $$(($${\#A} - 10))) +LOW32 := $(shell [ -n "$(HIGH32)" ] && A=11 || A=3; expr substr "$(VMLINUX_LOAD_ADDRESS)" $${A} 8) +VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" -a -n "$(LOW32)" ] && printf "$(HIGH32)%08x" $$(($(VMLINUX_SIZE) + 0x$(LOW32)))) # set the default size of the mallocing area for decompressing BOOT_HEAP_SIZE := 0x400000
Quoted 2 lines · Alexander Clouter
Counter to the documentation for the dash shell, it seems that on my
x86_64filth under Debian only does 32bit math. As I have configured my
POSIX apparently specifies at least "long" type arithmetic for shells, so if your dash indeed is a 64-bit binary it's in violation of POSIX. What does
file $(which $SHELL)
say?
The dash binary on my Fedora 12 i386 seems to perform 64-bit arithmetic.
Ralf
Hi,
Quoted 9 lines · Ralf Baechle
Quoted 2 lines · Alexander Clouter
Counter to the documentation for the dash shell, it seems that on my
x86_64filth under Debian only does 32bit math. As I have configured myPOSIX apparently specifies at least "long" type arithmetic for shells, so if your dash indeed is a 64-bit binary it's in violation of POSIX.
/me points to the 'Counter to the documentation for the dash shell...'
he put in his description...
Quoted 6 lines
What does
file $(which $SHELL)say?
Well, 'bash' (x86-64) as thats my *interactive* shell, I use dash for the non-interactive stuff.
Quoted 2 lines
The dash binary on my Fedora 12 i386 seems to perform 64-bit arithmetic.
...does it really matter, we still are leaving all the 32bit users out there in the lurch?
When I get around to looking at the problem further I'll report it to the Debian folk...meanwhile, builds on 32bit math only shells is broken for vmlinuz regardless of my borkened shell :)
Cheers
Signature · 2 lines
Alexander Clouter .sigmonster says: We are not anticipating any emergencies.
Quoted 9 lines · Ralf Baechle
Quoted 2 lines · Alexander Clouter
Counter to the documentation for the dash shell, it seems that on my
x86_64filth under Debian only does 32bit math. As I have configured myPOSIX apparently specifies at least "long" type arithmetic for shells, so if your dash indeed is a 64-bit binary it's in violation of POSIX. What does
Quoted 6 lines
file $(which $SHELL)say?
The dash binary on my Fedora 12 i386 seems to perform 64-bit arithmetic.
Hi, Ralf
on my yeeloong laptop, with dash(0.5.5.1-3) in o32 ABI, it also can only execute 32-bit numbers, but on my thinkpad SL400(i686, dash version is 0.5.5.1-2), it works well with 64-bit arithmetic.
So, it means dash not always works normally, perhaps there is a bug there, or the bug only exists on MIPS machines?
Best Regards,
Wu Zhangjin
Quoted 24 lines · Wu Zhangjin
From: Wu Zhangjin <[email protected]>
Date: Sat, 23 Jan 2010 19:56:16 +0800
To: Ralf Baechle <[email protected]>
Cc: Alexander Clouter <[email protected]>, [email protected]
Subject: Re: [PATCHv2] MIPS: fix vmlinuz build for 32bit-only math shells
Content-Type: text/plain; charset="UTF-8"Quoted 9 lines · Ralf Baechle
Quoted 2 lines · Alexander Clouter
Counter to the documentation for the dash shell, it seems that on my
x86_64filth under Debian only does 32bit math. As I have configured myPOSIX apparently specifies at least "long" type arithmetic for shells, so if your dash indeed is a 64-bit binary it's in violation of POSIX. What does
Quoted 6 lines
file $(which $SHELL)say?
The dash binary on my Fedora 12 i386 seems to perform 64-bit arithmetic.
Quoted 8 lines
Hi, Ralf
on my yeeloong laptop, with dash(0.5.5.1-3) in o32 ABI, it also can only execute 32-bit numbers, but on my thinkpad
SL400(i686, dash version is 0.5.5.1-2), it works well with 64-bit arithmetic.So, it means dash not always works normally, perhaps there is a bug there, or the bug only exists on MIPS machines?
Well, I was wondering if the dash being used by Alexander is simply defect. However in the end that doesn't matter; we try to restrict the build environment to just a standard POSIX environment - or at least as close as possible and that means we can only expect $((<expression)) to perform 32-bit arithmetic.
I've applied the patch for now but this is ugly. I was even considering if a small host C program that does the math is the lesser evil.
That said, applied. Thanks folks!
Ralf