关于newlib中的libgloss和libnosys

版权声明:本文为博主原创文章,转载请保持文章完整,保留作者信息。 https://blog.csdn.net/zoomdy/article/details/82884285

Newlib的构成

Newlib由三部分构成:libgloss、libc、libm,三者在Newlib源代码中的存储位置如下。

  • newlib-x.y.z
    • libgloss
    • newlib
      • libc
      • libm

libc是标准C库,libm是标准数学库,那libgloss是干啥的?

libgloss的作用

Libgloss is a library for all the details that usually get glossed over. This library refers to things like startup code, and usually I/O support for gcc and C library.

这段话的来源:Embed with GNU - Libgloss。也就是说libgloss是提供启动代码和底层I/O支持的。

提供启动代码

libgloss目录下有很多和处理器相关的子目录,例如有子目录armm68ki386mips等。这些子目录下都有一个crt0.S汇编文件,这个就是启动代码所在的源文件了,可能还会有其它的汇编文件,这和具体的处理器有关。

提供底层I/O支持

libgloss目录下还包含底层I/O支持相关的源代码,例如write.c源文件定义了write函数,当程序中引用了printf等标准输出函数时,最终printf会调用write函数进行输出,如果没有定义write函数,那么链接就失败了。

提供底层系统函数

libgloss目录下还包含底层系统函数相关的源代码,例如kill.c源文件定义了kill系统函数,getpid.c源文件定义了getpid系统函数。虽然在libgloss中,很多系统函数都被定义成空函数,没有实际的作用,但对程序完成正常的链接起到重要作用。特别是在引用了第三方库,而第三方库又引用系统函数的情况下,libgloss就显得特别有用了,这种情况下如果没有libgloss那么链接是会失败的。

libnosys是什么鬼

libgloss目录下除了和处理器相关的子目录外,还有个很特别的子目录,那就是libnosys目录,这个目录下的源文件重新定义了libgloss的所有函数,但是所有函数都是空的,例如对照一下libgloss/write.clibgloss/libnosys/write.c这两个文件。

// libgloss/write.c
int
_DEFUN (write, (fd, buf, nbytes),
       int fd _AND
       char *buf _AND
       int nbytes)
{
  int i;

  for (i = 0; i < nbytes; i++) {
    if (*(buf + i) == '\n') {
      outbyte ('\r');
    }
    outbyte (*(buf + i));
  }
  return (nbytes);
}

libgloss/write.c定义的write函数调用用户定义的outbyte函数输出内容。

扫描二维码关注公众号,回复: 3406745 查看本文章
// libgloss/libnosys/write.c
int
_DEFUN (_write, (file, ptr, len),
        int   file  _AND
        char *ptr   _AND
        int   len)
{
  errno = ENOSYS;
  return -1;
}

libgloss/libnosys/write.c定义的write函数设置了错误代码,然后什么也不做,因此纯粹是个stub函数,完全是为了链接通过而定义的。

什么时候需要libnosys

如果程序并不实际使用系统函数,但是某些代码引用了系统函数,那么可以引入libnosys,以便通过编译。

引用libnosys

给GCC传递编译选项-lnosys即可引用libnosys,这时编译器将链接到libnosys.a,这个文件位于ARM GCC安装目录的arm-none-eabi\lib子目录下。

猜你喜欢

转载自blog.csdn.net/zoomdy/article/details/82884285