[U-Boot] Size of external u-boot commands

My networking hardware needs microcode loaded into it before it will function. What's the best method to load this code? It's 70KB.
My current u-boot image is 170KB. I started working with the code in examples and api_examples. But the "hello world" programs built using those APIs are 65-72KB in size. That's almost half the size of my u-boot image and these programs just print "hello world". Why are these programs so big? My goal was to put the loader program and my microcode into a single 128KB erase block.
My code for loading the microcode into the hardware is 7KB. Now it looks like I will need to incorporate it into the main u-boot image instead of making it an external command.

Jon Smirl wrote:
My networking hardware needs microcode loaded into it before it will function. What's the best method to load this code? It's 70KB.
My current u-boot image is 170KB. I started working with the code in examples and api_examples. But the "hello world" programs built using those APIs are 65-72KB in size. That's almost half the size of my u-boot image and these programs just print "hello world". Why are these programs so big? My goal was to put the loader program and my microcode into a single 128KB erase block.
My code for loading the microcode into the hardware is 7KB. Now it looks like I will need to incorporate it into the main u-boot image instead of making it an external command.
Hi Jon,
I suspect the example code is 98% C libraries and 2% nugget. In your example, "hello world" probably uses the whole printf support tree (strings, formatted printing, possibly floating point...).
I would suggest you make a stand-alone application that simply returns and see how big it ends up. Depending on whether that is small or not, check what libraries get linked with it and see how to create your simple test app such that it doesn't use any extraneous libraries.
HTH, gvb

On Thu, Mar 26, 2009 at 9:52 AM, Jerry Van Baren gerald.vanbaren@ge.com wrote:
Jon Smirl wrote:
My networking hardware needs microcode loaded into it before it will function. What's the best method to load this code? It's 70KB.
My current u-boot image is 170KB. I started working with the code in examples and api_examples. But the "hello world" programs built using those APIs are 65-72KB in size. That's almost half the size of my u-boot image and these programs just print "hello world". Why are these programs so big? My goal was to put the loader program and my microcode into a single 128KB erase block.
My code for loading the microcode into the hardware is 7KB. Now it looks like I will need to incorporate it into the main u-boot image instead of making it an external command.
Hi Jon,
I suspect the example code is 98% C libraries and 2% nugget. In your example, "hello world" probably uses the whole printf support tree (strings, formatted printing, possibly floating point...).
I would suggest you make a stand-alone application that simply returns and see how big it ends up. Depending on whether that is small or not, check what libraries get linked with it and see how to create your simple test app such that it doesn't use any extraneous libraries.
Libraries appear to be the problem. A program that just returns is 100 bytes, add a puts("hello world") and it is 65KB.
I had expected the u-boot app examples to be smart and use the copy of those libraries in the u-boot image. For example the demo program in api_examples uses printf (65K library) instead of building an api calling into u-boot for printf.
HTH, gvb

Jon Smirl wrote:
On Thu, Mar 26, 2009 at 9:52 AM, Jerry Van Baren gerald.vanbaren@ge.com wrote:
Jon Smirl wrote:
My networking hardware needs microcode loaded into it before it will function. What's the best method to load this code? It's 70KB.
My current u-boot image is 170KB. I started working with the code in examples and api_examples. But the "hello world" programs built using those APIs are 65-72KB in size. That's almost half the size of my u-boot image and these programs just print "hello world". Why are these programs so big? My goal was to put the loader program and my microcode into a single 128KB erase block.
My code for loading the microcode into the hardware is 7KB. Now it looks like I will need to incorporate it into the main u-boot image instead of making it an external command.
Hi Jon,
I suspect the example code is 98% C libraries and 2% nugget. In your example, "hello world" probably uses the whole printf support tree (strings, formatted printing, possibly floating point...).
I would suggest you make a stand-alone application that simply returns and see how big it ends up. Depending on whether that is small or not, check what libraries get linked with it and see how to create your simple test app such that it doesn't use any extraneous libraries.
Libraries appear to be the problem. A program that just returns is 100 bytes, add a puts("hello world") and it is 65KB.
I had expected the u-boot app examples to be smart and use the copy of those libraries in the u-boot image. For example the demo program in api_examples uses printf (65K library) instead of building an api calling into u-boot for printf.
No, the u-boot interface is *much* more basic than a library interface, it is on the level of "read character" / "write character". Making a trap interface at a library level would be a lot of work and would be a large source of problems for something that is a simple utility function (supporting stand-alone apps, that is)... a shared library interface is non-trivial for a full blown OS.
Library interface issues was the pain and screaming you (may have) heard when the world changed from a.out to DWARF to ELF and changing from glibc5 to glibc6, etc.
If you work a bit at it, you should not need to use libraries in your network loading app. If you can get by with just returning error codes, you can do error printing back in u-boot. If you need to print, use static strings so you don't pull in the world of string handling. You may need to make your own print function (a limited printf() is pretty simple) that sends your strings out using the u-boot "putc" interface.
gvb

