Skip to content

arm: linker.ld: move bss section to ram end #21747

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 4, 2020

Conversation

lgl88911
Copy link
Contributor

@lgl88911 lgl88911 commented Jan 7, 2020

fix bss section be copy to binary

Signed-off-by: Frank Li lgl88911@163.com

@zephyrbot zephyrbot added the area: API Changes to public APIs label Jan 7, 2020
Copy link
Member

@stephanosio stephanosio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide an explanation as to why this is necessary in the commit message.

@ioannisg
Copy link
Member

ioannisg commented Jan 7, 2020

Please provide an explanation as to why this is necessary in the commit message.

agreed. What problem are you trying to address @lgl88911 ?

@lgl88911
Copy link
Contributor Author

lgl88911 commented Jan 7, 2020

@stephanosio @ioannisg Thanks for your review
When I hope load code to ram and run it, I compiling with non-xip(CONFIG_XIP=n), all sections will be placed in the ram. If NOBITS section is not placed at the end of the ram, these sections will be placed to binary file. eg: bss, noinit
You can reduce by using mimxrt1050_evk, follow below step:

  1. Add CONFIG_XIP=n to mimxrt1050_evk_defconfig
  2. build it with any sample
  3. check zephyr.bin size
  4. add large global variables to same sample and use these global variables to make sure it is not removed for optimization
  5. build it again, you will find the size of zephyr.bin has grown

@stephanosio
Copy link
Member

stephanosio commented Jan 7, 2020

While I can confirm that behaviour, something is wrong here ...

/opt/zephyr-sdk/arm-zephyr-eabi/bin/arm-zephyr-eabi-objcopy -S --gap-fill 0xff --output-target=binary --remove-section=.comment --remove-section=COMMON --remove-section=.eh_frame zephyr.elf zephyr.bin

CONFIG_XIP=y

-rwxrwxr-x 1 stephanos stephanos 21464 Jan  8 01:24 zephyr/zephyr.bin

CONFIG_XIP=n

-rwxrwxr-x 1 stephanos stephanos 90676 Jan  8 01:25 zephyr/zephyr.bin

https://gist.github.com/stephanosio/a7f5cd34c7480bacb5254d4760b54805

The bss and noinit sections are marked NOBITS and the objcopy should not be putting them in the bin file (regardless of how the sections are ordered). Maybe I am missing something .. I will look into this tomorrow.

EDIT: This is the correct behaviour because the LMA for the non-XIP image is the same as the VMA.

@stephanosio stephanosio added area: ARM ARM (32-bit) Architecture area: Linker Scripts and removed area: API Changes to public APIs labels Jan 7, 2020
@stephanosio
Copy link
Member

stephanosio commented Jan 9, 2020

If NOBITS section is not placed at the end of the ram, these sections will be placed to binary file. eg: bss, noinit

To be exact, it is not that the NOBITS sections are being "placed" into the output binary file; but rather, the gap between the last PROGBITS section before a NOBITS section and the next adjacent PROGBITS section must be filled before placing the data PROGBITS sections (note that LMA equals VMA in non-XIP images).

This in itself is not a bug (it does not break anything), but rather an inefficiency that comes with using the raw binary format.

Copy link
Member

@stephanosio stephanosio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not against this change because it does help reduce the output 'bin' file size, which can be useful if you must use the 'bin' image (e.g. booting from a 'bin' file in an SD card).

However, this seems to be breaking some existing platforms and they will need to be fixed before this PR can be approved.

@stephanosio stephanosio self-requested a review January 9, 2020 08:29
@lgl88911
Copy link
Contributor Author

lgl88911 commented Jan 9, 2020

I am not against this change because it does help reduce the output 'bin' file size, which can be useful if you must use the 'bin' image (e.g. booting from a 'bin' file in an SD card).

However, this seems to be breaking some existing platforms and they will need to be fixed before this PR can be approved.

Thanks for your check.

Yes, I hope load bin from SD card to sdram, Decreasing bin size can help improve download and load speeds。

What kind of problems this change will affect those existing platforms?

@lgl88911
Copy link
Contributor Author

I am not against this change because it does help reduce the output 'bin' file size, which can be useful if you must use the 'bin' image (e.g. booting from a 'bin' file in an SD card).
However, this seems to be breaking some existing platforms and they will need to be fixed before this PR can be approved.

