Baking PI with C and basic libs

294 Views Asked by At

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.

1

There are 1 best solutions below

5
On BEST ANSWER

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.