On 2009-03-26, at 15:21, Jon Smirl wrote:
Libraries appear to be the problem. A program that just returns is 100 bytes, add a puts("hello world") and it is 65KB.
I had expected the u-boot app examples to be smart and use the copy of those libraries in the u-boot image. For example the demo program in api_examples uses printf (65K library) instead of building an api calling into u-boot for printf.
While I can understand your position, let me explain that the idea behind the API was to provide calls to really elementary operations and printf() wasn't considered as such (we only have print, get and test a single character as far as console ops go); things like pre- formatting should be done in the application...
The demo application is just a demo, it links in the same printf- formatting code that U-Boot library uses, but specific standalone applications are supposed to implement their own formatting routines.
Rafal

On Thu, Mar 26, 2009 at 10:43 AM, Rafal Jaworowski raj@semihalf.com wrote:
On 2009-03-26, at 15:21, Jon Smirl wrote:
Libraries appear to be the problem. A program that just returns is 100 bytes, add a puts("hello world") and it is 65KB.
I had expected the u-boot app examples to be smart and use the copy of those libraries in the u-boot image. For example the demo program in api_examples uses printf (65K library) instead of building an api calling into u-boot for printf.
While I can understand your position, let me explain that the idea behind the API was to provide calls to really elementary operations and printf() wasn't considered as such (we only have print, get and test a single character as far as console ops go); things like pre-formatting should be done in the application...
The demo application is just a demo, it links in the same printf-formatting code that U-Boot library uses, but specific standalone applications are supposed to implement their own formatting routines.
I'm not sure that the size of the app is caused by libraries.
jonsmirl@terra:/home/apps/u-boot/api_examples$ ls -l demo.bin -rwxr-xr-x 1 jonsmirl jonsmirl 79060 2009-03-26 10:58 demo.bin
now gzip the bin.... -rwxr-xr-x 1 jonsmirl jonsmirl 7677 2009-03-26 10:58 demo.bin.gz
Here's the map file; I'm trying to remember how to read it. There's probably 64K of a data segment being initialized with zeros.
Archive member included because of file (symbol)
libglue.a(ppcstring.o) demo.o (memset) libglue.a(glue.o) demo.o (ub_dev_get) libglue.a(crc32.o) libglue.a(glue.o) (crc32) libglue.a(libgenwrap.o) demo.o (printf) libglue.a(vsprintf.o) libglue.a(libgenwrap.o) (vsprintf) libglue.a(ctype.o) libglue.a(vsprintf.o) (_ctype) libglue.a(string.o) libglue.a(vsprintf.o) (strnlen)
Allocating common symbols Common symbol size file
___strtok 0x4 libglue.a(string.o)
Discarded input sections
.note.GNU-stack 0x0000000000000000 0x0 demo.o .note.GNU-stack 0x0000000000000000 0x0 libglue.a(glue.o) .note.GNU-stack 0x0000000000000000 0x0 libglue.a(crc32.o) .note.GNU-stack 0x0000000000000000 0x0 libglue.a(libgenwrap.o) .note.GNU-stack 0x0000000000000000 0x0 libglue.a(vsprintf.o) .note.GNU-stack 0x0000000000000000 0x0 libglue.a(ctype.o) .note.GNU-stack 0x0000000000000000 0x0 libglue.a(string.o)
Memory Configuration
Name Origin Length Attributes *default* 0x0000000000000000 0xffffffffffffffff
Linker script and memory map
LOAD crt0.o Address of section .text set to 0x40000 LOAD demo.o LOAD libglue.a 0x0000000010000000 PROVIDE (__executable_start, 0x10000000) 0x0000000010000094 . = (0x10000000 + SIZEOF_HEADERS)
.interp *(.interp)
.note.gnu.build-id *(.note.gnu.build-id)
.hash *(.hash)
.gnu.hash *(.gnu.hash)
.dynsym *(.dynsym)
.dynstr *(.dynstr)
.gnu.version *(.gnu.version)
.gnu.version_d *(.gnu.version_d)
.gnu.version_r *(.gnu.version_r)
.rel.dyn *(.rel.init) *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) *(.rel.fini) *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) *(.rel.ctors) *(.rel.dtors) *(.rel.got) *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
.rela.dyn 0x0000000010000094 0x0 *(.rela.init) *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) .rela.text 0x0000000000000000 0x0 crt0.o *(.rela.fini) *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) *(.rela.ctors) *(.rela.dtors) *(.rela.got) *(.rela.got1) *(.rela.got2) .rela.got2 0x0000000000000000 0x0 crt0.o *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
.rel.plt *(.rel.plt)
.rela.plt *(.rela.plt)
.init *(.init)
.text 0x0000000000040000 0x2930 *(.text .stub .text.* .gnu.linkonce.t.*) .text 0x0000000000040000 0x38 crt0.o 0x0000000000040010 syscall 0x0000000000040034 search_hint 0x0000000000040000 _start 0x0000000000040024 syscall_ptr .text 0x0000000000040038 0x890 demo.o 0x0000000000040260 test_dump_si 0x000000000004038c test_dump_sig 0x0000000000040404 main 0x0000000000040184 test_dump_buf 0x000000000004003c test_dump_di .text 0x00000000000408c8 0x29c libglue.a(ppcstring.o) 0x00000000000408c8 strcpy 0x00000000000409e0 memmove 0x00000000000409e8 memcpy 0x000000000004090c strcat 0x0000000000040b3c memchr 0x00000000000408e4 strncpy 0x00000000000409d0 bcopy 0x0000000000040b0c memcmp 0x0000000000040a84 backwards_memcpy 0x0000000000040974 memset 0x0000000000040938 strcmp 0x000000000004095c strlen .text 0x0000000000040b64 0x8e0 libglue.a(glue.o) 0x0000000000041058 ub_puts 0x0000000000040d30 ub_dev_recv 0x0000000000041200 ub_dev_enum 0x0000000000040fb0 ub_get_timer 0x000000000004102c ub_reset 0x00000000000410fc ub_getc 0x0000000000040ff8 ub_udelay 0x00000000000410bc ub_tstc 0x0000000000041360 api_search_sig 0x0000000000041088 ub_putc 0x0000000000040ec4 ub_dev_close 0x0000000000041140 ub_env_enum 0x0000000000040de8 ub_dev_read 0x0000000000040f34 ub_dev_open 0x0000000000040c20 ub_env_set 0x0000000000040c9c ub_dev_send 0x0000000000040c54 ub_env_get 0x0000000000040b68 ub_dev_get 0x00000000000412bc ub_get_sys_info .text 0x0000000000041444 0x2b8 libglue.a(crc32.o) 0x0000000000041448 crc32 0x00000000000416dc crc32_wd 0x0000000000041598 crc32_no_comp .text 0x00000000000416fc 0x15c libglue.a(libgenwrap.o) 0x00000000000417b4 printf 0x000000000004170c hang 0x00000000000416fc malloc 0x0000000000041714 do_reset 0x0000000000041774 vprintf 0x0000000000041734 udelay 0x0000000000041754 putc .text 0x0000000000041858 0xc70 libglue.a(vsprintf.o) 0x0000000000041de4 vsprintf 0x0000000000041998 ustrtoul 0x000000000004195c simple_strtol 0x0000000000041d34 panic 0x0000000000042448 sprintf 0x000000000004185c simple_strtoul .text 0x00000000000424c8 0x0 libglue.a(ctype.o) .text 0x00000000000424c8 0x468 libglue.a(string.o) 0x00000000000427d4 memscan 0x0000000000042780 strswab 0x00000000000425a8 strnlen 0x0000000000042800 strrchr 0x0000000000042854 strstr 0x0000000000042524 strncmp 0x0000000000042670 strtok 0x00000000000424c8 strncat 0x00000000000428dc strdup 0x0000000000042728 strsep 0x00000000000425dc strspn 0x0000000000042574 strchr 0x0000000000042628 strpbrk *(.text.*personality*) *(.gnu.warning) *(.glink)
.fini *(.fini) 0x0000000000042930 PROVIDE (__etext, .) 0x0000000000042930 PROVIDE (_etext, .) 0x0000000000042930 PROVIDE (etext, .)
.rodata 0x0000000000042930 0x960 *(.rodata .rodata.* .gnu.linkonce.r.*) .rodata.str1.4 0x0000000000042930 0x4f3 demo.o 0x4fb (size before relaxing) *fill* 0x0000000000042e23 0x1 00 .rodata 0x0000000000042e24 0x5 demo.o *fill* 0x0000000000042e29 0x3 00 .rodata.str1.4 0x0000000000042e2c 0x9 libglue.a(glue.o) *fill* 0x0000000000042e35 0x3 00 .rodata 0x0000000000042e38 0x400 libglue.a(crc32.o) .rodata.str1.4 0x0000000000043238 0x58 libglue.a(vsprintf.o) 0x57 (size before relaxing)
.rodata1 *(.rodata1)
.sdata2 0x0000000000043290 0x0 0x000000000004b290 PROVIDE (_SDA2_BASE_, 0x8000) *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
.sbss2 *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
.eh_frame_hdr *(.eh_frame_hdr)
.eh_frame *(.eh_frame)
.gcc_except_table *(.gcc_except_table .gcc_except_table.*) 0x0000000000043290 . = (ALIGN (0x10000) - ((0x10000 - .) & 0xffff)) 0x0000000000053290 . = (0x10000 DATA_SEGMENT_ALIGN 0x1000)
.eh_frame *(.eh_frame)
.gcc_except_table *(.gcc_except_table .gcc_except_table.*)
.tdata *(.tdata .tdata.* .gnu.linkonce.td.*)
.tbss *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
.preinit_array 0x0000000000053290 0x0 0x0000000000053290 PROVIDE (__preinit_array_start, .) *(.preinit_array) 0x0000000000053290 PROVIDE (__preinit_array_end, .)
.init_array 0x0000000000053290 0x0 0x0000000000053290 PROVIDE (__init_array_start, .) *(SORT(.init_array.*)) *(.init_array) 0x0000000000053290 PROVIDE (__init_array_end, .)
.fini_array 0x0000000000053290 0x0 0x0000000000053290 PROVIDE (__fini_array_start, .) *(.fini_array) *(SORT(.fini_array.*)) 0x0000000000053290 PROVIDE (__fini_array_end, .)
.ctors *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors)
.dtors *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors)
.jcr *(.jcr)
.data.rel.ro *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*)
.got1 *(.got1)
.got2 0x0000000000053290 0x144 *(.got2) .got2 0x0000000000053290 0x114 demo.o .got2 0x00000000000533a4 0x18 libglue.a(glue.o) .got2 0x00000000000533bc 0x4 libglue.a(crc32.o) .got2 0x00000000000533c0 0x0 libglue.a(libgenwrap.o) .got2 0x00000000000533c0 0x10 libglue.a(vsprintf.o) .got2 0x00000000000533d0 0x0 libglue.a(ctype.o) .got2 0x00000000000533d0 0x4 libglue.a(string.o)
.dynamic *(.dynamic)
.got *(.got) 0x00000000000533d4 . = (. DATA_SEGMENT_RELRO_END 0x0)
.plt *(.plt)
.data 0x00000000000533d4 0x100 *(.data .data.* .gnu.linkonce.d.*) .data 0x00000000000533d4 0x0 crt0.o .data 0x00000000000533d4 0x0 demo.o .data 0x00000000000533d4 0x0 libglue.a(ppcstring.o) .data 0x00000000000533d4 0x0 libglue.a(glue.o) .data 0x00000000000533d4 0x0 libglue.a(crc32.o) .data 0x00000000000533d4 0x0 libglue.a(libgenwrap.o) .data 0x00000000000533d4 0x0 libglue.a(vsprintf.o) .data 0x00000000000533d4 0x100 libglue.a(ctype.o) 0x00000000000533d4 _ctype .data 0x00000000000534d4 0x0 libglue.a(string.o) *(.gnu.linkonce.d.*personality*)
.data1 *(.data1)
.got *(.got)
.sdata 0x00000000000534d4 0x0 0x000000000005b4d4 PROVIDE (_SDA_BASE_, 0x8000) *(.sdata .sdata.* .gnu.linkonce.s.*) 0x00000000000534d4 _edata = . 0x00000000000534d4 PROVIDE (edata, .) 0x00000000000534d4 __bss_start = .
.sbss 0x00000000000534d4 0x4 0x00000000000534d4 PROVIDE (__sbss_start, .) 0x00000000000534d4 PROVIDE (___sbss_start, .) *(.dynsbss) *(.sbss .sbss.* .gnu.linkonce.sb.*) .sbss 0x0000000000000000 0x0 crt0.o .sbss 0x00000000000534d4 0x4 libglue.a(string.o) 0x00000000000534d4 ___strtok *(.scommon) 0x00000000000534d8 PROVIDE (__sbss_end, .) 0x00000000000534d8 PROVIDE (___sbss_end, .)
.plt *(.plt)
.bss 0x00000000000534d8 0x9c8 *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) .bss 0x00000000000534d8 0x0 crt0.o .bss 0x00000000000534d8 0x800 demo.o .bss 0x0000000000053cd8 0x0 libglue.a(ppcstring.o) .bss 0x0000000000053cd8 0x1c8 libglue.a(glue.o) .bss 0x0000000000053ea0 0x0 libglue.a(crc32.o) .bss 0x0000000000053ea0 0x0 libglue.a(libgenwrap.o) .bss 0x0000000000053ea0 0x0 libglue.a(vsprintf.o) .bss 0x0000000000053ea0 0x0 libglue.a(ctype.o) .bss 0x0000000000053ea0 0x0 libglue.a(string.o) *(COMMON) 0x0000000000053ea0 . = ALIGN ((. != 0x0)?0x4:0x1) 0x0000000000053ea0 . = ALIGN (0x4) 0x0000000000053ea0 . = ALIGN (0x4) 0x0000000000053ea0 _end = . 0x0000000000053ea0 PROVIDE (end, .) 0x0000000000053ea0 . = DATA_SEGMENT_END (.)
.stab *(.stab)
.stabstr *(.stabstr)
.stab.excl *(.stab.excl)
.stab.exclstr *(.stab.exclstr)
.stab.index *(.stab.index)
.stab.indexstr *(.stab.indexstr)
.comment 0x0000000000000000 0x7e *(.comment) .comment 0x0000000000000000 0x12 demo.o .comment 0x0000000000000012 0x12 libglue.a(glue.o) .comment 0x0000000000000024 0x12 libglue.a(crc32.o) .comment 0x0000000000000036 0x12 libglue.a(libgenwrap.o) .comment 0x0000000000000048 0x12 libglue.a(vsprintf.o) .comment 0x000000000000005a 0x12 libglue.a(ctype.o) .comment 0x000000000000006c 0x12 libglue.a(string.o)
.debug *(.debug)
.line *(.line)
.debug_srcinfo *(.debug_srcinfo)
.debug_sfnames *(.debug_sfnames)
.debug_aranges *(.debug_aranges)
.debug_pubnames *(.debug_pubnames)
.debug_info *(.debug_info .gnu.linkonce.wi.*)
.debug_abbrev *(.debug_abbrev)
.debug_line *(.debug_line)
.debug_frame *(.debug_frame)
.debug_str *(.debug_str)
.debug_loc *(.debug_loc)
.debug_macinfo *(.debug_macinfo)
.debug_weaknames *(.debug_weaknames)
.debug_funcnames *(.debug_funcnames)
.debug_typenames *(.debug_typenames)
.debug_varnames *(.debug_varnames)
.debug_pubtypes *(.debug_pubtypes)
.debug_ranges *(.debug_ranges)
.gnu.attributes *(.gnu.attributes)
/DISCARD/ *(.fixup) *(.note.GNU-stack) *(.gnu_debuglink) OUTPUT(demo elf32-powerpc)

