diff mbox series

[LEDE-DEV] brcm47xx: relocate loader to higher address

Message ID 20171008150614.28695-1-hauke@hauke-m.de
State Accepted
Delegated to: Hauke Mehrtens
Headers show
Series [LEDE-DEV] brcm47xx: relocate loader to higher address | expand

Commit Message

Hauke Mehrtens Oct. 8, 2017, 3:06 p.m. UTC
The boot process on a WRT54GL works the following way:
1. CFE gets loaded by the boot rom from flash
2. CFE loads the loader from the flash and gzip uncompresses it
3. CFE starts the loader
4. The loader stores the FW arguments and relocates itself to
   BZ_TEXT_START (now 0x80600000)
5. The loader reads the Linux image from flash
6. The loader lzma decompresses the Linux image to LOADADDR (0x80001000)
7. The loader executes the uncompress Linux image at LOADADDR

The BZ_TEXT_START was set to 0x80400000 before. When the kernel gets
uncompressed and is bigger than BZ_TEXT_START - LOADADDR it overwrote
the loader which was currently uncompressing it and made the board
crash. Increase the BZ_TEXT_START my 2 MB to have more space for the
kernel. Even on 16MB RAM devices the memory goes till 0x80FFFFFF so this
should not be a problem.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 target/linux/brcm47xx/image/lzma-loader/src/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Hauke Mehrtens Oct. 8, 2017, 3:29 p.m. UTC | #1
On 10/08/2017 05:06 PM, Hauke Mehrtens wrote:
> The boot process on a WRT54GL works the following way:
> 1. CFE gets loaded by the boot rom from flash
> 2. CFE loads the loader from the flash and gzip uncompresses it
> 3. CFE starts the loader
> 4. The loader stores the FW arguments and relocates itself to
>    BZ_TEXT_START (now 0x80600000)
> 5. The loader reads the Linux image from flash
> 6. The loader lzma decompresses the Linux image to LOADADDR (0x80001000)
> 7. The loader executes the uncompress Linux image at LOADADDR
> 
> The BZ_TEXT_START was set to 0x80400000 before. When the kernel gets
> uncompressed and is bigger than BZ_TEXT_START - LOADADDR it overwrote
> the loader which was currently uncompressing it and made the board
> crash. Increase the BZ_TEXT_START my 2 MB to have more space for the
> kernel. Even on 16MB RAM devices the memory goes till 0x80FFFFFF so this
> should not be a problem.
> 
> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
> ---
>  target/linux/brcm47xx/image/lzma-loader/src/Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target/linux/brcm47xx/image/lzma-loader/src/Makefile b/target/linux/brcm47xx/image/lzma-loader/src/Makefile
> index 3320e565d0..444039c558 100644
> --- a/target/linux/brcm47xx/image/lzma-loader/src/Makefile
> +++ b/target/linux/brcm47xx/image/lzma-loader/src/Makefile
> @@ -18,7 +18,7 @@
>  #
>  
>  TEXT_START	:= 0x80001000
> -BZ_TEXT_START	:= 0x80400000
> +BZ_TEXT_START	:= 0x80600000
>  
>  OBJCOPY		:= $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S


This makes my WRT54GS boot a kernel 4.9 with CONFIG_KALLSYMS. Without
this patch it is not booting up.

The FW arguments are more or less useless, I got these in Linux from CFE
forwarded by the loader:
fw_arg0: 0x803401a0, fw_arg1: 0x0, fw_arg2: 0x803029c8, fw_arg3: 0x43464531

They are pointing somewhere into CFE:

Total memory used by CFE:  0x80300000 - 0x8043DF30 (1302320)
Initialized Data:          0x803381A0 - 0x8033A550 (9136)
BSS Area:                  0x8033A550 - 0x8033BF30 (6624)
Local Heap:                0x8033BF30 - 0x8043BF30 (1048576)
Stack Area:                0x8043BF30 - 0x8043DF30 (8192)
Text (code) segment:       0x80300000 - 0x803381A0 (229792)
Boot area (physical):      0x0043E000 - 0x0047E000
Relocation Factor:         I:00000000 - D:00000000

