2011-05-04 43 views
2

我正在編寫一個MIPS32仿真器,並希望在使用gcc編譯C程序時可以使用整個標準C庫(可能與GNU擴展)。libc如何工作?

據我所知,在這一點上,I/O由MIPS32架構上的系統調用處理。如何使用libc/glibc成功運行程序,如何判斷需要模擬的系統調用?(沒有反覆試驗)

編輯:請參閱this瞭解我的意思是系統調用的例子。

(您可以檢查出該項目here如果您有興趣,歡迎任何的反饋。記住,這是在一個非常早期)

+0

我是否理解你的問題意味着你想將系統調用傳遞給主機的libc? – Blrfl 2011-05-04 13:03:56

+0

不完全。那麼,從某種意義上說,最終它是主機的系統調用將被執行,例如,程序將一個字符輸出到模擬器的標準輸出。但我並不關心如何管理它,只是模擬器可以執行libc使用的系統調用。 – 2011-05-04 13:15:06

+0

換句話說,我會編寫C++代碼來模擬仿真器中的系統調用。 – 2011-05-04 13:17:12

回答

6

非常簡答

閱讀更長的答案。

簡答

如果您打算提供自定義的libc中的使用您的仿真器的一些功能,將主機OS執行你的系統調用,你必須實現所有的人。

更長的答案

退後一步一分鐘,看東西都在真實(非仿真)系統通常分層的方式:

  1. 外設有一些I/O接口(例如,編號的端口或內存映射),CPU可以使其發癢,使他們能夠做任何事情。
  2. CPU運行了解如何操作硬件的軟件。這可以是一個單一目的程序或運行其他程序的操作系統。由於libc在圖中,我們假設有一個操作系統,它是Unix-y的東西。
  3. 由操作系統運行的用戶空間程序使用自己和操作系統之間定義的接口來要求執行某些「系統」功能。

你試圖完成的任務是在第3層和第2層之間進行,其中libc或用戶代碼中的函數執行OS定義爲觸發系統調用的任何操作。這開闢了蠕蟲的衆多罐:

  • 什麼OS定義爲觸發系統調用從OS到不同的操作系統和同一操作系統的不同版本之間(很少)。通過提供可動態鏈接的libc,可以在「真實」系統上緩解此問題,從而可以隱藏這些細節。除此之外,如果你想運行一個MIPS32二進制文件,它是否使用你的模擬器支持的系統調用約定?

  • 您需要提供一個自定義libc,它可以讓您的模擬器識別出一些特定的系統調用並執行它。您希望運行的任何程序都必須交叉編譯爲MIPS32並與其靜態鏈接,該程序需要的任何其他庫(libm都會想到)。或者,您的模擬器軟件包需要提供動態鏈接器的模擬以及所有必需庫的動態鏈接副本,因爲在主機上打開這些副本將不起作用。如果你有足夠的資源來重新編譯程序,移植可能比模擬更好。

  • 任何對特定系統上的文件路徑進行假設的假設代碼,或者對某些設備(它們本身就是文件)中的特定假設都無法正確運行。

  • 如果您提供的是第2層,那麼您將自行簽名以提供對整個操作系統的特定版本的行爲的完整,正確的模擬。有些電話如read()write()很容易處理;其他人喜歡fork(),uselib()ioctl()會困難得多。您的程序使用的主機操作系統提供的調用和行爲也不一定是一對一映射。所有這些都假定主機是Unix,目標程序也是如此。如果目標是針對其他環境編譯的,則所有投注均關閉。

最後一點就是爲什麼大多數仿真器只提供一個CPU以及一些目標系統的硬件的行爲(即,一切都在第1層)。有了這些,您可以運行原始系統的啓動ROM,操作系統和用戶程序,這些都不會改變。有許多existing MIPS32 emulators這樣做,並且可以運行在他們模擬的硬件上運行的操作系統的未改變版本。

HTH和你的項目中最好的運氣。

+0

@Downvoter,你能解釋爲什麼你認爲這是一個不好的答案? – 2011-05-04 15:54:55

+0

+1對不起,你投下了票......我不是downvoter,但是當有人對此做出很好的回答時,我感到很難受 – Jason 2011-05-04 16:03:33

+0

謝謝你的深入解答。 – 2011-05-05 09:02:14

0

大多數ISO標準C庫的可寫筆直的C.只有少數部分需要訪問較低級別的操作系統功能。

至少,您需要在塊或字符級別模擬fopen,freadfwrite的基本I/O。不過,您可以採用Unix方法,並在較低級別的openreadwrite調用之上實施這些方法。

而且您必須管理動態內存分配mallocfree

setjmplongjmp,它需要訪問執行堆棧。

還有timesignal.h功能。

+0

感謝您的回答,但這並沒有多大幫助。我知道我想要效仿什麼。 gcc編譯的代碼可能會使用系統調用來要求處理器實際執行文件I/O等操作。我想知道這些系統調用代碼是什麼以及他們期望做什麼。例如[SPIM](http://www.doc.ic.ac.uk/lab/secondyear/spim/node8.html)爲基本功能提供了一些系統調用。 – 2011-05-04 15:13:53

+0

Mea culpa;從你的問題中不清楚你的模擬需要什麼水平。我假設你在圖書館級仿效LIBC。 – 2011-05-04 15:34:15

0

我不知道MIPS是如何工作的,但是在Win32上,OS調用必須通過DLL/EXE導入表顯式導入進程。 MIPS系統使用的可執行格式可能有些類似。

+0

比這個低一個或兩個等級。它是我決定使用的任何格式(可能會寫ELF加載器)。 – 2011-05-04 15:27:45

0

通常的做法是不僅模擬CPU,而且模擬一組標準外設。然後,在模擬器中啓動一個包含libc和硬件驅動程序的操作系統。 Libc將調用調用仿真器中虛擬硬件的OSes驅動程序。有關流行示例,請參閱DosBox。

你的問題的另一種解釋是你不想寫一個完整的模擬器,而是一個二進制兼容層,它允許你在非mips32系統上執行mips32二進制文件。 MacOsX(Intel)也可以執行PowerPC應用程序。

在後一種情況下,您需要模擬操作系統ABI(應用程序二進制接口)或者您可以使用libc的ABI。在這兩種情況下,你需要實現仿真器和代理代碼運行在主機上運行的存根代碼:

  • 存根序列化函數調用的參數
  • ...和仿真器內存使用到主機內存發送它們一些特殊的虛擬指令
  • 代理需要打補丁的參數(字節序,整數長度,地址空間...)
  • ...並執行主機系統
  • 的代理,那麼paches和序列化的函數調用傳出函數參數
  • ...,並將它們發送回存根
  • ...返回的數據給調用者

大部分電話都無法與普通的存根/代理的工作,但需要一個特定的解決方案。

祝你好運!