uClinux和Linux的異同分析

來源:互聯網
上載者:User

標準Linux是針對有MMU的處理器設計的。在這種處理器上,虛擬位址被送到MMU,把虛擬位址映射為物理地址。通過賦予每個任務不同的虛擬-物理地址轉換映射,支援不同任務之間的保護。uClinux是針對控制領域的嵌入式linux作業系統,它從Linux 2.0/2.4核心派生而來,沿襲了主流Linux的絕大部分特性。適合不具備記憶體治理單元(MMU)的微處理器/微控制器。沒有MMU支援是uClinux與主流Linux的基本差異。
        對uCLinux來說,其設計針對沒有MMU的處理器,不能使用處理器的虛擬記憶體治理技術。uCLinux仍然採用儲存空間的分頁治理,系統在啟動時把實際儲存空間進行分頁。在載入應用程式時程式分頁載入。但是由於沒有MMU治理,所以實際上uCLinux採用實儲存空間治理策略。uCLinux系統對於記憶體的訪問是直接的,所有程式中訪問的地址都是實際的物理地址。作業系統對記憶體空間沒有保護,各個進程實際上共用一個Runspace。一個進程在執行前,系統必須為進程分配足夠的連續地址空間,然後全部載入主儲存空間的連續空間中。同時,uClinux有著非凡小的核心和使用者軟體空間。熟悉主流Linux的開發人員會注重到在uClinux下工作的微小差異,但同樣也可以很快熟悉uclinux的一些特性。對於設計核心或系統空間的應用程式的開發人員,要非凡注重uClinux既沒有記憶體保護,也沒有虛擬記憶體模型,另外,有些核心系統調用也有差異。 
1.1 記憶體保護
  沒有記憶體保護(Memory Protection)的操作會導致這樣的結果:即使由無特權的進程來調用一個無效指標,也會觸發一個地址錯誤,並潛在地引起程式崩潰,甚至導致系統的掛起。顯然,在這樣的系統上啟動並執行代碼必須仔細編程,並深入測試來確保健壯性和安全。
對於普通的Linux來說,需要運行不同的使用者程式,假如沒有記憶體保護將大大降低系統的安全性和可*性;然而對於嵌入式uClinux系統而言,由於所啟動並執行程式往往是在出廠前已經固化的,不存在危害系統安全的程式侵入的隱患,因此只要應用程式經過較完整的測試,出現問題的機率就可以控制在有限的範圍內。

1.2 虛擬記憶體
  沒有虛擬記憶體(Virtual Memory)主要導致下面幾個後果:
首先,由核心所載入的進程必須能夠獨立運行,與它們在記憶體中的位置無關。實現這一目標的第一種辦法是一旦程式被載入到RAM中,那麼程式的基準地址就“固定”下來;另一種辦法是產生只使用相對定址的代碼(稱為“位置無關代碼”,Position Independent Code,簡稱PIC)。uClinux對這兩種模式都支援。
         其次,要解決在扁平(flat)的記憶體模型中的記憶體配置和釋放問題。非常動態記憶體配置會造成記憶體片段,並可能耗盡系統的資源。對於使用了動態記憶體分配的那些應用程式來說,增強健壯性的一種辦法是用預分配緩衝區池(Preallocated buffer pool)的辦法來取代malloc()調用。由於uclinux中不使用虛擬記憶體,進出記憶體的頁面交換也沒有實現,因為不能保證頁面會被載入到RAM中的同樣位置。在普通電腦上,作業系統答應應用程式使用比實體記憶體(RAM)更大的記憶體空間,這往往是通過在硬碟上設立交換分區來實現的。但是,在嵌入式系統中,通常都用FLASH儲存空間來代替硬碟,很難高效地實現記憶體頁面交換的存取,因此,對啟動並執行應用程式都限制其可分配空間不大於系統的RAM空間。 

        最後,uClinux目標板處理器缺乏記憶體治理的硬體單元,使得Linux的系統介面需要作些改變。有可能最大的不同就是沒有fork()和brk()系統調用。 調用fork()將複製出進程來建立一個子進程。在Linux下,fork()是使用copy-on-write頁面來實現的。由於沒有MMU,uclinux不能完整、可*地複製一個進程,也沒有對copy-on-write的存取。為了彌補這一缺陷,uClinux實現了vfork(),當父進程調用vfork()來建立子進程時,兩個進程共用它們的全部記憶體空間,包括堆棧。子進程要麼代替父進程執行(此時父進程已經sleep)直到子進程調用exitI()退出,要麼調用exec()執行一個新的進程,這個時候將產生可執行檔的載入。即使這個進程只是父進程的拷貝,這個過程也不能避免。當子進程執行exit()或exec()後,子進程使用wakeup把父進程喚醒,父進程繼續往下執行。
         注重,多任務並沒有受影響。哪些舊式的、廣泛使用fork()的網路背景程式(daemon)的確是需要修改的。由於子進程運行在和父進程同樣的地址空間內,在一些情況下,也需要修改兩個進程的行為。
         很多現代的程式依靠子進程來執行基本任務,使得即時在進程負載很重時,系統仍可以保持一種“可互動”的狀態,這些程式可能需要實質上的修改來在uClinux下完成同樣的任務。假如一個要害的應用程式非常依靠這樣的結構,那就不得不對它重新編寫了。 M開發論壇
  假設有一個簡單的網路背景程式(daemon),大量使用了fork()。這個daemon總監聽一個知名連接埠(或通訊端)等待網路用戶端來串連。當用戶端串連時,這個daemon給它一個新的串連資訊(新的socket編號),並調用fork()。子進程接下來就會和用戶端在新的socket上進行串連,而父進程被釋放,可以繼續監聽新的串連。
uClinux 既沒有自動生長的堆棧,也沒有brk()函數,這樣,使用者空間的程式必須使用mmap() 命令來分配記憶體。為了方便,在uclinux的C語言庫中所實現的malloc()實質上就是一個mmap()。在編譯時間,可以指定程式的堆棧大小。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.