在安卓的內核裏讓一隻純種Linux程序跑起來

linux啓動一個二進制程序

linux程序在用戶態啓動運行時,會內核先自己搞一些小動作:

fork-》複製頁表-》複製VMA(PTE)-》copyprocess()(好像是這個)-》copythread()(好像是這個)-》僞裝好進程執行時的現場、

初始化調度相關的東西-》加入可執行隊列等待調度-》其餘的啥忘了

若是在shell執行的程序,調度到所執行程序時,可能shell會有exec來加載程序代碼,

但是也不是一次性全加載,記錄下硬盤可執行文件每部分的地址,和載入內存後的地址(虛址),

這就算加載完了。當調度到程序執行缺代碼時,會缺中然後去硬盤讀代碼。


堆棧細節

linux程序的棧、堆

本質上,棧應該算是數據結構,或者應該算是一種內存使用方式,並不是說有一個東西叫棧。

程序執行的規則裏,局部變量、函數調用,按照FILO的方式往一段內存裏寫。就有了棧,於是爲什麼會爆棧。

另:內核知不知道棧?

知道的,內核多精,一看這貨吃完不拉直往外吐;點點頭,這貨是棧,限制一下大小,吃多了不吐就炸了它。

malloc等的就在堆,就是個垃圾堆。垃圾吃多了,一不小心就會頂破棧,這也是一種程序異常。


解釋器細節

linux程序的解釋器

不要誤會,這裏說的不是shell類的解釋語言。就是二進制程序,linux的二進制程序是需要解釋器的。

在所有的linux中(包括完成閹割的小android)

/lib下(安卓/system/lib下),有一個ld-*.so,搜索了NNNN多東西,沒找到他是做什麼的

最終再oracle linux的相關文檔裏查到ld-*.so,是一個運行時解釋器,調用了.so的運行的程序是要依靠ld-*.so找到動態庫運行的。

注意,對ld-*.so的調用應該是在sh fork完進程,執行exevc()時調用。

這也是純種普通的編譯成aarch64指令的linux程序爲什麼不能在安卓直接執行;

因爲猥瑣的谷歌,在AndroidO上用了不同的解釋器叫ld-android.so

於是,linux應用來安卓的時候請自備解釋器(解釋器文件名是相關的)。


如生孩子般複雜的製作-linux二進制程序的生產過程

預處理->編譯->彙編->鏈接

預處理

這一過程將所有宏打開,此時C還是C,但是宏卻不是宏了。。。

這裏需要指出,預處理階段有豐富的編譯選項

-Werror 可以輕易讓你的警告變成錯誤(想編譯?見鬼去吧!)

-Wtraditional 代碼遵循ISO C會產生警告(打不斷你煩死你)

-Wall 開啓所有警告(強迫症必選,注入char 和unsigned char撲面而來)

。。。總之,正事不少,花活兒也挺多。但大致與平臺無關。

編譯

這一步是非常複雜的操作,由gcc的神奇大隊長gcc-core來做,gcc-core會進行詞法分析(感謝有詞法分析,不然鬼才知道把define都落實了的鬼畫符會是什麼東西。不過就算有詞法分析,也就語法分析有可能—————————————


。。。。這篇blog有點古老,不太全了,還有一截不知道哪兒去了,等找到了再續上

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章