On Thu, Mar 26, 2009 at 11:06 AM, Jon Smirl jonsmirl@gmail.com wrote:
On Thu, Mar 26, 2009 at 10:43 AM, Rafal Jaworowski raj@semihalf.com wrote:
On 2009-03-26, at 15:21, Jon Smirl wrote:
Libraries appear to be the problem. A program that just returns is 100 bytes, add a puts("hello world") and it is 65KB.
I had expected the u-boot app examples to be smart and use the copy of those libraries in the u-boot image. For example the demo program in api_examples uses printf (65K library) instead of building an api calling into u-boot for printf.
While I can understand your position, let me explain that the idea behind the API was to provide calls to really elementary operations and printf() wasn't considered as such (we only have print, get and test a single character as far as console ops go); things like pre-formatting should be done in the application...
The demo application is just a demo, it links in the same printf-formatting code that U-Boot library uses, but specific standalone applications are supposed to implement their own formatting routines.
I'm not sure that the size of the app is caused by libraries.
jonsmirl@terra:/home/apps/u-boot/api_examples$ ls -l demo.bin -rwxr-xr-x 1 jonsmirl jonsmirl 79060 2009-03-26 10:58 demo.bin
now gzip the bin.... -rwxr-xr-x 1 jonsmirl jonsmirl 7677 2009-03-26 10:58 demo.bin.gz
Here's the map file; I'm trying to remember how to read it. There's probably 64K of a data segment being initialized with zeros.
What is this doing? Can I turn it off?
.gcc_except_table *(.gcc_except_table .gcc_except_table.*) 0x0000000000043290 . = (ALIGN (0x10000) - ((0x10000 - .) & 0xffff)) 0x0000000000053290 . = (0x10000 DATA_SEGMENT_ALIGN 0x1000)