See section 8.2.3 "Registers passed to boot loaders" for details on what
these arguments mean:
http://melbourne.wireless.org.au/files/wrt54/cfe.pdf

Our image does not use them anyway so this is also save.


Hauke
Florian Fainelli Oct. 8, 2017, 4:43 p.m. UTC | #2
On 10/08/2017 08:29 AM, Hauke Mehrtens wrote:
> On 10/08/2017 05:06 PM, Hauke Mehrtens wrote:
>> The boot process on a WRT54GL works the following way:
>> 1. CFE gets loaded by the boot rom from flash
>> 2. CFE loads the loader from the flash and gzip uncompresses it
>> 3. CFE starts the loader
>> 4. The loader stores the FW arguments and relocates itself to
>>    BZ_TEXT_START (now 0x80600000)
>> 5. The loader reads the Linux image from flash
>> 6. The loader lzma decompresses the Linux image to LOADADDR (0x80001000)
>> 7. The loader executes the uncompress Linux image at LOADADDR
>>
>> The BZ_TEXT_START was set to 0x80400000 before. When the kernel gets
>> uncompressed and is bigger than BZ_TEXT_START - LOADADDR it overwrote
>> the loader which was currently uncompressing it and made the board
>> crash. Increase the BZ_TEXT_START my 2 MB to have more space for the
>> kernel. Even on 16MB RAM devices the memory goes till 0x80FFFFFF so this
>> should not be a problem.
>>
>> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
>> ---
>>  target/linux/brcm47xx/image/lzma-loader/src/Makefile | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/target/linux/brcm47xx/image/lzma-loader/src/Makefile b/target/linux/brcm47xx/image/lzma-loader/src/Makefile
>> index 3320e565d0..444039c558 100644
>> --- a/target/linux/brcm47xx/image/lzma-loader/src/Makefile
>> +++ b/target/linux/brcm47xx/image/lzma-loader/src/Makefile
>> @@ -18,7 +18,7 @@
>>  #
>>  
>>  TEXT_START	:= 0x80001000
>> -BZ_TEXT_START	:= 0x80400000
>> +BZ_TEXT_START	:= 0x80600000
>>  
>>  OBJCOPY		:= $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S
> 
> 
> This makes my WRT54GS boot a kernel 4.9 with CONFIG_KALLSYMS. Without
> this patch it is not booting up.
> 
> The FW arguments are more or less useless, I got these in Linux from CFE
> forwarded by the loader:
> fw_arg0: 0x803401a0, fw_arg1: 0x0, fw_arg2: 0x803029c8, fw_arg3: 0x43464531

Yes, those do not really matter on brcm47xx since the CFE environment
and all associated services (cfe_getenv, cfe_write) are not available
anyway...

> 
> They are pointing somewhere into CFE:
> 
> Total memory used by CFE:  0x80300000 - 0x8043DF30 (1302320)
> Initialized Data:          0x803381A0 - 0x8033A550 (9136)
> BSS Area:                  0x8033A550 - 0x8033BF30 (6624)
> Local Heap:                0x8033BF30 - 0x8043BF30 (1048576)
> Stack Area:                0x8043BF30 - 0x8043DF30 (8192)
> Text (code) segment:       0x80300000 - 0x803381A0 (229792)
> Boot area (physical):      0x0043E000 - 0x0047E000
> Relocation Factor:         I:00000000 - D:00000000
> 
> See section 8.2.3 "Registers passed to boot loaders" for details on what
> these arguments mean:
> http://melbourne.wireless.org.au/files/wrt54/cfe.pdf
> 
> Our image does not use them anyway so this is also save.
> 
> 
> Hauke
> 
> _______________________________________________
> Lede-dev mailing list
> Lede-dev@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/lede-dev
>
p.wassi@gmx.at Oct. 8, 2017, 7:25 p.m. UTC | #3
Hi Hauke,

> When the kernel gets uncompressed and is bigger than
> BZ_TEXT_START - LOADADDR it overwrote the loader which was currently uncompressing
> it and made the board crash.