Thanks for your check.

Yes, I hope load bin from SD card to sdram, Decreasing bin size can help improve download and load speeds。

What kind of problems this change will affect those existing platforms?

I know "EXISTING PLATFORMS" problem is :
some object address in zephyr_prebuilt.elf diff to zephyr.elf. I'm trying to find the reason

@zephyrbot zephyrbot added the area: API Changes to public APIs label Feb 22, 2020
@lgl88911
Copy link
Contributor Author

@stephanosio Shippable check pass, Could you help review again,Thanks

Copy link
Member

@stephanosio stephanosio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, in summary, we cannot have the bss section as the last RAM section when USERSPACE is enabled; I wonder why that is.

IMO, we should figure out why the userspace tests fault when the bss section is placed as the last section in the RAM and provide a more fundamental fix, unless there is a technical reason as to why that is not possible and/or feasible.

I don't have time to look into it right now; if it does not get resolved in time, I will eventually come back to it.

@lgl88911 lgl88911 force-pushed the fix_ld_bss branch 2 times, most recently from 5bd7a02 to 324f1bd Compare March 6, 2020 13:29
@lgl88911
Copy link
Contributor Author

lgl88911 commented Mar 6, 2020

So, in summary, we cannot have the bss section as the last RAM section when USERSPACE is enabled; I wonder why that is.

IMO, we should figure out why the userspace tests fault when the bss section is placed as the last section in the RAM and provide a more fundamental fix, unless there is a technical reason as to why that is not possible and/or feasible.

I don't have time to look into it right now; if it does not get resolved in time, I will eventually come back to it.

When bss moves to the end, the bss section will be after the kobject_data section.
Uninitialized kernel objects are placed in bss.
When userspace is enabled, there is no data in kobject_data during the first stage of linking(prelink), so the kernel object address is small.
Before the second stage of linking(finial), the kernel objects in prelink are scanned and their addresses are placed in kobject_data.
At this time, kobject_data becomes larger, bss be shifted backwards , cause the kernel object address in the final link result will become larger, which will be inconsistent with that in kobject_data.
If the position of bss is before kobject_data, there will not be this problem.
The appropriate method may be to reserve space for kobject_data during prelink, but the related process is relatively unfamiliar to me, so it is difficult to modify.

@andrewboie
Copy link
Contributor

The appropriate method may be to reserve space for kobject_data during prelink, but the related process is relatively unfamiliar to me, so it is difficult to modify.

The relevant linker snippet is include/linker/kobject.ld.

I don't have a good suggestion to fix this at the moment. The problem is that the size of this area is a linear function of the number of kernel objects in the binary, there isn't a good way to predict how large it is without going through the full process of building.

@lgl88911
Copy link
Contributor Author

lgl88911 commented Mar 7, 2020

The appropriate method may be to reserve space for kobject_data during prelink, but the related process is relatively unfamiliar to me, so it is difficult to modify.

The relevant linker snippet is include/linker/kobject.ld.

I don't have a good suggestion to fix this at the moment. The problem is that the size of this area is a linear function of the number of kernel objects in the binary, there isn't a good way to predict how large it is without going through the full process of building.

Indeed, the inability to predict kernel object data is a problem. Maybe reserve enough space, or add a third link, use the final elf to generate kobject_hash.c again, and relink the new elf.
But both methods are "not pretty", so my idea is to make this scheme work on non-userspace first.

@stephanosio
Copy link
Member

Indeed, the inability to predict kernel object data is a problem. Maybe reserve enough space, or add a third link, use the final elf to generate kobject_hash.c again, and relink the new elf.
But both methods are "not pretty", so my idea is to make this scheme work on non-userspace first.

Thanks for the explanation. It looks like that will require a major overhaul, which should probably be a separate PR.

Copy link
Member

@stephanosio stephanosio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving for now, noting that it is not feasible for userspace to have the bss as the last section in the RAM.

fix bss section be copy to binary.

When compiling with non-xip.
All sections will be placed in the ram.
If NOBITS section isn't placed at the end of ram,
objcopy will placed these section to binary file.

The modify only for no-userspace.
In userspace the section will be adjust,
kobject_data size increase,
the bss be shifted, the content of kobject_data
will no mactch to kernel obj of bss.