On Thu, Mar 26, 2009 at 11:10 AM, Jon Smirl jonsmirl@gmail.com wrote:
On Thu, Mar 26, 2009 at 11:06 AM, Jon Smirl jonsmirl@gmail.com wrote:
On Thu, Mar 26, 2009 at 10:43 AM, Rafal Jaworowski raj@semihalf.com wrote:
On 2009-03-26, at 15:21, Jon Smirl wrote:
Libraries appear to be the problem. A program that just returns is 100 bytes, add a puts("hello world") and it is 65KB.
I had expected the u-boot app examples to be smart and use the copy of those libraries in the u-boot image. For example the demo program in api_examples uses printf (65K library) instead of building an api calling into u-boot for printf.
While I can understand your position, let me explain that the idea behind the API was to provide calls to really elementary operations and printf() wasn't considered as such (we only have print, get and test a single character as far as console ops go); things like pre-formatting should be done in the application...
The demo application is just a demo, it links in the same printf-formatting code that U-Boot library uses, but specific standalone applications are supposed to implement their own formatting routines.
I'm not sure that the size of the app is caused by libraries.
jonsmirl@terra:/home/apps/u-boot/api_examples$ ls -l demo.bin -rwxr-xr-x 1 jonsmirl jonsmirl 79060 2009-03-26 10:58 demo.bin
now gzip the bin.... -rwxr-xr-x 1 jonsmirl jonsmirl 7677 2009-03-26 10:58 demo.bin.gz
Here's the map file; I'm trying to remember how to read it. There's probably 64K of a data segment being initialized with zeros.
What is this doing? Can I turn it off?
.gcc_except_table *(.gcc_except_table .gcc_except_table.*) 0x0000000000043290 . = (ALIGN (0x10000)
- ((0x10000 - .) & 0xffff))
0x0000000000053290 . = (0x10000 DATA_SEGMENT_ALIGN 0x1000)
I don't know what I'm doing playing around with the linker scripts but adding this: .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
to the script for api_example/demo makes the binary 50KB smaller. -rwxr-xr-x 1 jonsmirl jonsmirl 16964 2009-03-26 12:08 demo.bin
-- Jon Smirl jonsmirl@gmail.com

