Compressed kernels currently won't boot
James Bottomley
maintainerI noticed this trying to test out compressed kernel booting. The problem is that a compressed kernel is divided into two pieces, one of which starts at 0x000e0000 and is the bootstrap code which is uncompressed into 0x00100000 and the rest of which is the real compressed kernel which is loaded above the end of the current decompressed size of the entire kernel. palo decompresses the head and jumps to it and it then decompresses the rest of the kernel into place.
This means that the first part of the compressed image can't be larger
than 0x20000 == 131072 because otherwise it will be loaded into an area that decompression will alter.
The problem is that a change was introduced by
commit 34c201ae49fe9e0bf3b389da5869d810f201c740
Author: Helge Deller <[email protected]> Date: Mon Oct 15 22:14:01 2018 +0200
parisc: Include compressed vmlinux file in vmlinuz boot kernel
Which moved the compressed vmlinux from the second segment to the first, which is what makes it too big for me. This patch reverting that piece allows me to boot again.
James
---
arch/parisc/boot/compressed/vmlinux.lds.S +6 -6
@@ -42,12 +42,6 @@ SECTIONS #endif _startcode_end = .; - /* vmlinux.bin.gz is here */ - . = ALIGN(8); - .rodata.compressed : { - *(.rodata.compressed) - } - /* bootloader code and data starts behind area of extracted kernel */ . = (SZ_end - SZparisc_kernel_start + KERNEL_BINARY_TEXT_START);
@@ -73,6 +67,12 @@ SECTIONS *(.rodata.*) _erodata = . ; } + /* vmlinux.bin.gz is here */ + . = ALIGN(8); + .rodata.compressed : { + *(.rodata.compressed) + } + . = ALIGN(8); .bss : { _bss = . ;
Hi,
Quoted 11 lines · James Bottomley
I noticed this trying to test out compressed kernel booting. The problem is that a compressed kernel is divided into two pieces, one of which starts at
0x000e0000and is the bootstrap code which is uncompressed into0x00100000and the rest of which is the real compressed kernel which is loaded above the end of the current decompressed size of the entire kernel. palo decompresses the head and jumps to it and it then decompresses the rest of the kernel into place.
This means that the first part of the compressed image can't be larger
than0x20000== 131072 because otherwise it will be loaded into an area that decompression will alter.
Quoted 5 lines
The problem is that a change was introduced by
commit
34c201ae49fe9e0bf3b389da5869d810f201c740Author: Helge Deller <[email protected]> Date: Mon Oct 15 22:14:01 2018 +0200
Hmm. This is what i've been facing as well. After reading this commit i'm not sure that the patch i've just sent ("parisc: strip debug information when building compressed images") is really wanted. However, it is really a pain to always copy huge lifimages around when booting parisc machines via LAN. Does someone really extract the vmlinux file from a compressed kernel images? Should we keep that?
Regards
Sven
James Bottomley
maintainerQuoted 14 lines · Sven Schnelle
Hi,
Quoted 11 lines · James Bottomley
I noticed this trying to test out compressed kernel booting. The problem is that a compressed kernel is divided into two pieces, one of which starts at
0x000e0000and is the bootstrap code which is uncompressed into0x00100000and the rest of which is the real compressed kernel which is loaded above the end of the current decompressed size of the entire kernel. palo decompresses the head and jumps to it and it then decompresses the rest of the kernel into place. This means that the first part of the compressed image can't be larger than0x20000== 131072 because otherwise it will be loaded into an area that decompression will alter.
Quoted 7 lines
Quoted 5 lines
The problem is that a change was introduced by
commit
34c201ae49fe9e0bf3b389da5869d810f201c740Author: Helge Deller <[email protected]> Date: Mon Oct 15 22:14:01 2018 +0200Hmm. This is what i've been facing as well.
Yes, except you're a more extreme case than me ... you actually have the compressed segment overlapping the end of the decompressed text. that does seem to mean we have a lot of no-load debug information which isn't useful to the compressed image.
Quoted 6 lines
After reading this commit i'm not sure that the patch i've just sent
("parisc: strip debug information when building compressed images") is really wanted. However, it is really a pain to always copy huge lifimages around when booting parisc machines via LAN. Does someone really extract the vmlinux file from a compressed kernel images? Should we keep that?
Well, it's a thing. There's a script in the kernel source tree
scripts/extract-vmlinux
that does it. It doesn't seem to be packaged by debian, though.
James
James Bottomley
maintainerQuoted 40 lines · James Bottomley
Quoted 18 lines · Sven Schnelle
Hi,
Quoted 15 lines · James Bottomley
I noticed this trying to test out compressed kernel booting. The problem is that a compressed kernel is divided into two pieces, one
of which starts at0x000e0000and is the bootstrap code which is uncompressed into0x00100000and the rest of which is the real compressed kernel which is loaded above the end of the current decompressed size of the entire kernel. palo decompresses the head
and jumps to it and it then decompresses the rest of the kernel into place. This means that the first part of the compressed image
can't be larger than0x20000== 131072 because otherwise it will be
loaded into an area that decompression will alter.Quoted 7 lines
Quoted 5 lines
The problem is that a change was introduced by
commit
34c201ae49fe9e0bf3b389da5869d810f201c740Author: Helge Deller <[email protected]> Date: Mon Oct 15 22:14:01 2018 +0200Hmm. This is what i've been facing as well.
Yes, except you're a more extreme case than me ... you actually have the compressed segment overlapping the end of the decompressed text. that does seem to mean we have a lot of no-load debug information which
isn't useful to the compressed image.Quoted 6 lines
After reading this commit i'm not sure that the patch i've just
sent ("parisc: strip debug information when building compressed images") is really wanted. However, it is really a pain to always copy huge lifimages around when booting parisc machines via LAN. Does someone really extract the vmlinux file from a compressed kernel images? Should we keep that?
Quoted 5 lines
Well, it's a thing. There's a script in the kernel source tree
scripts/extract-vmlinuxthat does it. It doesn't seem to be packaged by debian, though.
What about causing the compressed make to build both a stripped and a non-stripped bzImage (say sbzImage and bzImage). That way you always have the stripped one available for small size things like boot from tape or DVD? but in the usual case we use the bzImage with full contents.
James
Hi James,
Quoted 5 lines · James Bottomley
What about causing the compressed make to build both a stripped and a non-stripped bzImage (say sbzImage and bzImage). That way you always have the stripped one available for small size things like boot from tape or DVD? but in the usual case we use the bzImage with full contents.
In that case we would also need to build two lifimages - how about adding a config option option? Something like "Strip debug information from compressed kernel images"?
Regards
Sven
Helge Deller
maintainerQuoted 10 lines · Sven Schnelle
Hi James,
Quoted 5 lines · James Bottomley
What about causing the compressed make to build both a stripped and a non-stripped bzImage (say sbzImage and bzImage). That way you always have the stripped one available for small size things like boot from tape or DVD? but in the usual case we use the bzImage with full contents.
Quoted 3 lines
In that case we would also need to build two lifimages - how about adding a config option option? Something like "Strip debug information from compressed kernel images"?
I agree, two lifimages don't make sense. Only one vmlinuz gets installed. Instead of the config option, I tink my latest patch is better.
Helge
James Bottomley
maintainerQuoted 11 lines · Helge Deller
Quoted 10 lines · Sven Schnelle
Hi James,
Quoted 5 lines · James Bottomley
What about causing the compressed make to build both a stripped and a non-stripped bzImage (say sbzImage and bzImage). That way you always have the stripped one available for small size things like boot from tape or DVD? but in the usual case we use the bzImage with full contents.
Quoted 7 lines
Quoted 3 lines
In that case we would also need to build two lifimages - how about adding a config option option? Something like "Strip debug information from compressed kernel images"?
I agree, two lifimages don't make sense. Only one vmlinuz gets installed. Instead of the config option, I tink my latest patch is better.
It doesn't solve the problem that if a stripped compressed image is > 128kb then it overwrites the decompress area starting at 0x00100000 so we can't decompress the end because we've already overwritten it before the decompressor gets to it.
What we could possibly do is be clever and align the .rodata.compressed so its last text byte ends where the uncompressed kernel text would end. We could be even more clever and split .rodata.compressed into a load and a noload part so we would only load the part of the compressed kernel we need. Then the lifimage creation scripts could discard the noload part containing the debug symbols.
James
Helge Deller
maintainerQuoted 16 lines · James Bottomley
Quoted 15 lines · Helge Deller
Quoted 13 lines · Sven Schnelle
Hi James,
Quoted 5 lines · James Bottomley
What about causing the compressed make to build both a stripped and a non-stripped bzImage (say sbzImage and bzImage). That way you always have the stripped one available for small size things like boot from tape or DVD? but in the usual case we use the bzImage with full contents.
In that case we would also need to build two lifimages - how about adding a config option option? Something like "Strip debug information from compressed kernel images"?
Quoted 8 lines
Quoted 3 lines
I agree, two lifimages don't make sense. Only one vmlinuz gets installed. Instead of the config option, I tink my latest patch is better.
It doesn't solve the problem that if a stripped compressed image is > 128kb then it overwrites the decompress area starting at
0x00100000so we can't decompress the end because we've already overwritten it before the decompressor gets to it.
I don't get this point.
hppa64-linux-gnu-objdump -h vmlinuz
shows:
Sections:
Idx Name Size VMA LMA File off Algn 0 .head.text 00000084 00000000000e0000 00000000000e0000 00001000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .opd 00000340 00000000000e0090 00000000000e0090 00001090 2**3
CONTENTS, ALLOC, LOAD, DATA
2 .dlt 00000160 00000000000e03d0 00000000000e03d0 000013d0 2**3
CONTENTS, ALLOC, LOAD, DATA
3 .rodata.compressed 01f3c2b0 00000000000e0530 00000000000e0530 00001530 2**0
CONTENTS, ALLOC, LOAD, DATA
4 .text 00005cc0 000000000201d000 000000000201d000 01f3e000 2**7
CONTENTS, ALLOC, LOAD, READONLY, CODE
5 .data 00000060 0000000002022cc0 0000000002022cc0 01f43cc0 2**3
CONTENTS, ALLOC, LOAD, DATA
Only .head.text gets loaded at e0000, and it is basically just a few bytes which sets-up registers and jump to .text segment (at 0201d000 in this case).
See: arch/parisc/boot/compressed/head.S
How should that get bigger than 128KB ?
Then the code in .text decompresses the whole kernel image behind itself (behind "data").
Then the ELF loader moves the parts from the high-memory to the final destination (e.g. 1000000).
The steps are:
1. palo loads vmlinuz into memory.
2. vmlinuz' head starts, and decompress_kernel() in arch/parisc/boot/compressed/misc.c decompresses the vmlinuz file to a vmlinux file and stores it to vmlinux_addr (which is behind the bss section of the boot decompressor).
3. Then the original kernel entry is started (arch/parisc/kernel/entry.S) which moves the code to where it belongs and starts the kernel.
Helge
Quoted 9 lines
What we could possibly do is be clever and align the .rodata.compressed so its last text byte ends where the uncompressed kernel text would end. We could be even more clever and split .rodata.compressed into a load and a noload part so we would only load the part of the compressed kernel we need. Then the lifimage creation scripts could discard the noload part containing the debug symbols.
James
James Bottomley
maintainerQuoted 59 lines · Helge Deller
Quoted 22 lines · James Bottomley
Quoted 13 lines · Helge Deller
Quoted 12 lines · Sven Schnelle
Hi James,
Quoted 6 lines · James Bottomley
What about causing the compressed make to build both a stripped and a non-stripped bzImage (say sbzImage and bzImage). That way you always have the stripped one available for small size things like boot from tape or DVD? but in the usual case we use the bzImage with full contents.
Quoted 7 lines
Quoted 3 lines
In that case we would also need to build two lifimages - how about adding a config option option? Something like "Strip debug information from compressed kernel images"?
I agree, two lifimages don't make sense. Only one vmlinuz gets installed. Instead of the config option, I tink my latest patch is better.
Quoted 5 lines
It doesn't solve the problem that if a stripped compressed image is
Quoted 1 line
128kb then it overwrites the decompress area starting at
0x00100000so we can't decompress the end because we've already overwritten it before the decompressor gets to it.I don't get this point.
hppa64-linux-gnu-objdump -h vmlinuz
shows:
Sections:
Idx Name Size VMA LMA File
off Algn
0
.head.text 0000008400000000000e000000000000000e000000001000
2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1
.opd 0000034000000000000e009000000000000e009000001090
2**3
CONTENTS, ALLOC, LOAD, DATA
2
.dlt 0000016000000000000e03d000000000000e03d0000013d0
2**3
CONTENTS, ALLOC, LOAD, DATA
3 .rodata.compressed01f3c2b000000000000e053000000000000e053000001530 2**0
CONTENTS, ALLOC, LOAD, DATA
4
.text00005cc0000000000201d000000000000201d00001f3e000
2**7
CONTENTS, ALLOC, LOAD, READONLY, CODE
5
.data 000000600000000002022cc00000000002022cc001f43cc0
2**3
CONTENTS, ALLOC, LOAD, DATA
Quoted 3 lines
Only .head.text gets loaded at e0000, and it is basically just a few bytes which sets-up registers and jump to .text segment (at
0201d000in this case).
Actually, you're looking at the wrong thing, you want to look at the program header (the segments) not the section header. It's the program header we load. If I extract this from the current debian kernel we get
jejb@ion:~/git/linux-build/arch/parisc/boot/compressed> readelf -l /boot/vmlinuz-4.19.0-5-parisc64-smp
Elf file type is EXEC (Executable file) Entry point 0xe0000
There are 4 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000001040 0x0000000000000000
0x00000000000000e0 0x00000000000000e0 R E 0x8
LOAD 0x0000000000001000 0x00000000000e0000 0x00000000000e0000
0x00000000000004d8 0x00000000000004d8 RWE 0x1000
LOAD 0x0000000000002000 0x0000000001400000 0x0000000001400000
0x00000000003dd46c 0x00000000003e1000 RWE 0x1000
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RWE 0x10 Section to Segment mapping:
Segment Sections...
00
01 .head.text .opd .dlt
02 .text .data .rodata .eh_frame .bss
03
The two LOAD sections corresponding to what PALO actually loads. The problem happens if the length of the first load section is bigger than 0x20000. Now if you look what happens after your change:
jejb@ion:~/git/linux-build/build/parisc64/arch/parisc/boot> readelf -l bzImage
Elf file type is EXEC (Executable file) Entry point 0xe0000
There are 4 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000001040 0x0000000000000000
0x00000000000000e0 0x00000000000000e0 R E 0x8
LOAD 0x0000000000001000 0x00000000000e0000 0x00000000000e0000
0x00000000004ae760 0x00000000004ae760 RWE 0x1000
LOAD 0x00000000004b0000 0x000000000118a000 0x000000000118a000
0x0000000000006044 0x000000000000a000 RWE 0x1000
GNU_STACK 0 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RWE 0x10 Section to Segment mapping:
Segment Sections...
00
01 .head.text .opd .dlt .rodata.compressed
02 .text .data .rodata .eh_frame .bss
03
So the first section tries to load between 0x000e0000-0x0058e760 and that's overwritten at 0x00100000 when the decompression starts because 0x00100000 is our KERNEL_BINARY_TEXT_START. The result for me is that I get the Decompressing linux ... message followed by a HPMC.
James
Helge Deller
maintainerQuoted 94 lines · James Bottomley
Quoted 59 lines · Helge Deller
Quoted 22 lines · James Bottomley
Quoted 13 lines · Helge Deller
Quoted 12 lines · Sven Schnelle
Hi James,
Quoted 6 lines · James Bottomley
What about causing the compressed make to build both a stripped and a non-stripped bzImage (say sbzImage and bzImage). That way you always have the stripped one available for small size things like boot from tape or DVD? but in the usual case we use the bzImage with full contents.
Quoted 7 lines
Quoted 3 lines
In that case we would also need to build two lifimages - how about adding a config option option? Something like "Strip debug information from compressed kernel images"?
I agree, two lifimages don't make sense. Only one vmlinuz gets installed. Instead of the config option, I tink my latest patch is better.
Quoted 5 lines
It doesn't solve the problem that if a stripped compressed image is
Quoted 1 line
128kb then it overwrites the decompress area starting at
0x00100000so we can't decompress the end because we've already overwritten it before the decompressor gets to it.I don't get this point.
hppa64-linux-gnu-objdump -h vmlinuz
shows:
Sections:
Idx Name Size VMA LMA File
off Algn0.head.text 00000084
00000000000e000000000000000e000000001000
2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1
.opd 0000034000000000000e009000000000000e009000001090
2**3
CONTENTS, ALLOC, LOAD, DATA
2
.dlt 0000016000000000000e03d000000000000e03d0000013d0
2**3
CONTENTS, ALLOC, LOAD, DATA
3 .rodata.compressed01f3c2b000000000000e053000000000000e053000001530 2**0
CONTENTS, ALLOC, LOAD, DATA
4
.text00005cc0000000000201d000000000000201d00001f3e000
2**7
CONTENTS, ALLOC, LOAD, READONLY, CODE
5
.data 000000600000000002022cc00000000002022cc001f43cc0
2**3
CONTENTS, ALLOC, LOAD, DATAQuoted 3 lines
Only .head.text gets loaded at e0000, and it is basically just a few bytes which sets-up registers and jump to .text segment (at
0201d000in this case).Actually, you're looking at the wrong thing, you want to look at the program header (the segments) not the section header. It's the program header we load. If I extract this from the current debian kernel we get
jejb@ion:~/git/linux-build/arch/parisc/boot/compressed> readelf -l
/boot/vmlinuz-4.19.0-5-parisc64-smpElf file type is EXEC (Executable file) Entry point
0xe0000
There are 4 program headers, starting at offset 64Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0x0000000000001040 0x0000000000000000 0x00000000000000e0 0x00000000000000e0 R E 0x8 LOAD 0x0000000000001000 0x00000000000e0000 0x00000000000e0000 0x00000000000004d8 0x00000000000004d8 RWE 0x1000 LOAD 0x0000000000002000 0x0000000001400000 0x0000000001400000 0x00000000003dd46c 0x00000000003e1000 RWE 0x1000 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RWE 0x10Section to Segment mapping:
Segment Sections...
00
01 .head.text .opd .dlt
02 .text .data .rodata .eh_frame .bss
03
Quoted 3 lines
The two LOAD sections corresponding to what PALO actually loads. The problem happens if the length of the first load section is bigger than
0x20000.
What exactly is the problem if the first section is bigger than 0x20000?
Quoted 2 lines
Now if you look what happens after your change:
jejb@ion:~/git/linux-build/build/parisc64/arch/parisc/boot> readelf -l bzImage
Ok - bzImage is the same as ./vmlinuz.
Quoted 23 lines
Elf file type is EXEC (Executable file) Entry point
0xe0000
There are 4 program headers, starting at offset 64Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0x0000000000001040 0x0000000000000000 0x00000000000000e0 0x00000000000000e0 R E 0x8 LOAD 0x0000000000001000 0x00000000000e0000 0x00000000000e0000 0x00000000004ae760 0x00000000004ae760 RWE 0x1000 LOAD 0x00000000004b0000 0x000000000118a000 0x000000000118a000 0x0000000000006044 0x000000000000a000 RWE 0x1000 GNU_STACK 0 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RWE 0x10Section to Segment mapping:
Segment Sections...
00
01 .head.text .opd .dlt .rodata.compressed
02 .text .data .rodata .eh_frame .bss
03
Quoted 3 lines
So the first section tries to load between 0x000e0000-0x0058e760 and that's overwritten at
0x00100000when the decompression starts because0x00100000is ourKERNEL_BINARY_TEXT_START.
The decompression decompresses the image from .rodata.compressed
to an area behind .bss.
So, "vmlinux" ends up behind .bss for further processing.
This "vmlinux" (which can have multiple ELF sections) is then started at the high address. That address is way above the 0x00100000 or KERNEL_BINARY_TEXT_START.
It then finally moves itself (the ELF sections) to 0x00100000.
Quoted 2 lines
The result for me is that
I get the Decompressing linux ... message followed by a HPMC.
It actually does boot for me and Sven without a HPMC. The decompression is slow (~40 seconds on my c3000 for 160MB). I still *believe* you are facing a HPMC because of other reasons. On which machine do you start.
How much memory?
Helge
James Bottomley
maintainerQuoted 182 lines · Helge Deller
Quoted 121 lines · James Bottomley
Quoted 72 lines · Helge Deller
Quoted 29 lines · James Bottomley
Quoted 18 lines · Helge Deller
Quoted 12 lines · Sven Schnelle
Hi James,
Quoted 6 lines · James Bottomley
What about causing the compressed make to build both a stripped and a non-stripped bzImage (say sbzImage and bzImage). That way you always have the stripped one available for small size things like boot from tape or DVD? but in the usual case we use the bzImage with full contents.
Quoted 4 lines
In that case we would also need to build two lifimages - how
about adding a config option option? Something like "Strip debug information from compressed kernel images"?Quoted 5 lines
I agree, two lifimages don't make sense. Only one vmlinuz gets
installed. Instead of the config option, I tink my latest patch
is better.It doesn't solve the problem that if a stripped compressed image is
Quoted 1 line
Quoted 5 lines
128kb then it overwrites the decompress area starting at
0x00100000
so we can't decompress the end because we've already overwritten it
before the decompressor gets to it.I don't get this point.
hppa64-linux-gnu-objdump -h vmlinuz
shows:
Sections:
Idx
Name Size VMA LMA File
off Algn0.head.text 00000084
00000000000e000000000000000e000000001
000
2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1
.opd 0000034000000000000e009000000000000e009000001
090
2**3
CONTENTS, ALLOC, LOAD, DATA
2
.dlt 0000016000000000000e03d000000000000e03d000001
3d0
2**3
CONTENTS, ALLOC, LOAD, DATA
3 .rodata.compressed01f3c2b000000000000e053000000000000e053000001530 2**0
CONTENTS, ALLOC, LOAD, DATA
4
.text00005cc0000000000201d000000000000201d00001f3e
000
2**7
CONTENTS, ALLOC, LOAD, READONLY, CODE
5
.data 000000600000000002022cc00000000002022cc001f43
cc0
2**3
CONTENTS, ALLOC, LOAD, DATAQuoted 5 lines
Only .head.text gets loaded at e0000, and it is basically just a few
bytes which sets-up registers and jump to .text segment (at0201d000
in this case).Actually, you're looking at the wrong thing, you want to look at the
program header (the segments) not the section header. It's the program
header we load. If I extract this from the current debian kernel we
getjejb@ion:~/git/linux-build/arch/parisc/boot/compressed> readelf -l
/boot/vmlinuz-4.19.0-5-parisc64-smpElf file type is EXEC (Executable file) Entry point
0xe0000
There are 4 program headers, starting at offset 64Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Ali
gn
PHDR0x00000000000000400x00000000000010400x00000000000000000x00000000000000e0 0x00000000000000e0 R E 0x8 LOAD 0x0000000000001000 0x00000000000e0000 0x00000000000e0000 0x00000000000004d8 0x00000000000004d8 RWE 0x1000 LOAD 0x0000000000002000 0x0000000001400000 0x0000000001400000 0x00000000003dd46c 0x00000000003e1000 RWE 0x1000 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000RWE0x10Section to Segment mapping:
Segment Sections...
00
01 .head.text .opd .dlt
02 .text .data .rodata .eh_frame .bss
03Quoted 5 lines
The two LOAD sections corresponding to what PALO actually loads. The
problem happens if the length of the first load section is bigger than0x20000.What exactly is the problem if the first section is bigger than
0x20000?Quoted 3 lines
Now if you look what happens after your change:
jejb@ion:~/git/linux-build/build/parisc64/arch/parisc/boot> readelf -l bzImageOk - bzImage is the same as ./vmlinuz.
Quoted 31 lines
Elf file type is EXEC (Executable file) Entry point
0xe0000
There are 4 program headers, starting at offset 64Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Ali
gn
PHDR0x00000000000000400x00000000000010400x00000000000000000x00000000000000e0 0x00000000000000e0 R E 0x8 LOAD 0x0000000000001000 0x00000000000e0000 0x00000000000e0000 0x00000000004ae760 0x00000000004ae760 RWE 0x1000 LOAD 0x00000000004b0000 0x000000000118a000 0x000000000118a000 0x0000000000006044 0x000000000000a000 RWE 0x1000 GNU_STACK 0 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000RWE0x10Section to Segment mapping:
Segment Sections...
00
01 .head.text .opd .dlt .rodata.compressed
02 .text .data .rodata .eh_frame .bss
03Quoted 5 lines
So the first section tries to load between 0x000e0000-0x0058e760 and
that's overwritten at0x00100000when the decompression starts because0x00100000is ourKERNEL_BINARY_TEXT_START.The decompression decompresses the image from .rodata.compressed to an area behind .bss.
So, "vmlinux" ends up behind .bss for further processing. This "vmlinux" (which can have multiple ELF sections) is then started at the high address.
That address is way above the0x00100000orKERNEL_BINARY_TEXT_START. It then finally moves itself (the ELF sections) to0x00100000.
Quoted 8 lines
Quoted 2 lines
The result for me is that
I get the Decompressing linux ... message followed by a HPMC.It actually does boot for me and Sven without a HPMC. The decompression is slow (~40 seconds on my c3000 for 160MB). I still *believe* you are facing a HPMC because of other reasons. On which machine do you start.
How much memory?
This turned out to be a very eccentric bug. Apparently we don't have an archclean target in our arch/parisc/Makefile, so files in there never get cleaned out by make mrproper. This, in turn means that the sizes.h file in arch/parisc/boot/compressed never gets removed and worse, when you transition to an O=build/parisc[64] build model it overrides the generated file. The upshot being my bzImage was building with a SZ_end that was too small.
I fixed it by making mrproper clean everyting.
James
---
arch/parisc/Makefile +3 -0
@@ -182,5 +182,8 @@ define archhelp @echo ' zinstall - Install compressed vmlinuz kernel' endef +archclean: + $(Q)$(MAKE) $(clean)=$(boot) + archheaders: $(Q)$(MAKE) $(build)=arch/parisc/kernel/syscalls all
James Bottomley
maintainerQuoted 10 lines · Sven Schnelle
Hi James,
Quoted 5 lines · James Bottomley
What about causing the compressed make to build both a stripped and a non-stripped bzImage (say sbzImage and bzImage). That way you always have the stripped one available for small size things like boot from tape or DVD? but in the usual case we use the bzImage with full contents.
Quoted 3 lines
In that case we would also need to build two lifimages - how about adding a config option option? Something like "Strip debug information from compressed kernel images"?
Actually, I just looked at what x86 does. It has this in the arch/x86/boot/compressed/Makefile:
OBJCOPYFLAGS_vmlinux.bin := -R .comment -S
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
So it basically strips all the debug information from the kernel before compressing, which argues there's no need to retain the information because x86 doesn't bother.
James
Hi,
Quoted 18 lines · James Bottomley
Quoted 10 lines · Sven Schnelle
Hi James,
Quoted 5 lines · James Bottomley
What about causing the compressed make to build both a stripped and a non-stripped bzImage (say sbzImage and bzImage). That way you always have the stripped one available for small size things like boot from tape or DVD? but in the usual case we use the bzImage with full contents.
Quoted 3 lines
In that case we would also need to build two lifimages - how about adding a config option option? Something like "Strip debug information from compressed kernel images"?
Actually, I just looked at what x86 does. It has this in the
arch/x86/boot/compressed/Makefile:
Quoted 7 lines
OBJCOPYFLAGS_vmlinux.bin := -R .comment -S
$(obj)/vmlinux.bin: vmlinux FORCE$(call if_changed,objcopy)So it basically strips all the debug information from the kernel before compressing, which argues there's no need to retain the information because x86 doesn't bother.
Nice. So we could convince Helge by saying "Look, x86 is also stripping it"! :-)
Regards
Sven
Helge Deller
maintainerQuoted 25 lines · Sven Schnelle
Hi,
Quoted 22 lines · James Bottomley
Quoted 10 lines · Sven Schnelle
Hi James,
Quoted 5 lines · James Bottomley
What about causing the compressed make to build both a stripped and a non-stripped bzImage (say sbzImage and bzImage). That way you always have the stripped one available for small size things like boot from tape or DVD? but in the usual case we use the bzImage with full contents.
Quoted 3 lines
In that case we would also need to build two lifimages - how about adding a config option option? Something like "Strip debug information from compressed kernel images"?
Actually, I just looked at what x86 does. It has this in the
arch/x86/boot/compressed/Makefile:OBJCOPYFLAGS_vmlinux.bin := -R .comment -S
$(obj)/vmlinux.bin: vmlinux FORCE$(call if_changed,objcopy)
Quoted 5 lines
Quoted 3 lines
So it basically strips all the debug information from the kernel before compressing, which argues there's no need to retain the information because x86 doesn't bother.
Nice. So we could convince Helge by saying "Look, x86 is also stripping it"! :-)
I'm fine with doing exactly why x86 does :-)
Helge
Helge Deller
maintainerQuoted 26 lines · Helge Deller
Quoted 25 lines · Sven Schnelle
Hi,
Quoted 22 lines · James Bottomley
Quoted 10 lines · Sven Schnelle
Hi James,
Quoted 5 lines · James Bottomley
What about causing the compressed make to build both a stripped and a non-stripped bzImage (say sbzImage and bzImage). That way you always have the stripped one available for small size things like boot from tape or DVD? but in the usual case we use the bzImage with full contents.
Quoted 3 lines
In that case we would also need to build two lifimages - how about adding a config option option? Something like "Strip debug information from compressed kernel images"?
Actually, I just looked at what x86 does. It has this in the
arch/x86/boot/compressed/Makefile:OBJCOPYFLAGS_vmlinux.bin := -R .comment -S
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
So it basically strips all the debug information from the kernel before compressing, which argues there's no need to retain the information because x86 doesn't bother.
Nice. So we could convince Helge by saying "Look, x86 is also stripping it"! :-)
I'm fine with doing exactly why x86 does :-)
Attached is the revised patch, and it gets the compressed kernel down from 32MB to 3.8MB.
Helge
arch/parisc/boot/compressed/Makefile +2 -1
@@ -55,7 +55,8 @@ $(obj)/misc.o: $(obj)/sizes.h CPPFLAGS_vmlinux.lds += -I$(objtree)/$(obj) -DBOOTLOADER $(obj)/vmlinux.lds: $(obj)/sizes.h -$(obj)/vmlinux.bin: vmlinux +OBJCOPYFLAGS_vmlinux.bin := -R .comment -S +$(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) vmlinux.bin.all-y := $(obj)/vmlinux.bin
arch/parisc/boot/compressed/vmlinux.lds.S +2 -2
@@ -48,8 +48,8 @@ SECTIONS *(.rodata.compressed) } - /* bootloader code and data starts behind area of extracted kernel */ - . = (SZ_end - SZparisc_kernel_start + KERNEL_BINARY_TEXT_START); + /* bootloader code and data starts at least behind area of extracted kernel */ + . = MAX(ABSOLUTE(.), (SZ_end - SZparisc_kernel_start + KERNEL_BINARY_TEXT_START)); /* align on next page boundary */ . = ALIGN(4096);
Hi Helge,
Quoted 4 lines · Helge Deller
Attached is the revised patch, and it gets the compressed kernel down from 32MB to 3.8MB.
Works for me, thanks!
Regards
Sven
Helge Deller
maintainerQuoted 17 lines · James Bottomley
I noticed this trying to test out compressed kernel booting. The problem is that a compressed kernel is divided into two pieces, one of which starts at
0x000e0000and is the bootstrap code which is uncompressed into0x00100000and the rest of which is the real compressed kernel which is loaded above the end of the current decompressed size of the entire kernel. palo decompresses the head and jumps to it and it then decompresses the rest of the kernel into place.
This means that the first part of the compressed image can't be larger
than0x20000== 131072 because otherwise it will be loaded into an area that decompression will alter.The problem is that a change was introduced by
commit
34c201ae49fe9e0bf3b389da5869d810f201c740Author: Helge Deller <[email protected]> Date: Mon Oct 15 22:14:01 2018 +0200
Quoted 6 lines
parisc: Include compressed vmlinux file in vmlinuz boot kernel
Which moved the compressed vmlinux from the second segment to the first, which is what makes it too big for me. This patch reverting that piece allows me to boot again.
There are two requirements:
1. Make sure not to use too much memory for "old" machines. Otherwise you won't be able to boot a compressed kernel on e.g. a 16MB machine.
If you move the compressed data behind where the kernel would self-extract itself, you double the amount of memory required. I think with the patch below I won't be able to boot my 715/64 any longer.
2. Old palo versions had a bug which prevented the ELF loader to load sections above 16MB. So, one needs to keep everything thin in the low memory without extracting over oneself.
3. There might have been other reasons too, but currently I don't remember :-)
I believe the the patch I sent for arch/parisc/boot/compressed/vmlinux.lds.S:
+ /* bootloader code and data starts at least behind area of extracted kernel */
+ . = MAX(ABSOLUTE(.), (SZ_end - SZparisc_kernel_start + KERNEL_BINARY_TEXT_START));
keeps everything bootable (on low-memory-machines and with palo ELF bootloader bug).
Helge
Quoted 32 lines
arch/parisc/boot/compressed/vmlinux.lds.S +6
-6@@ -42,12 +42,6 @@ SECTIONS #endif _startcode_end = .; - /* vmlinux.bin.gz is here */ - . = ALIGN(8); - .rodata.compressed : { - *(.rodata.compressed) - } - /* bootloader code and data starts behind area of extracted kernel */ . = (SZ_end - SZparisc_kernel_start + KERNEL_BINARY_TEXT_START);@@ -73,6 +67,12 @@ SECTIONS *(.rodata.*) _erodata = . ; } + /* vmlinux.bin.gz is here */ + . = ALIGN(8); + .rodata.compressed : { + *(.rodata.compressed) + } + . = ALIGN(8); .bss : { _bss = . ;