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.