diff options
author | Simon Glass | 2021-01-24 10:06:05 -0700 |
---|---|---|
committer | Bin Meng | 2021-02-01 15:29:02 +0800 |
commit | 37c664e82534ad84d2f7c06ce7d6459fa6bd24ae (patch) | |
tree | 1106ec7b8ec5c8c19117fc79291a9d8b7c98ee43 | |
parent | 0b2bedbc6d02d9b9563b40a2b7e39fec6e9bf07c (diff) |
x86: Make sure the SPL image ends on a suitable boundary
The part of U-Boot that actually ends up in u-boot-nodtb.bin is not built
with any particular alignment. It ends at the start of the BSS section.
The BSS section selects its own alignment, which may larger.
This means that there can be a gap of a few bytes between the image
ending and BSS starting.
Since u-boot.bin is build by joining u-boot-nodtb.bin and u-boot.dtb (with
perhaps some padding for BSS), the expected result is not obtained. U-Boot
uses the end of BSS to find the devicetree, so this means that it cannot
be found.
Add 32-byte alignment of BSS so that the image size is correct and
appending the devicetree will place it at the end of BSS.
Example SPL output without this patch:
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000142a1 fef40000 fef40000 00001000 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .u_boot_list 000014a4 fef542a8 fef542a8 000152a8 2**3
CONTENTS, ALLOC, LOAD, RELOC, DATA
2 .rodata 0000599c fef55760 fef55760 00016760 2**5
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
3 .data 00000970 fef5b100 fef5b100 0001c100 2**5
CONTENTS, ALLOC, LOAD, RELOC, DATA
4 .binman_sym_table 00000020 fef5ba70 fef5ba70 0001ca70 2**2
CONTENTS, ALLOC, LOAD, DATA
5 .bss 00000060 fef5baa0 fef5baa0 00000000 2**5
ALLOC
You can see that .bss is aligned to 2**5 (32 bytes). This is because of
the mallinfo struct in dlmalloc.c:
17 .bss.current_mallinfo 00000028 00000000 00000000 000004c0 2**5
ALLOC
In this case the size of u-boot-spl-nodtb.bin is 0x1ba90. This matches up
with the _image_binary_end symbol:
fef5ba90 g .binman_sym_table 00000000 _image_binary_end
But BSS starts 16 bytes later, at 0xfef5baa0, due to the 32-byte
alignment. So we must align _image_binary_end to a 32-byte boundary. This
forces the binary size to be 0x1baa0, i.e. ending at the start of bss, as
expected.
Note that gcc reports __BIGGEST_ALIGNMENT__ of 16 on this build, even
though it generates an object file with a member that requests 32-byte
alignment.
The current_mallinfo struct is 40 bytes in size. Increasing the struct to
68 bytes (i.e. just above a 64-byte boundary) does not cause the alignment
to go above 32 bytes. So it seems that 32 bytes is the maximum alignment
at present.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
[bmeng: add more details in the commit message to help people understand]
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
-rw-r--r-- | arch/x86/cpu/u-boot-spl.lds | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/arch/x86/cpu/u-boot-spl.lds b/arch/x86/cpu/u-boot-spl.lds index e6c22895b35..ead4f380e74 100644 --- a/arch/x86/cpu/u-boot-spl.lds +++ b/arch/x86/cpu/u-boot-spl.lds @@ -43,6 +43,16 @@ SECTIONS __binman_sym_start = .; KEEP(*(SORT(.binman_sym*))); __binman_sym_end = .; + + /* + * Force 32-byte alignment so that it lines up with the start of + * bss, which may have up to 32-byte alignment. This ensures + * that the end of the .bin file matches up with + * _image_binary_end or __bss_end - see board_fdt_blob_setup(). + * The alignment of BSS depends on what is in it, so can range + * from 4 to 32 bytes. + */ + . = ALIGN(32); } _image_binary_end = .; |