Signed-off-by: Frank Li <lgl88911@163.com>
@lgl88911
Copy link
Contributor Author

lgl88911 commented Apr 3, 2020

@galak @MaureenHelm @andrewboie @ioannisg This PR has been pending for a long time, can you help review if need to make other changes?

@carlescufi
Copy link
Member

carlescufi commented Apr 22, 2020

@galak @MaureenHelm @andrewboie @ioannisg This PR has been pending for a long time, can you help review if need to make other changes?

Yep, this should be followed-up. @lgl88911 if you get no response before tomorrow I can suggest you add it to the dev-review meeting and join if you are able to. But I think this mostly needs an approval from @ioannisg.

Copy link
Contributor

@andrewboie andrewboie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine with this for now, but I'm going to open a GH enhancement to investigate this more deeply, such that if user mode is enabled on a non-XIP system the binary isn't inflated by NOBITS sections.

@lgl88911
Copy link
Contributor Author

@carlescufi Is there any document explaining how to proceed with "add item to the dev-review meeting", I have never done this. Thanks!

@ioannisg ioannisg added the dev-review To be discussed in dev-review meeting label Apr 24, 2020
@galak galak removed the dev-review To be discussed in dev-review meeting label Apr 30, 2020
@carlescufi carlescufi merged commit a298c89 into zephyrproject-rtos:master May 4, 2020
gramsay0 added a commit to gramsay0/zephyr that referenced this pull request Jan 9, 2025
…mode

Userspace originally required bss to precede kobject_data, as
kobject_data size was not known until the final linking stage (zephyrproject-rtos#21747).

zephyrproject-rtos#33687 reserved space for kobject_data, allowing bss to now be after
kobject_data.

Placing bss/noinit at the end of the linker script reduces the size
of a "zephyr.bin" file, as the NOLOAD sections can be excluded. It
also keeps the code common between kernel/user mode

Signed-off-by: Grant Ramsay <gramsay@enphaseenergy.com>
kartben pushed a commit that referenced this pull request Feb 6, 2025
…mode

Userspace originally required bss to precede kobject_data, as
kobject_data size was not known until the final linking stage (#21747).

#33687 reserved space for kobject_data, allowing bss to now be after
kobject_data.

Placing bss/noinit at the end of the linker script reduces the size
of a "zephyr.bin" file, as the NOLOAD sections can be excluded. It
also keeps the code common between kernel/user mode

Signed-off-by: Grant Ramsay <gramsay@enphaseenergy.com>
RuibinChang pushed a commit to RuibinChang/zephyr that referenced this pull request Mar 4, 2025
…mode

Userspace originally required bss to precede kobject_data, as
kobject_data size was not known until the final linking stage (zephyrproject-rtos#21747).

zephyrproject-rtos#33687 reserved space for kobject_data, allowing bss to now be after
kobject_data.

Placing bss/noinit at the end of the linker script reduces the size
of a "zephyr.bin" file, as the NOLOAD sections can be excluded. It
also keeps the code common between kernel/user mode

(cherry picked from commit f9d69fc)

Original-Signed-off-by: Grant Ramsay <gramsay@enphaseenergy.com>
GitOrigin-RevId: f9d69fc
Cr-Build-Id: 8723641050355720609
Cr-Build-Url: https://cr-buildbucket.appspot.com/build/8723641050355720609
Copybot-Job-Name: zephyr-main-copybot-downstream
Change-Id: I96b5fbac36ff22a501f30c08c1b4ca42a0425fec
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/zephyr/+/6241424
Commit-Queue: Jeremy Bettis <jbettis@chromium.org>
Tested-by: Jeremy Bettis <jbettis@chromium.org>
Tested-by: ChromeOS Prod (Robot) <chromeos-ci-prod@chromeos-bot.iam.gserviceaccount.com>
Reviewed-by: Jonathon Murphy <jpmurphy@google.com>
Reviewed-by: Jeremy Bettis <jbettis@chromium.org>
Bot-Commit: ChromeOS Prod (Robot) <chromeos-ci-prod@chromeos-bot.iam.gserviceaccount.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: API Changes to public APIs area: ARM ARM (32-bit) Architecture area: Linker Scripts
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants