



Minimum executable image size
by werne on Jan 27, 2014 |
werne
Posts: 3 Joined: Jan 22, 2014 Last seen: Jan 31, 2014 |
||
I'd like to get an idea of the minimum executable image size generated by the bare-metal or1k-* toolchain. I built a newlib-backed gcc cross compiler from the development tree by following the instructions on the wiki. I wrote a trivial c program:
int main() { I compiled it with -Os and extracted the image using: or1k-elf-objcopy -O binary test test.bin The output binary image is about 22kB. I have extensive experience working with embedded PowerPC and Microblaze processors in Xilinx systems, and a similar program on those platforms is at least 3x smaller. Is this expected? Is there anything I can do to shrink the image? |
RE: Minimum executable image size
by olof on Jan 27, 2014 |
olof
Posts: 218 Joined: Feb 10, 2010 Last seen: Dec 17, 2018 |
||
Hi Werne,
There is a known issue with the toolchain that always brings in malloc and other functions even when they are not used. This has been noted in http://bugzilla.opencores.org/show_bug.cgi?id=45 What makes this more interesting is that we just had a discussion about this on IRC and right until you sent this post, we thought that it had actually been fixed. The relevant parts of the discussion can be read here http://juliusbaxter.net/openrisc-irc/%23openrisc.2014-01-25.log.html and http://juliusbaxter.net/openrisc-irc/%23openrisc.2014-01-27.log.html Hope that we can shed some more light on this issue during the coming days. Please join us at #openrisc on irc.freenode.net if you want to participate in the discussions Best Regards, Olof |
RE: Minimum executable image size
by stekern on Jan 27, 2014 |
stekern
Posts: 84 Joined: Apr 28, 2009 Last seen: Nov 10, 2016 |
||
That's not related, and the issue described in the bug report seems to not be present in the or1k toolchain anyway.
(One of) the reason(s) why a small program like that is much larger on or1k than for example Microblaze and PowerPC is due to a deficiency how the exception vectors are designed. On or1k, each exception vector takes 0x100 bytes, and there are 32 different exception vectors. So, 8192 bytes are "wasted" on the exception vectors. Another reason might be that our libgloss board support code that is used during startup is a bit more bloated than the above mentioned architectures. Stefan |
RE: Minimum executable image size
by werne on Jan 27, 2014 |
werne
Posts: 3 Joined: Jan 22, 2014 Last seen: Jan 31, 2014 |
||
Thanks for the quick reply. I'll try to drop in on IRC.
I ran nm on my executable, and both malloc and free are listed as weak symbols with no value, so they actually haven't been linked in (I checked with objdump to verify, and they're definitely not in the output). I think you guys have that issue fixed. I also just ran size on it, and the total returned size is a much more reasonable 14k. The difference must be due to section alignments. I can try using a custom linker script to shrink the output size. I saw there are some __uart routines in the executable, even though I don't call them. Is that part of the CRT initialization? Can those functions be removed? If possible, I'm hoping to get a minimal executable below 8k. As a little background, I do a lot of FPGA development on Xilinx FPGAs, and I typically use a Microblaze or PPC for command handling. I've started working with ProASIC3Es, and I'm looking for something similar that can be used across multiple platforms. Having a small minimal executable to embed within the bitstream to do simple debug U/I and/or act as a bootloader is a really desirable capability. |
RE: Minimum executable image size
by werne on Jan 28, 2014 |
werne
Posts: 3 Joined: Jan 22, 2014 Last seen: Jan 31, 2014 |
||
That's not related, and the issue described in the bug report seems to not be present in the or1k toolchain anyway.
(One of) the reason(s) why a small program like that is much larger on or1k than for example Microblaze and PowerPC is due to a deficiency how the exception vectors are designed. On or1k, each exception vector takes 0x100 bytes, and there are 32 different exception vectors. So, 8192 bytes are "wasted" on the exception vectors. Another reason might be that our libgloss board support code that is used during startup is a bit more bloated than the above mentioned architectures. Stefan I have a dumb question about this I'd like to ask before I go down a rabbit hole. If I'm only going to hook up and enable one or two interrupts (e.g. using an external interrupt controller), is it easy/possible to recover that area? I'd imagine I can do it with a linker script, but I haven't read the OpenRISC specification yet, so I could be overlooking an obvious problem with that approach. Thoughts? |
RE: Minimum executable image size
by stekern on Jan 28, 2014 |
stekern
Posts: 84 Joined: Apr 28, 2009 Last seen: Nov 10, 2016 |
||
I'll try to answer both your questions.
The __uart routine is called from CRT, to initialize the uart. It's a bit silly and should probably be moved away from there. The only way to get rid of it if you want to use the libgloss startup routines is to modify them directly. Regarding the interrupt vectors: It should be possible to recover some of it if you have a clever linker script and data that you can interleave with the interrupt vectors. Another solution is to add an address decoder in the hardware which would just map the two first words of each exception vector to actual physical ram. Both of the approaches will of course break assumptions made in available software, but it sounds to me that you are mostly interested in running some custom baremetal application, so it's perhaps not an issue. Stefan |