On Thursday 26 March 2009 09:47:08 Jon Smirl wrote:
My networking hardware needs microcode loaded into it before it will function. What's the best method to load this code? It's 70KB.
can the microcode access external memory (i.e. where u-boot lives) ? iirc, the external functions are not linked statically into "u-boot applications". the application uses function pointers that get relocated to point to u-boot in external memory. -mike

Dear Jon Smirl,
In message 9e4733910903260647w549a97acv7101ea9347a767bb@mail.gmail.com you wrote:
My networking hardware needs microcode loaded into it before it will function. What's the best method to load this code? It's 70KB.
My current u-boot image is 170KB. I started working with the code in examples and api_examples. But the "hello world" programs built using those APIs are 65-72KB in size. That's almost half the size of my u-boot image and these programs just print "hello world". Why are these programs so big? My goal was to put the loader program and my microcode into a single 128KB erase block.
My code for loading the microcode into the hardware is 7KB. Now it looks like I will need to incorporate it into the main u-boot image instead of making it an external command.
I'm not sure how you calcualte sizes, or how you link your applications. Note that classical standalone application do not link against any libraries, so they are really small:
-> size examples/{hello_world,timer} text data bss dec hex filename 796 40 0 836 344 examples/hello_world 1556 56 0 1612 64c examples/timer
As you can see, the "hello world" demo program just needs a few hundret bytes.
Best regards,
Wolfgang Denk