Currently, BZ_TEXT_START - LOADADDR = 0x80400000 - 0x80001000 = 3FF000 = 4190208 bytes
Today's trunk brcm47xx kernel is 4069124 bytes. So increasing the address is actually
just a preventive countermeasure for future kernels.(?)
The WRT54GL CFEs seem to use a memory area about half the size of your WRT54GS'
So I guess, the actual problem for the WRT54GL was that the stack was smashed?

Once my compiling machine finishes your ar71xx with kernel 4.9, I'll test this one here :-)

Happy to see, that this problem seems to be solved.

Regards,
P. Wassi
Arjen de Korte Oct. 8, 2017, 7:33 p.m. UTC | #4
Citeren p.wassi@gmx.at:

> Hi Hauke,
>
>> When the kernel gets uncompressed and is bigger than
>> BZ_TEXT_START - LOADADDR it overwrote the loader which was  
>> currently uncompressing
>> it and made the board crash.
>
> Currently, BZ_TEXT_START - LOADADDR = 0x80400000 - 0x80001000 =  
> 3FF000 = 4190208 bytes
> Today's trunk brcm47xx kernel is 4069124 bytes. So increasing the  
> address is actually
> just a preventive countermeasure for future kernels.(?)

The change from 4.4 to 4.9, will add approximately 500 kbytes to the  
kernel (assuming the increase will be similar as for ar71xx), so this  
won't fit anymore. So this preventive measure may be needed sooner  
than you think.

> The WRT54GL CFEs seem to use a memory area about half the size of  
> your WRT54GS'
> So I guess, the actual problem for the WRT54GL was that the stack  
> was smashed?
>
> Once my compiling machine finishes your ar71xx with kernel 4.9, I'll  
> test this one here :-)
>
> Happy to see, that this problem seems to be solved.
>
> Regards,
> P. Wassi
>
> _______________________________________________
> Lede-dev mailing list
> Lede-dev@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/lede-dev
Hauke Mehrtens Oct. 8, 2017, 7:35 p.m. UTC | #5
On 10/08/2017 09:25 PM, p.wassi@gmx.at wrote:
> Hi Hauke,
> 
>> When the kernel gets uncompressed and is bigger than
>> BZ_TEXT_START - LOADADDR it overwrote the loader which was currently uncompressing
>> it and made the board crash.
> 
> Currently, BZ_TEXT_START - LOADADDR = 0x80400000 - 0x80001000 = 3FF000 = 4190208 bytes
> Today's trunk brcm47xx kernel is 4069124 bytes. So increasing the address is actually
> just a preventive countermeasure for future kernels.(?)
> The WRT54GL CFEs seem to use a memory area about half the size of your WRT54GS'
> So I guess, the actual problem for the WRT54GL was that the stack was smashed?
> 
> Once my compiling machine finishes your ar71xx with kernel 4.9, I'll test this one here :-)
> 
> Happy to see, that this problem seems to be solved.

Hi,

The stack was not a problem with my kernel, I just added it to prevent
later problems, now I debugged this, I do not want to debug this again
in 2 years.

My vmlinux kernel file is 4277380 bytes, so bigger than the available
size you calculated. The stack starts at 0x8043BF30 so there are 4435760
bytes available till my image would overwrite the stack.

It does not matter where CFE is located as we do not need it any more
after the loader started, we will never jump back into it and use the
memory region used for CFE later also for Linux.

With both patches there is now almost 6 MB space available.

Hauke
diff mbox series

Patch

diff --git a/target/linux/brcm47xx/image/lzma-loader/src/Makefile b/target/linux/brcm47xx/image/lzma-loader/src/Makefile
index 3320e565d0..444039c558 100644
--- a/target/linux/brcm47xx/image/lzma-loader/src/Makefile
+++ b/target/linux/brcm47xx/image/lzma-loader/src/Makefile
@@ -18,7 +18,7 @@ 
 #
 
 TEXT_START	:= 0x80001000
-BZ_TEXT_START	:= 0x80400000
+BZ_TEXT_START	:= 0x80600000
 
 OBJCOPY		:= $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S