diff --git a/Kconfig b/Kconfig index 58e0dbe6135..eb038a17425 100644 --- a/Kconfig +++ b/Kconfig @@ -15,15 +15,25 @@ config CROSS_COMPILE default make runs in this kernel build directory. You don't need to set this unless you want the configured kernel build directory to select the cross-compiler automatically. -endmenu config MINIMAL_LIBC bool prompt "Build minimal c library" default y + depends on !NEWLIB help Build integrated minimal c library. +config TOOLCHAIN_NEWLIB + bool + prompt "Build with newlib c library" + depends on !MINIMAL_LIBC + default n + help + Build with newlib library. The newlib library is expected to be + part of the SDK in this case. +endmenu + menu "Debugging Options" config STDOUT_CONSOLE diff --git a/Makefile b/Makefile index df4259cc9d5..ed216bc0d5d 100644 --- a/Makefile +++ b/Makefile @@ -630,6 +630,10 @@ libs-y := $(KLIBC_DIR)/ TIMOINCLUDE += -I$(srctree)/lib/libc/minimal/include endif +ifdef CONFIG_TOOLCHAIN_NEWLIB +libs-y += lib/libc/newlib/ +endif + #File that includes all prepare special embedded architecture targets. include $(srctree)/scripts/Makefile.preparch sinclude $(srctree)/scripts/Makefile.$(SRCARCH).preparch diff --git a/lib/libc/Makefile b/lib/libc/Makefile new file mode 100644 index 00000000000..2e5063bfea3 --- /dev/null +++ b/lib/libc/Makefile @@ -0,0 +1,2 @@ +libs-$(CONFIG_MINIMAL_LIBC) += minimal/ +libs-$(CONFIG_NEWLIB) += newlib/ diff --git a/lib/libc/newlib/Makefile b/lib/libc/newlib/Makefile new file mode 100644 index 00000000000..a4d561090b9 --- /dev/null +++ b/lib/libc/newlib/Makefile @@ -0,0 +1 @@ +lib-y := libc-hooks.o diff --git a/lib/libc/newlib/libc-hooks.c b/lib/libc/newlib/libc-hooks.c new file mode 100644 index 00000000000..4fd64b64ac6 --- /dev/null +++ b/lib/libc/newlib/libc-hooks.c @@ -0,0 +1,105 @@ +#include +#include +#include + +#define HEAP_SIZE 4096 +unsigned char heap[HEAP_SIZE]; +unsigned int heap_sz = 0; + +static int _stdout_hook_default(int c) { + (void)(c); /* Prevent warning about unused argument */ + + return EOF; +} + +static int (*_stdout_hook)(int) = _stdout_hook_default; + +void __stdout_hook_install(int (*hook)(int)) { + _stdout_hook = hook; +} + +static unsigned char _stdin_hook_default(void) { + return 0; +} + +static unsigned char (*_stdin_hook)(void) = _stdin_hook_default; + +void __stdin_hook_install(unsigned char (*hook)(void)) { + _stdin_hook = hook; +} + +int read( int fd, char *buf, int nbytes) { + int i = 0; + + for (i = 0; i < nbytes; i++) { + *(buf + i) = _stdin_hook(); + if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { + i++; + break; + } + } + return (i); +} + +int write(int fd, char *buf, int nbytes) { + int i; + + for (i = 0; i < nbytes; i++) { + if (*(buf + i) == '\n') { + _stdout_hook ('\r'); + } + _stdout_hook (*(buf + i)); + } + return (nbytes); +} + +int fstat( int fd, struct stat *buf) { + buf->st_mode = S_IFCHR; /* Always pretend to be a tty */ + buf->st_blksize = 0; + + return (0); +} + +int isatty(int file) { + return 1; +} + + +int kill(int i, int j) { + return 0; +} + +int getpid() { + return 0; +} + +int _fstat(int file, struct stat *st) { + st->st_mode = S_IFCHR; + return 0; +} + + +void exit(int status) { + write(1, "exit", 4); + while (1) { + ; + } +} + +int close(int file) { + return -1; +} + +int lseek(int file, int ptr, int dir) { + return 0; +} + +void *sbrk(int count) { + void *ptr = heap + heap_sz; + if ((heap_sz + count) <= HEAP_SIZE) { + heap_sz += count; + return ptr; + } else { + return (void *)-1; + } +} diff --git a/scripts/Makefile.toolchain.xtools b/scripts/Makefile.toolchain.xtools index fb651412537..42a7f8dc95d 100644 --- a/scripts/Makefile.toolchain.xtools +++ b/scripts/Makefile.toolchain.xtools @@ -13,6 +13,6 @@ CROSS_COMPILE_x86=${XTOOLS_TOOLCHAIN_PATH}/${CROSS_COMPILE_TARGET_x86}/bin/${CRO CROSS_COMPILE= $(CROSS_COMPILE_$(ARCH)) -TOOLCHAIN_LIBS = gcc +TOOLCHAIN_LIBS = gcc c m export CROSS_COMPILE TOOLCHAIN_LIBS