On Thu, Mar 26, 2009 at 4:27 PM, Wolfgang Denk wd@denx.de wrote:
Dear Jon Smirl,
In message 9e4733910903260647w549a97acv7101ea9347a767bb@mail.gmail.com you wrote:
My networking hardware needs microcode loaded into it before it will function. What's the best method to load this code? It's 70KB.
My current u-boot image is 170KB. I started working with the code in examples and api_examples. But the "hello world" programs built using those APIs are 65-72KB in size. That's almost half the size of my u-boot image and these programs just print "hello world". Why are these programs so big? My goal was to put the loader program and my microcode into a single 128KB erase block.
My code for loading the microcode into the hardware is 7KB. Now it looks like I will need to incorporate it into the main u-boot image instead of making it an external command.
I'm not sure how you calculate sizes, or how you link your applications. Note that classical standalone application do not link against any libraries, so they are really small:
The *.bin files are ending up at 60-75K. Adding this to the linker script fixes it. .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
Approximately 60KB of zeros are getting inserted into the *.bin files.
Before: jonsmirl@terra:/home/apps/u-boot/examples$ ls *.bin -l -rwxr-xr-x 1 jonsmirl jonsmirl 66424 2009-03-26 15:59 hello_world.bin -rwxr-xr-x 1 jonsmirl jonsmirl 66460 2009-03-26 15:59 interrupt.bin -rwxr-xr-x 1 jonsmirl jonsmirl 68464 2009-03-26 15:59 sched.bin
After the linker script change: jonsmirl@terra:/home/apps/u-boot/examples$ ls *.bin -l -rwxr-xr-x 1 jonsmirl jonsmirl 4136 2009-03-26 16:49 hello_world.bin -rwxr-xr-x 1 jonsmirl jonsmirl 4128 2009-03-26 16:49 interrupt.bin -rwxr-xr-x 1 jonsmirl jonsmirl 4184 2009-03-26 16:49 sched.bin jonsmirl@terra:/home/apps/u-boot/examples$
-> size examples/{hello_world,timer} text data bss dec hex filename 796 40 0 836 344 examples/hello_world 1556 56 0 1612 64c examples/timer
As you can see, the "hello world" demo program just needs a few hundret bytes.
Best regards,
Wolfgang Denk
-- 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@denx.de The computer can't tell you the emotional story. It can give you the exact mathematical design, but what's missing is the eyebrows.
- Frank Zappa

