0

I have following problem - I've done baking pi course without any problems and then I 've decided to link this pure asm with some C. And I have done this and everything is working nice as far as I decided to use function sprintf to convert int to char*. Now when im trying to compile im enjoying following error

ctesty.c:(.text+0x20): undefined reference to 'sprintf' make: *** [build/output.elf] Error 1

of course i have included stdio.h, i also tried to include this lib directly in makefile but without success.

Macko
  • 139
  • 7

1 Answers1

3

You want to link with libc.so. Try adding -lc in the link step in your makefiles.

Update after Better Understanding of the Question

The Baking Pi examples build a kernel.img that runs in place of the usual Linux kernel. This means that the C standard library is not available. You'll need to supply your own sprintf() implementation, e.g.:

  • Adapt this BSD licensed ee_printf.c
  • Remove uart_send_char()
  • Adapt ee_printf() into sprintf() by making buf a function parameter

Why a Userspace libc Wouldn't Work Without Source Modifications in any Kernel

Conceptually:

  • The C standard library contains facilities dealing with dynamic memory allocation (malloc, free), the file system (fopen, fclose and all of stdio), environment variables (getenv), error handling facilities like setjmp longjmp and more.
  • Consider: how would you implement malloc in a program running under an operating system?
    • Answer: You'd need some interface to request additional memory from the OS, such as brk, sbrk and mmap under Linux.
    • In an OS kernel, brk, mmap etc wouldn't be the right interfaces to allocate memory.
    • Thus though most non-toy kernels provide malloc like facilities, they won't be able to use the userspace malloc implementations unmodified.
  • In an OS kernel, functions like fopen, getenv are not really that useful. Most kernel writers choose not to include them.
  • Thus most kernels don't include complete C standard library implementations but only the functions that the kernel writers find useful.

In a more mechanical sense:

  • The Baking Pi Makefile produces the kernel ELF image with the command $(ARMGNU)-ld --no-undefined $(OBJECTS) -Map $(MAP) -o $(BUILD)output.elf -T $(LINKER). This doesn't link build/output.elf with any libc implementation so the linker wouldn't be able to find a symbol named sprintf.
  • When you build a program with gcc T.c -o T, gcc implicitly links in libc unless an option like -nostdlib is passed.

But the conceptually important points are:

  • The parts of the C standard library that are useful in a kernel would require different implementations
  • A lot of other parts of libc wouldn't be that useful in a kernel

There are C standard library implementations targeting bare metal environments. See for example, newlib.

scottt
  • 7,008
  • 27
  • 37
  • not sure how it may help, other libs like stdlib.h works perfect only with sprintf (for now) I have problem I will try maybe some other functions from this lib and give an response. Thanks for help. – Macko Jun 23 '14 at 14:11
  • @Macko, showing the commands you're using to build and link your program would help you get a better answer. – scottt Jun 23 '14 at 14:12
  • im using standart baking pi course makefile [link]http://pastebin.com/hvW2TmAA itoa not working too. – Macko Jun 23 '14 at 15:57
  • @Macko, I've updated my answer to explain that you need to supply your own `sprintf` and how to do so – scottt Jun 23 '14 at 16:14
  • thanks, I have already written my own function to workaround, but I just wondering why these functions doesnt working and I still dunno, can u explain why i cant use them while building kernel? Sorry Im new in bare metal. – Macko Jun 24 '14 at 14:03