fdt: Fix bug in size calculation in fdt_resize() with initrd use
PATCH 1/1 fdt: Fix bug in size calculation in fdt_resize() with initrd use
From: Feng Wang <[email protected]>
Original bug description from Feng (fdt_resize() bug caused "WARNING:
could not set linux, initrd-start FDT_ERR_NOSPACE."):
What I got is an error: "WARNING: could not set linux,initrd-start FDT_ERR_NOSPACE." after loading Device Tree blob. This in turn caused linux to miss init part.
After some digging, I found out the reason for this error, it is caused by fdt_resize().
FDT blob got resized after filling in all board specific information of PowerPC. (in boot_body_linux()). It reduced blob size with only extra space for two fdt_reserve_entry, one for fdt itself, and one for initrd. Then it's aligned to a 0x1000 page boundary. However, later in fdt_initrd(), it could add two more properties, initrd-start AND initrd-end, each one needs at least two fdt_reserve_entry sizes done by _fdt_add_property() (name and value). Thus, the two fdt_reserve_entry extra space is not sufficient.
So for some specific fdt size which is just under the page boundary after resizing, this will cause an error of FDT_ERR_NOSPACE in fdt_initrd() when setting those two properties, and failed to pass initrd information to linux.
My fix is in fdt_resize(), leave at least 4 fdt_reserve_entry for initrd. So instead of 2*sizeof(struct fdt_reserve_entry) for actual_totalsize, use 5*sizeof(struc fdt_reserve_entry).
Stefan: I got this same error on katmai, when trying to boot with initrd (run flash_self). This patch fixes this issue.
--- common/fdt_support.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
common/fdt_support.c +4 -3
@@ -498,11 +498,12 @@ int fdt_resize(void *blob)/* * Calculate the actual size of the fdt -* plus the size needed for two fdt_add_mem_rsv, one -* for the fdt itself and one for a possible initrd +* plus the size needed for 5 fdt_add_mem_rsv, one +* for the fdt itself and 4 for a possible initrd +* ((initrd-start + initrd-end) * 2 (name & value)) */ actualsize =fdt_off_dt_strings (blob) + -fdt_size_dt_strings (blob) +2 *sizeof (struct fdt_reserve_entry ); +fdt_size_dt_strings (blob) +5 *sizeof (struct fdt_reserve_entry );/* Make it so the fdt ends on a page boundary */ actualsize =ALIGN (actualsize + ((uint )blob &0xfff ),0x1000 );
Signature · 1 line
1.7.2.1
PATCH 1/1 fdt: Fix bug in size calculation in fdt_resize() with initrd use
Quoted 30 lines · Stefan Roese
From: Feng Wang<[email protected]>
Original bug description from Feng (
fdt_resize()bug caused "WARNING:
could not set linux, initrd-startFDT_ERR_NOSPACE."):What I got is an error: "WARNING: could not set linux,initrd-start
FDT_ERR_NOSPACE." after loading Device Tree blob. This in turn caused linux to miss init part.After some digging, I found out the reason for this error, it is caused by
fdt_resize().FDT blob got resized after filling in all board specific information of PowerPC. (in
boot_body_linux()). It reduced blob size with only extra space for twofdt_reserve_entry, one for fdt itself, and one for initrd. Then it's aligned to a0x1000page boundary. However, later infdt_initrd(), it could add two more properties, initrd-start AND initrd-end, each one needs at least twofdt_reserve_entrysizes done by_fdt_add_property()(name and value). Thus, the twofdt_reserve_entryextra space is not sufficient.So for some specific fdt size which is just under the page boundary after resizing, this will cause an error of
FDT_ERR_NOSPACEinfdt_initrd()when setting those two properties, and failed to pass initrd information to linux.My fix is in
fdt_resize(), leave at least 4fdt_reserve_entryfor initrd. So instead of 2*sizeof(structfdt_reserve_entry) foractual_totalsize, use 5*sizeof(strucfdt_reserve_entry).
Quoted 6 lines
Stefan: I got this same error on katmai, when trying to boot with initrd (run
flash_self). This patch fixes this issue.Signed-off-by Feng Wang<[email protected]>Tested-by Stefan Roese<[email protected]>Cc Jerry Van Baren<[email protected]>
Stefan or Wolfgang, can you apply this?
Thanks,
gvb
Quoted 24 lines
--- common/fdt_support.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)common/fdt_support.c +4
-3@@ -498,11 +498,12 @@ int fdt_resize(void *blob)/* * Calculate the actual size of the fdt -* plus the size needed for two fdt_add_mem_rsv, one -* for the fdt itself and one for a possible initrd +* plus the size needed for 5 fdt_add_mem_rsv, one +* for the fdt itself and 4 for a possible initrd +* ((initrd-start + initrd-end) * 2 (name& value)) */ actualsize =fdt_off_dt_strings (blob) + -fdt_size_dt_strings (blob) +2 *sizeof (struct fdt_reserve_entry ); +fdt_size_dt_strings (blob) +5 *sizeof (struct fdt_reserve_entry );/* Make it so the fdt ends on a page boundary */ actualsize =ALIGN (actualsize + ((uint )blob&0xfff ),0x1000 );
PATCH 1/1 fdt: Fix bug in size calculation in fdt_resize() with initrd use
Dear Jerry Van Baren,
Quoted 4 lines · In message <[email protected]> you wrote:
Acked-by Gerald Van Baren <[email protected]>Stefan or Wolfgang, can you apply this?
Done, thanks.
Best regards,
Wolfgang Denk
Signature · 9 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
I've been programming for (35-9=) 24 years myself, and I find the
best way to learn a new language is to *read* every example snippet I
can find, with a reference book close by. Eventually, the *rhythm* of
the language starts pounding in my head... and my fluency is close at
hand. That's how I learned Perl, and now I'm one of the drummers. :-)
-- Randal L. Schwartz in <[email protected]>Wolfgang Denk
AppliedPATCH 1/1 fdt: Fix bug in size calculation in fdt_resize() with initrd use
In reply to Stefan RoeseDear Stefan Roese,
Quoted 33 lines · In message <[email protected]> you wrote:
From: Feng Wang <[email protected]>
Original bug description from Feng (
fdt_resize()bug caused "WARNING:
could not set linux, initrd-startFDT_ERR_NOSPACE."):What I got is an error: "WARNING: could not set linux,initrd-start
FDT_ERR_NOSPACE." after loading Device Tree blob. This in turn caused linux to miss init part.After some digging, I found out the reason for this error, it is caused by
fdt_resize().FDT blob got resized after filling in all board specific information of PowerPC. (in
boot_body_linux()). It reduced blob size with only extra space for twofdt_reserve_entry, one for fdt itself, and one for initrd. Then it's aligned to a0x1000page boundary. However, later infdt_initrd(), it could add two more properties, initrd-start AND initrd-end, each one needs at least twofdt_reserve_entrysizes done by_fdt_add_property()(name and value). Thus, the twofdt_reserve_entryextra space is not sufficient.So for some specific fdt size which is just under the page boundary after resizing, this will cause an error of
FDT_ERR_NOSPACEinfdt_initrd()when setting those two properties, and failed to pass initrd information to linux.My fix is in
fdt_resize(), leave at least 4fdt_reserve_entryfor initrd. So instead of 2*sizeof(structfdt_reserve_entry) foractual_totalsize, use 5*sizeof(strucfdt_reserve_entry).Stefan: I got this same error on katmai, when trying to boot with initrd (run
flash_self). This patch fixes this issue.
Quoted 6 lines
Signed-off-by Feng Wang <[email protected]>Tested-by Stefan Roese <[email protected]>Cc Jerry Van Baren <[email protected]>--- common/fdt_support.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
Applied, thanks.
Best regards,
Wolfgang Denk
Signature · 5 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de Wisdom is one of the few things that looks bigger the further away it is. - Terry Pratchett, _Witches Abroad_