Dear Jon Smirl,
In message 9e4733910903261350v21bf16c5l5729927048e0df3b@mail.gmail.com you wrote:
I'm not sure how you calculate sizes, or how you link your applications. Note that classical standalone application do not link against any libraries, so they are really small:
The *.bin files are ending up at 60-75K. Adding this to the linker
Yes, but that's mostly empty space, due to the alignment requirments in the linker script.
script fixes it. .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
Approximately 60KB of zeros are getting inserted into the *.bin files.
But this is just a "gap", it e. it is not used space; if you have bigger program code, or if you change your alignment requirements, you will see different (much smaller) values.
Best regards,
Wolfgang Denk

On Thu, Mar 26, 2009 at 5:15 PM, Wolfgang Denk wd@denx.de wrote:
Dear Jon Smirl,
In message 9e4733910903261350v21bf16c5l5729927048e0df3b@mail.gmail.com you wrote:
I'm not sure how you calculate sizes, or how you link your applications. Note that classical standalone application do not link against any libraries, so they are really small:
The *.bin files are ending up at 60-75K. Adding this to the linker
Yes, but that's mostly empty space, due to the alignment requirments in the linker script.
script fixes it. .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
Approximately 60KB of zeros are getting inserted into the *.bin files.
But this is just a "gap", it e. it is not used space; if you have bigger program code, or if you change your alignment requirements, you will see different (much smaller) values.
I'm on powerpc. The *.bin format is not smart enough to encode gaps. It just puts in 60KB of zeros.
My ELF files are 73KB. -rwxr-xr-x 1 jonsmirl jonsmirl 73290 2009-03-26 16:49 hello_world
Tell me the right way to make these example programs small and I'll submit a patch.

Dear Jon Smirl,
In message 9e4733910903261435x598055f8m74c5ac03ad16b67e@mail.gmail.com you wrote:
The *.bin format is not smart enough to encode gaps. It just puts in 60KB of zeros.
Yes, of course. A binary image cannot have holes in it.
My ELF files are 73KB. -rwxr-xr-x 1 jonsmirl jonsmirl 73290 2009-03-26 16:49 hello_world
Tell me the right way to make these example programs small and I'll submit a patch.
I don't see a problem that needs fixing. These are example problems. The image size plays no role. If you have any specific requirements for your own code, then adjust the linker script according to your requirements.
Best regards,
Wolfgang Denk

On Thu, Mar 26, 2009 at 7:26 PM, Wolfgang Denk wd@denx.de wrote:
Dear Jon Smirl,
In message 9e4733910903261435x598055f8m74c5ac03ad16b67e@mail.gmail.com you wrote:
The *.bin format is not smart enough to encode gaps. It just puts in 60KB of zeros.
Yes, of course. A binary image cannot have holes in it.
My ELF files are 73KB. -rwxr-xr-x 1 jonsmirl jonsmirl 73290 2009-03-26 16:49 hello_world
Tell me the right way to make these example programs small and I'll submit a patch.
I don't see a problem that needs fixing. These are example problems. The image size plays no role. If you have any specific requirements for your own code, then adjust the linker script according to your requirements.
By providing a sample linker script to make the example programs smaller, you could avoid discussions like this in the future.

