newlib Cross-Compile
newlib简介
NewLib调研
NewLib简介
C 标准库有多种实现,从glibc
大多数 GNU/Linux 系统上的古老版本开始。替代实现包括 Musl libc 1、 Bionic libc 2、 ucLibc 3和 Dietlibc 4。
Newlib是一个面向嵌入式系统的C运行库。最初是由Cygnus Solutions收集组装的一个源代码集合,取名为newlib,现在由Red Hat维护,目前的最新的稳定版本是4.4.2[1]。
对于与GNU兼容的嵌入式C运行库,Newlib并不是唯一的选择,但是从成熟度来讲,newlib是最优秀的。newlib具有独特的体系结构,使得它能够非常好地满足深度嵌入式系统的要求。newlib可移植性强,具有可重入特性、功能完备等特点,已广泛应用于各种嵌入式系统中。而且newlib可以集成到gcc交叉编译器中,在使用gcc的时候,直接链接newlib库,生成可执行文件。Cygwin目前使用Newlib来作为它的C标准库。
注意:当代码大小受到限制时,可以选择使用 newlib 的变体,称为 newlib-nano,它取消了一些 C99 功能和一些printf
花里胡哨,以提供更紧凑的标准库。Newlib-nano 通过—specs=nano.specs
CFLAG 启用
NewLib中syscall桩函数
使用newlib库时,需要自己实现的桩函数,包括了_write,_close函数等等。因为newlib库,并不知道裸机底层,是如何实现这些操作的。
Newlib的所有库函数都建立在20个桩函数的基础上[2],这20个桩函数完成一些newlib无法实现的功能:
- 级I/O和文件系统访问(open、close、read、write、lseek、stat、fstat、fcntl、link、unlink、rename);
- 扩大内存堆的需求(sbrk);
- 获得当前系统的日期和时间(gettimeofday、times);
- 各种类型的任务管理函数(execve、fork、getpid、kill、wait、_exit);
这20个桩函数在语义、语法上与POSIX标准下对应的20个同名系统调用是完全兼容的。成功移植newlib的关键是在目标系统环境下,找到能够与这些桩函数衔接的功能函数并实现这些桩函数。
Newlib为每个桩函数提供了可重入的和不可重入的两种版本。两种版本的区别在于,如果不可重入版桩函数的名字是xxx,则对应的可重入版桩函数的名字是_xxx_r,如close和_close_r,open和_open_r,等等。此外,可重入的桩函数在参数表中含有一个_reent结构指针,这个指针使得系统的实现者能在库和目标操作环境之间传送上下文相关的信息,尤其是发生错误时,能够便捷的传送errno的值到适当的任务中。
所谓最小实现是指,假定将要移植的目标系统中没有文件系统,也没有符合POSIX标准的任务管理机制和应用编程接口(Application Programming Interface, API),仅仅实现newlib的一个最小移植。在newlib的移植过程中全功能实现的桩函数只有open、close、read、write和sbrk五个,其他桩函数仅仅实现一个返回错误的空函数。
任务管理的execve、fork、getpid、kill、wait和_exit六个桩函数,仅仅实现一个返回-1的空函数,返回之前将errno设置为ENOTSUP,表示系统不支持该函数。
与文件相关的link和unlink桩函数也仅仅实现一个返回-1的空函数,将errno设置为EMLINK表示连接过多;lseek函数则不需要返回任何错误,直接返回0,表示操作成功。
fstat和stat桩函数在newlib中主要用于判断流的类型(常规文件、字符设备、目录),将其实现为不论输入参数如何,都返回字符设备类型的空函数。
times桩函数返回当前进程中的各种时间信息,如果目标系统中的任务不能提供类似的时间信息,仅仅实现一个返回-1的空函数,将errno设置为ENOTSUP。
由于newlib认为在目标系统中fcntl、rename和gettimeofday三个桩函数缺省是不提供的,所以也不提供这三个桩函数的实现[2]。
下载newlib
mkdir newlib && cd newlib
wget ftp://sourceware.org/pub/newlib/newlib-4.1.0.tar.gz
#多线程下载
# mwget ftp://sourceware.org/pub/newlib/newlib-4.1.0.tar.gz
tar -xzvf newlib-4.1.0.tar.gz
newlib内容
cd newlib-4.1.0 && ls
ChangeLog COPYING.LIB lt~obsolete.m4 move-if-change
compile COPYING.LIBGLOSS ltoptions.m4 newlib
config COPYING.NEWLIB ltsugar.m4 README
config.guess depcomp ltversion.m4 README-maintainer-mode
config-ml.in djunpack.bat MAINTAINERS setup.com
config.rpath etc Makefile.def src-release
config.sub include Makefile.in symlink-tree
configure install-sh Makefile.tpl texinfo
configure.ac libgloss makefile.vms ylwrap
COPYING libtool.m4 missing
COPYING3 ltgcc.m4 mkdep
COPYING3.LIB ltmain.sh mkinstalldirs
cd newlib && ls
acconfig.h configure.in MAINTAINERS NEWS
acinclude.m4 confsubdir.m4 Makefile.am README
aclocal.m4 doc Makefile.in refcontainers.xslt
ChangeLog HOWTO Makefile.shared stamp-h.in
ChangeLog-2015 iconvdata man.xsl testsuite
configure libc newlib.hin
configure.host libm _newlib_version.hin
编译newlib
cd newlib-4.1.0
cd newlib
# Cross-Compile
./configure --host=aarch64 --target=aarch64-linux-gnu CC=/home/x1/Documents/yishengyishi/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
sudo make all -j16
sudo make install
其中:
gcc 的 build、host 和 target 概念定义如下:
--build:构建 gcc 的平台。
--host:运行 gcc 的平台。
--target:gcc 生成代码的平台
编译结果
参考文献
[1] newlib库介绍以及底层调用研究_weiqi7777的博客-CSDN博客_newlib
[2] Newlib的研究与最小实现_whatday的博客-CSDN博客
[3] newlib-cygwin/newlib/libc/syscalls at master · mirror/newlib-cygwin
[4] The Red Hat newlib C Library
[5] mirror/newlib-cygwin: Cygwin newlib mirror
[6] newlib.pdf