天天看點

關于newlib中的libgloss和libnosysNewlib的構成libgloss的作用libnosys是什麼鬼什麼時候需要libnosys引用libnosys

關于newlib中的libgloss和libnosys

  • Newlib的構成
  • libgloss的作用
    • 提供啟動代碼
    • 提供底層I/O支援
    • 提供底層系統函數
  • libnosys是什麼鬼
  • 什麼時候需要libnosys
  • 引用libnosys

libgloss提供啟動代碼、底層I/O支援、底層系統函數。libnosys提供空的底層系統函數以便程式通過編譯。

https://blog.csdn.net/zoomdy/article/details/82884285

mingdu.zheng at gmail dot com

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目錄下有很多和處理器相關的子目錄,例如有子目錄arm、m68k、i386、mips等。這些子目錄下都有一個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.c和libgloss/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

函數輸出内容。

// 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子目錄下。