Hi Jon,
On Thu, Mar 26, 2009 at 7:26 PM, Wolfgang Denk wd@denx.de wrote:
Dear Jon Smirl,
In message 9e4733910903261435x598055f8m74c5ac03ad16b67e@mail.gmail.com you wrote:
The *.bin format is not smart enough to encode gaps. It just puts in 60KB of zeros.
Yes, of course. A binary image cannot have holes in it.
My ELF files are 73KB. -rwxr-xr-x 1 jonsmirl jonsmirl 73290 2009-03-26 16:49 hello_world
Tell me the right way to make these example programs small and I'll submit a patch.
I don't see a problem that needs fixing. These are example problems. The image size plays no role. If you have any specific requirements for your own code, then adjust the linker script according to your requirements.
By providing a sample linker script to make the example programs smaller, you could avoid discussions like this in the future.
But as long as we do not understand what we change or what this does, we may well get a lot of bug threads in return. And I have to admit, I'm not to keen on that.
Cheers Detlev

Dear Detlev,
In message m27i2bl0a3.fsf@ohwell.denx.de you wrote:
By providing a sample linker script to make the example programs smaller, you could avoid discussions like this in the future.
But as long as we do not understand what we change or what this does, we may well get a lot of bug threads in return. And I have to admit, I'm not to keen on that.
But we do understand what's going on, or am I missing something?
There is simply no linker script for the PowerPC examples, so the default alignment settings for section alignment apply, and I think I remember that ELF sections are aligned on 64k boundaries by default.
So if somebody wants a less generous alignment, all that needs to be done is to set up a linker script that uses other alignment; it is a matter of personal test or projec tneeds if you want to align this on any specific boundary or if you shose some arbitrary value like 4k or 64 bytes or whatever.
The thing is, that these are examples, and use default settings.
Best regards,
Wolfgang Denk

Hi Wolfgang,
In message m27i2bl0a3.fsf@ohwell.denx.de you wrote:
By providing a sample linker script to make the example programs smaller, you could avoid discussions like this in the future.
But as long as we do not understand what we change or what this does, we may well get a lot of bug threads in return. And I have to admit, I'm not to keen on that.
But we do understand what's going on, or am I missing something?
I was referring to the other proposed change which I still do not understand:
The *.bin files are ending up at 60-75K. Adding this to the linker script fixes it. .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
I fully agree that the examples should rather use defaults because as the name implies, they are examples after all, not tightly optimized special cases.
Cheers Detlev

On Fri, Mar 27, 2009 at 7:17 AM, Detlev Zundel dzu@denx.de wrote:
Hi Wolfgang,
In message m27i2bl0a3.fsf@ohwell.denx.de you wrote:
By providing a sample linker script to make the example programs smaller, you could avoid discussions like this in the future.
But as long as we do not understand what we change or what this does, we may well get a lot of bug threads in return. And I have to admit, I'm not to keen on that.
But we do understand what's going on, or am I missing something?
I was referring to the other proposed change which I still do not understand:
The *.bin files are ending up at 60-75K. Adding this to the linker script fixes it. .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
I fully agree that the examples should rather use defaults because as the name implies, they are examples after all, not tightly optimized special cases.
Providing an example linker script would show us the right way to write it. I've never written a linker script for the ppc and I don't know what I'm doing. Copying the the one over from the CPU directory was not sufficient to make the app smaller.

On Friday 27 March 2009 08:47:40 Jon Smirl wrote:
On Fri, Mar 27, 2009 at 7:17 AM, Detlev Zundel dzu@denx.de wrote:
Hi Wolfgang,
In message m27i2bl0a3.fsf@ohwell.denx.de you wrote:
By providing a sample linker script to make the example programs smaller, you could avoid discussions like this in the future.
But as long as we do not understand what we change or what this does, we may well get a lot of bug threads in return. And I have to admit, I'm not to keen on that.
But we do understand what's going on, or am I missing something?
I was referring to the other proposed change which I still do not
understand:
The *.bin files are ending up at 60-75K. Adding this to the linker script fixes it. .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
I fully agree that the examples should rather use defaults because as the name implies, they are examples after all, not tightly optimized special cases.
Providing an example linker script would show us the right way to write it. I've never written a linker script for the ppc and I don't know what I'm doing. Copying the the one over from the CPU directory was not sufficient to make the app smaller.
ask the toolchain for the linker script its using. having u-boot duplicate it leads to obvious bit rot scenarios. u-boot isnt an exercise in teaching you how to read the linker manual.
link with -Wl,--verbose to see the default linker script that is used. -mike
participants (6)
-
Detlev Zundel
-
Jerry Van Baren
-
Jon Smirl
-
Mike Frysinger
-
Rafal Jaworowski
-
Wolfgang Denk