生產者消費者課設報告_第1頁
生產者消費者課設報告_第2頁
生產者消費者課設報告_第3頁
生產者消費者課設報告_第4頁
生產者消費者課設報告_第5頁
已閱讀5頁,還剩22頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、 課程設計目的進行操作系統課程設計主要是在學習操作系統課程的基礎上,在完成操作系統各部分實驗的基礎上,對操作系統的整體進行一個模擬,通過實踐加深對各個部分的管理功能的認識,還能進一步分析各個部分之間的聯系,最后達到對完整系統的理解。同時,可以提高運用操作系統知識解決實際問題的能力;鍛煉實際的編程能力;還能提高調查研究、查閱技術文獻、資料以及編寫軟件設計文檔的能力。課程設計內容與要求模擬仿真“生產者-消費者”問題的解決過程及方法。通過研究Linux的進程機制和信號量,實現生產者消費者問題的并發控制。設計要求:生產者與消費者均有二個以上。生產者和消費者進程的數目在程序界面上可調,在運行時可隨時單個

2、增加與減少生產者與消費者。3) 生產者的生產速度與消費者的消費速度均可在程序界面調節,在運行中,該值調整后立即生效。4) 多個生產者或多個消費者之間必須有共享對緩沖區進行操作的函數代碼。 5) 每個生產者和消費者對有界緩沖區進行操作后,即時顯示有界緩沖區的全部內容、當前生產者與消費者的指針位置,以及生產者和消費者線程標識符。 6) 采用可視化界面,可在運行過程中隨時暫停,查看當前生產者、消費者以及有界緩沖區的狀態。 生產者與消費者問題是經典進程同步問題的典型代表之一。該課程設計通過了解進程間的兩種制約關系,從而理解信號量機制;通過對實例的分析和討論,理解信號量機制實現進程的同步及互斥的方法;通

3、過對經典進程同步問題的剖析,初步掌握運用信號量解決進程同步問題的方法。本系統的功能是根據輸入的生產者進程和消費者進程(緩沖區設為了固定大小20),動態顯示生產者進程從生產“產品”到放入緩沖區,消費者進程從緩沖區中取“產品”的整個過程,同時,系統也顯示了整個過程中緩沖池中臨界資源的變化情況。系統分析與設計系統分析在操作系統中, 線程有時被稱為輕量級進程, 是CPU 使用的基本單位, 它與屬于同一進程的其他進程共享其他代碼段、數據段和其他操作系統資源。在Java 中, 線程的建立有兩種方法: 繼承Thread 類和實現Runnable 接口。其中, 采用實現Runnable 接口建立線程的好處是允

4、許同時繼承其他類從而實現多繼承,并且在Java 中, 可采用synchronized 或Object 類的方法wait( ), notify( ), notifyAll( )來實現多線程同步。Java 多線程同步機制的實現是基于管程(Monitor)機制,在Java 中每個對象都包含一把同步鎖( 管程對象) 和一個線程等待集合, 當對象生成時它們隨之自動生成。線程等待集的初值為空, 同步鎖的初始狀態為開鎖狀態。 只有當對象object 的同步鎖處于開鎖狀態時, 對象object 的synchronized 方法或以對象為同步參數的synchronized 塊( 以下簡稱synchronized

5、 方法( 塊) ) 才允許訪問對象object。當線程thread1 運行對象object 的synchronized方法( 塊) 時, 首先需object 的同步鎖鎖上, thread1將object 上鎖成功后才繼續執行synchronized 方法( 塊) 內語句。當synchronized 方法( 塊) 正常結束或異常退出時, 同步鎖解鎖動作自動執行。Object 類的方法wait( ), notify( )和notifyAll( )可實現線程間的通信。當線程thread1 調用object.wait( )時, 則thread1 停止執行, 將thread1 加入object 的線程等

6、待集, 并解鎖其上鎖的所有對象同步鎖; 當線程thread2 調用object.notify( )時, 從object 的線程等待集中隨機移出一個線程thread3 ( 在Java 語言規范中沒有規定選擇移出線程的算法, 由JVM實現時決定) 去參與線程調度。多個生產者進程在生產產品,并將這些產品提供給消費者進程去消費。為使生產者進程與消費者進程能并發執行,在兩者之間設置了一個具有20個存儲單元的緩沖區,生產者進程將它所生產的產品放入緩沖區中;消費者進程可從緩沖區中取走產品去消費。利用信號量機制來實現多進程(生產者進程和消費者進程)對緩沖區(臨界資源)的互斥訪問。設置多進程的共享變量為臨界資源

7、,同時給它設置一個互斥信號量,多進程利用互斥信號量來完成對臨界資源的互斥訪問(當信號量為某個值是允許進程訪問,否則則不允許進程訪問),從而確保共享數據的正確性。系統設計: 1) 生產者- 消費者問題的提出并發程序在設計上是有困難, 其中最大的問題是進程或者線程間的同步問題, 而生產者消費者問題是最經典的問題之一, 其描述如下: 有n 個生產者和m 個消費者, 連接在一個有k 個單位緩沖區的有界環形緩沖上, pi、cj 都是并發進程, 只要緩沖區未滿, 生產者pi 生產的產品就可以投入緩沖區; 類似地, 只要緩沖區不空, 消費者進程cj 就可以從緩沖區取走并消耗產品。 2) 生產者- 消費者問題

8、的解決模型與Java 實現在下面的Java 應用程序中, 生產者線程向緩沖區中寫數據, 消費者從緩沖區中讀數據, 這樣, 在這個程序中同時運行的多個線程競爭同一個緩沖區資源。類Producer 是生產者模型, 其中的run( )方法中定義了生產者線程所做的操作, 循環地將生產的“產品”放入緩沖區中, 每次生產完后, 調用sleep( )方法睡眠一段隨機時間, 以給其他線程執行的機會。類Consumer是消費者模型, 循環地消費“產品”, 從緩沖區中取出數據, 每次執行完消費操作后, 調用sleep( )方法睡眠一段隨機時間, 以給其他線程執行的機會。同時靠著信號量:mutex、empty、fu

9、ll 來同步多個生產者消費者之間的操作, 表1 列出了各個類在模型中所起到的作用。在Windows中,常見的同步對象有:信號量(Semaphore)、互斥量(Mutex) 。使用這些對象都分為三個步驟,一是創建或者初始化;接著請求該同步對象,隨即進入臨界區,這一步對應于互斥量的上鎖;最后釋放該同步對象,這對應于互斥量的解鎖。這些同步對象在主進程中創建,在其子線程中都可。2、1模塊設計:模式還需要有一個緩沖區處于生產者和消費者之間,作為一個中介。生產者把數據放入緩沖區,而消費者從緩沖區取出數據。大概的結構如下圖。生產者流程圖:阻塞為空阻塞為空否無空緩沖區否無空緩沖區空緩沖區空緩沖區是是結 束 解

10、 鎖緩沖區已滿,請等待生產者生產產品 放入緩沖區對緩沖區加鎖結 束 解 鎖緩沖區已滿,請等待生產者生產產品 放入緩沖區對緩沖區加鎖消費者流程圖:阻塞為空阻塞為空否無滿緩沖區否無滿緩沖區滿緩沖區滿緩沖區是是結 束 解 鎖沒有產品可消費,請等待消費者消費緩沖區內的產品對緩沖區加鎖結 束 解 鎖沒有產品可消費,請等待消費者消費緩沖區內的產品對緩沖區加鎖函數關系圖:OSProject()函數OSProject()函數Producer()函數Consumer()函數OSProject.formBufferPool類緩沖區wait_metux(),signal_metux()供生產者和消費者共享!2、2數

11、據結構說明: (1)Producer類:聲明并創建了Producer類, 定義了生產者的操作。 類Producer 是生產者模型, 其中的run( )方法中定義了生產者線程所做的操作, 循環地將生產的“產品”放入緩沖區中, 每次生產完后, 調用sleep( )方法睡眠一段隨機時間, 以給其他線程執行的機會。(2)Consumer類:聲明并創建了Consumer類,定義了消費者的操作。類Consumer是消費者模型, 循環地消費“產品”, 從緩沖區中取出數據, 每次執行完消費操作后, 調用sleep( )方法睡眠一段隨機時間, 以給其他線程執行的機會。(3)兩個互斥量:Full_Control:

12、當緩沖區滿時迫使生產者等待。 提供信號量full的P V 操作及其阻塞隊列,及消費者阻塞隊列。 Empty_Control:當緩沖區空時迫使消費者等待。提供信號量full的P V 操作及其阻塞隊列,及消費者阻塞隊列。 (4)BufferPool類:聲明并創建了BufferPool類,定義了緩沖區的操作。提供基本數據結構、信號量mutex的P V操作及其阻塞隊列。 有界緩沖區內設有20個存儲單元,放入取出的產品設定為1-20個整數。對緩沖區的生產和消費操作都是互斥訪問,設有互斥量mutex用來實現這個功能。(5)在實現本程序的消費生產模型時,具體地通過如下同步對象實現互斥:一個互斥量mutex,

13、以實現生產者在查詢和保留緩沖區內的下一個空位置時進行互斥。(6)程序中用到的類及每個的屬性和方法: 2、3算法流程圖:生產一條數據生產一條數據等待資源,阻塞等待資源,阻塞是否可用存儲單元是否可用存儲單元 無被喚醒被喚醒 有存入一條數據存入一條數據full數據單元加1,喚醒一個消費者full數據單元加1,喚醒一個消費者生產者算法是否有數據單元是否有數據單元 否等待資源,阻塞等待資源,阻塞 有取走一條數據被喚醒取走一條數據被喚醒empty數據單元加1,喚醒一個生產者empty數據單元加1,喚醒一個生產者消費數據消費數據消費者算法等待訪問臨界資源的線程等待訪問臨界資源的線程置管程為開鎖狀態管程狀態

14、locked置管程為開鎖狀態管程狀態 unlocked獲得管程釋放管程獲得管程釋放管程臨界資源臨界資源 緩沖區算法四、模塊調試與系統測試1、模塊調試輸入的形式:輸入生產者、消費者的個數及速度輸出的形式:以文本框輸出的形式動態展現生產者生產和消費者消費的全過程。程序所能達到的功能:本系統的功能是根據輸入的生產者進程和消費者進程以及緩沖區的大小,動態顯示生產者進程從生產“產品”到放入緩沖區,消費者進程從緩沖區中取“產品”的整個過程,同時,系統也顯示了整個過程中緩沖區中臨界資源的變化情況。2、系統測試測試方法:黑盒測試法黑盒測試(Blackbox Testing,又稱為功能測試或數據驅動測試)是把測

15、試對象看作一個黑盒子。利用黑盒測試法進行動態測試時,需要測試軟件產品的功能,不需測試軟件產品的內部結構和處理過程。黑盒測試試圖發現以下類型的錯誤:功能錯誤或遺漏;界面錯誤;數據結構或外部數據庫訪問錯誤;性能錯誤;初始化或終止錯誤; 測試技術:單元測試 單元測試應用背景:它是從開發者的角度來編寫的,用于確保類的每個特定方法成功執行一系列特定的任務。每一個測試都要保證對于給定的一個已知的輸入應該得到所期望的輸出。測試數據:生產者和消費者的個數初始為0,演示過程中逐個增加進程的個數和隨 時改變生產者和消費者的速度。測試報告:測試結果如下:測試說明測試名稱用多線程同步演示生產者消費者程序測試目的模擬仿

16、真“生產者-消費者”問題的解決過程及方法測試技術單元測試測試方法黑盒測試測試用例測試內容程序各個功能實現水平測試步驟單個增加進程數目輸入合法速度改變速度測試數據生產者加1消費者加13000,2000500,600預期結果程序正確運行生產消費者按輸入速度執行速度明顯改變測試結果與預期相符與預期相符與預期相符測試用例測試內容緩沖區存儲單元變化測試步驟更改進程的數目輸入合法速度改變速度測試數據進程加減1300,20003000,200預期結果緩沖區存儲正常變化緩沖區存儲飽和緩沖區變空測試結果與預期相符與預期相符與預期相符 3、調試分析:根據用戶的實際要求對系統進行初始化并執行程序,其操作的一般流程:

17、系統初始化(設置進程數和緩沖區的大小)、生產者生產資源并存放在緩沖區中、消費者從緩沖區中取資源和消耗資源。不足和缺陷:此程序不便于對較大的數據量的生產者消費者問題進行測試,主要由于設計上的對系統處理的數據量的限制,例如本系統初始化方面設計時將緩沖區大小限制了固定大小。沒有對其中的生產者和消費者設置優先級,在生產者和消費者進程中只是以采用synchronized方法,隨機的確保每個進程都能夠執行,不能滿足用戶某些優先進程的特殊要求。五、用戶手冊1、使用的平臺是:MyEclipse8.5 Swing/MetisseMyEclipse8.5具有如下優勢:快速開發新突破創建杰出的用戶體驗跨越開發周期的

18、協作采用統一整合的方式處理數據體驗全新的web開發工具將數據庫功能整合到應用程序生命周期的管理中下載地址:/tool/myeclipse/17872.html、2、不需要安裝但需要配置文件。下面是我的安裝步驟:1解壓MyEclipse8.5;解壓的時候需要記住解壓目錄;2 選擇工作環境;3. 配置文件前先確認安裝jdk;4 建立目錄E:AndroideclipseMyEclipse;5本程序是用Java語言編寫的,在MyEclipse8.5集成開發環境中運行的。在使程序時,進行運行該程序。程序即進入運行階段。程序運行效果圖:初始化界面及各種功能按鈕:初始生產與消費的結果: 速度改變后生產與消費

19、的結果:緩沖區為滿時的狀態緩沖區為空時的狀態六、程序清單生產者:Producerpublic void run() while (count !=bp.BUFFER_SIZE) ec.wait_empty(); / 等待有空的緩沖區可用bp.wait_mutex(); / 等待緩沖區可用/ 生產產品放入緩沖區bp.bufferbp.in = i;count+;/ 生產者線程使用的下一個緩沖區索引System.out.println( 生產者 + number + 放入了 + i + 個產品);System.out.println(此時緩沖區內有 + count + 個產品);bp.signal

20、_mutex();/ 釋放緩沖池,喚醒可能存在的生產者或消費者線程fc.signal_full();/ 可用的緩沖區數量加1, 喚醒可能存在的消費者線程try int Pspeed =OSProject.PSpeed;sleep(Pspeed);/ 讓線程等待一段時間再運行, 為了模擬而用 catch (InterruptedException e) System.out.println(緩沖區已滿,等待消費者消費產品);消費者 Consumer public void run() while(p.count!=0)fc.wait_full();/ 等待有裝有“產品”的緩沖區可用bp.wait

21、_mutex();/ 等待緩沖池可用/ 消費“產品”System.out.println( 消費者+number+取出了 + i+個產品);p.count-;System.out.println(此時緩沖區內有+p.count+個產品);/ 消費者線程使用的下一個緩沖區索引bp.signal_mutex();/ 釋放緩沖池,喚醒可能存在的生產者或消費者線程ec.signal_empty();/ 可用的空緩沖區數量加1, 喚醒可能存在的生產者線程try int Cspeed =OSProject.CSpeed;sleep(Cspeed);/ 讓線程等待一段時間再運行, 為了模擬而用 catch

22、(InterruptedException e) System.out.println(緩沖區已空,等待生產者生產產品); 緩沖區BufferPoolpublic static final int BUFFER_SIZE = 20;/ 設置緩沖池buffer 的互斥信號量及池中空數據緩沖區、可消費的數據緩沖區的初值public static int mutex = 1, empty = BUFFER_SIZE, full = 0;public int in = 0, out = 0;public int buffer = new intBUFFER_SIZE;public synchroniz

23、ed void wait_mutex() mutex-;if (mutex 0) / 其他線程正在使用緩沖池buffertry wait(); / 在本pool的阻塞隊列中等待 catch (InterruptedException e) public synchronized void signal_mutex() mutex+;if (mutex = 0)notify();/ 喚醒本pool的阻塞隊列中的其他等待使用緩沖池buffer 的線程兩個信號量控制Empty_Controlpublic synchronized void wait_empty() BufferPool.empty-

24、;if (BufferPool.empty 0)try wait(); catch (InterruptedException e) public synchronized void signal_empty() BufferPool.empty+;if (BufferPool.empty = 0)notify();Full_Controlpublic synchronized void wait_full() BufferPool.full-;if (BufferPool.full 0)try wait(); catch (InterruptedException e) public syn

25、chronized void signal_full() BufferPool.full+;if (BufferPool.full = 0)notify();七、體會與自我評價通過此次課程設計過程,使我通過實際實踐來更加了解計算機操作系統的知識,至少比以前更加了解生產者消費者問題,應該不會出現題不會做的現象,特別是通過做“生產者消費者”經典同步問題,對進程的運行方式、以及如何確保計算機操作系統既保持同步又保持互斥的對臨界資源的訪問來同時進行多任務工作。通過對信號量以及管程機制的引入,使得對臨界資源的 使用更加有效,多任務的準確性得以保證。從Java 的多線程機制出發, 研究了操作系統中經典的同

26、步問題生產者消費者問題, 提出了兩種解決此問題的模型, 及其Java 解決方案。提出的兩個模型充分利用了Java 中面向對象和管程機制, 模擬了操作系統中進程同步的經典問題生產者消費者問題。在第一個模型中, 我們按照生產者消費者問題典型的解決方案給出了Java 解決模型; 在第二個模型中, 我們分析了信號量mutex 在問題中所起的作用, 并為了提高緩沖區讀寫的效率, 提出了將信號量mutex 分為兩個分別控制生產者和消費者的信號量,并討論了此方案的可行性。在Java 中, 線程的建立有兩種方法: 繼承Thread 類和實現Runnable 接口。其中, 采用實現Runnable 接口建立線程

27、的好處是允許同時繼承其他類從而實現多繼承,并且在Java 中, 可采用synchronized 或Object 類的方法wait( ), notify( ), notifyAll( )來實現多線程同步。Java 多線程同步機制的實現是基于管程(Monitor)機制,在Java 中每個對象都包含一把同步鎖( 管程對象) 和一個線程等待集合, 當對象生成時它們隨之自動生成。線程等待集的初值為空, 同步鎖的初始狀態為開鎖狀態。課程設計的收獲: 1.程序的設計思想的精巧的重要性,是不管怎么說都不為過的,好的設計可以讓大家很快的明白你的思想,而且很方便的來實現它。 2.良好的編程習慣,它可以使你的程序很

28、方便的被別人閱讀,也很方便的被更改,所以可以的話,盡可能多的寫出注釋,使程序簡潔明了。 3.基本的語言功底一定要扎實。 4.在實現各個功能的過程中,細心和耐心是必不可少的。八、參考文獻1 湯子瀛 編著,計算機操作系統(修訂版) 西安電子科技大學出版社,2001年2 胡明慶,高巍,鐘梅 操作系統教程與實驗 清華大學出版社 2007.1 3 丁振凡主編,薛清華副主編 java程序語言設計 清華大學出版社 2010.104李善平 操作系統學習指導和考試指導 浙江大學出版社2004 年 九、課程設計評價課程設計評價 成績: 教師: 年 月 日附錄資料:不需要的可以自行刪除 busybox詳解制作根文件

29、系統詳解制作根文件系統 一、FHS(Filesystem Hierarchy Standard)標準介紹當我們在linux下輸入ls / 的時候,見到的目錄結構以及這些目錄下的內容都大同小異,這是因為所有的linux發行版在對根文件系統布局上都遵循FHS標準的建議規定。該標準規定了根目錄下各個子目錄的名稱及其存放的內容:目錄名存放的內容/bin必備的用戶命令,例如ls、cp等/sbin必備的系統管理員命令,例如ifconfig、reboot等/dev設備文件,例如mtdblock0、tty1等/etc系統配置文件,包括啟動文件,例如inittab等/lib必要的鏈接庫,例如C鏈接庫、內核模塊/

30、home普通用戶主目錄/rootroot用戶主目錄/usr/bin非必備的用戶程序,例如find、du等/usr/sbin非必備的管理員程序,例如chroot、inetd等/usr/lib庫文件/var守護程序和工具程序所存放的可變,例如日志文件/proc用來提供內核與進程信息的虛擬文件系統,由內核自動生成目錄下的內容/sys用來提供內核與設備信息的虛擬文件系統,由內核自動生成目錄下的內容/mnt文件系統掛接點,用于臨時安裝文件系統/tmp臨時性的文件,重啟后將自動清除制作根文件系統就是要建立以上的目錄,并在其中建立完整目錄內容。其過程大體包括:編譯安裝busybox,生成/bin、/sbin

31、、/usr/bin、/usr/sbin目錄 利用交叉編譯工具鏈,構建/lib目錄 手工構建/etc目錄 手工構建最簡化的/dev目錄 創建其它空目錄 配置系統自動生成/proc目錄 利用udev構建完整的/dev目錄 制作根文件系統的jffs2映像文件 下面就來詳細介紹這個過程。二、編譯安裝busybox,生成/bin、/sbin、/usr/bin、/usr/sbin目錄這些目錄下存儲的主要是常用命令的二進制文件。如果要自己編寫這幾百個常用命令的源程序,my god, 這簡直是一個噩夢!好在我們有嵌入式Linux系統的瑞士軍刀busybox,事情就簡單很多。1、從 HYPERLINK / /

32、下載busybox-1.7.0.tar.bz22、tar xjvf busybox-1.7.0.tar.bz2解包3、修改Makefile文件175 ARCH ?= arm176 CROSS_COMPILE ?= arm-linux- 4、make menuconfig配置busyboxbusybox配置主要分兩部分。第一部分是Busybox Settings,主要編譯和安裝busybox的一些選項。這里主要需要配置:1)、Build Options - Build BusyBox as a static binary (no shared libs),表示編譯busybox時,是否靜態鏈接C

33、庫。我們選擇動態鏈接C庫。2)、Installation Options - Applets links (as soft-links) - (X) as soft-links,表示安裝busybox時,將各個命令安裝為指向busybox的軟鏈接還是硬鏈接。我們選擇軟鏈接。3)、Installation Options - (/work/nfs_root/fs_mini3) BusyBox installation prefix,表示busybox的安裝位置。我們選擇/work/nfs_root/fs_mini34)Busybox Library Tuning。保留Command line e

34、diting以支持命令行編輯;保留History size以支持記憶歷史命令;選中Tab completion和Username completion以支持命令自動補全 第二部分是Applets,他將busybox的支持的幾百個命令分門別類。我們只要在各個門類下選擇想要的命令即可。這里我們基本保持默認設置。1)選中Networking Utilities - httpd下的Enable -u option,以啟用http服務器的功能allows the server to run as a specific user5、編譯busyboxmake6、安裝busyboxmake install安

35、裝完成后,可以看到在/work/nfs_root/fs_mini3目錄下生成了binsbinusr/binusr/sbin目錄,其下包含了我們常用的命令,這些命令都是指向bin/busybox的軟鏈接,而busybox本身的大小不到800K:dennisdennis-desktop:/work/nfs_root/fs_mini3$ lsbin linuxrc sbin usrdennisdennis-desktop:/work/nfs_root/fs_mini3$ ls -l bintotal 740lrwxrwxrwx 1 dennis dennis 7 2010-04-03 23:57 a

36、ddgroup - busyboxlrwxrwxrwx 1 dennis dennis 7 2010-04-03 23:57 adduser - busyboxlrwxrwxrwx 1 dennis dennis 7 2010-04-03 23:57 ash - busybox-rwxr-xr-x 1 dennis dennis 749632 2010-04-03 23:57 busyboxlrwxrwxrwx 1 dennis dennis 7 2010-04-03 23:57 cat busybox 而普通PC機上的ls命令就有差不多80K的大小: dennisdennis-desktop

37、:/work/nfs_root/fs_mini3$ ls -l /bin/ls-rwxr-xr-x 1 root root 78004 2007-09-29 20:51 /bin/ls busybox以它嬌小的身軀容納了數以百計的命令代碼,實在是讓人佩服不已,其不愧嵌入式系統瑞士軍刀之美譽。據說,busybox的作者身患絕癥,這更讓人欽佩GNU開源軟件的作者們。 三、利用交叉編譯工具鏈,構建/lib目錄 光有應用程序(命令)是不夠的,因為應用程序本身需要使用C庫的庫函數,因此還必需制作for ARM的C庫,并將其放置于/lib目錄。my god,要自己寫C庫的源代碼嗎?不用!還記得交叉編譯工具

38、鏈的3個組成部分嗎?交叉編譯器、for ARM的C庫和二進制工具。哈哈,for ARM的C庫是現成的,我們只需要拷貝過來就可以了。遺憾的是:整個C庫目錄下的文件總大小有26M。而我們根文件系統所在分區不過區區16M而已,根本放不下。怎么辦呢? dennisdennis-desktop:/work/nfs_root/fs_mini3$ du -s -si /work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib26M /work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib 需要C庫目錄下所有的文件嗎?no,absolu

39、tely no! 讓我們來分析一下glibc庫目錄下內容的組成。該目錄下的子目錄和文件共分8類: 目標文件,如crtn.o,用于gcc鏈接可執行文件 libtool庫文件(.la),在鏈接庫文件時這些文件會被用到,比如他們列出了當前庫文件所依賴的其它庫文件,程序運行時無需這些文件 gconv目錄,里面是各種鏈接腳本,在編譯應用程序時,他們用于指定程序的運行地址,各段的位置等 靜態庫文件(.a),例如libm.a,libc.a 動態庫文件 (.so、.so.0-9*) 動態鏈接庫加載器ld-2.3.6.so、ld-linux.so.2 其它目錄及文件很顯然,第1、2、3、4、7類文件和目錄是不需

40、要拷貝的。由于動態鏈接的應用程序本身并不含有它所調用的C庫函數的代碼,因此執行時需要動態鏈接庫加載器來為它加載相應的C庫文件,所以第6類文件是需要拷貝的。除此之外,第5類文件當然要拷貝。但第5類文件的大小也相當大。dennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ du -c -si *.so* 7.2M total 需要全部拷貝嗎?非也,非也!其實,需要哪些庫完全取決于要運行的應用程序使用了哪些庫函數。如果我們只制作最簡單的系統,那么我們只需要運行busybox這一個應用程序即可。通過執行 dennisd

41、ennis-desktop:/work/nfs_root/fs_mini3$ arm-linux-readelf -a bin/busybox | grep Shared0 x00000001 (NEEDED) Shared library: libcrypt.so.10 x00000001 (NEEDED) Shared library: libm.so.60 x00000001 (NEEDED) Shared library: libc.so.6 可知:busybox只用到了3個庫:通用C庫(libc)、數學庫(libm)、加密庫(libcrypt),因此我們只需要拷貝這3個庫的庫文件即可

42、。但是每個庫都有4個文件,4個文件都要拷貝嗎?當然不是。 dennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ ls -l libcrypt.-*-rwxr-xr-x 1 dennis dennis 30700 2008-01-22 05:32 libcrypt-2.3.6.so-rw-r-r- 1 dennis dennis 23118 2008-01-22 05:32 libcrypt.alrwxrwxrwx 1 dennis dennis 13 2008-12-22 15:38 libcrypt.so

43、- libcrypt.so.1lrwxrwxrwx 1 dennis dennis 17 2008-12-22 15:38 libcrypt.so.1 - libcrypt-2.3.6.sodennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ ls -l libm.-*-rwxr-xr-x 1 dennis dennis 779096 2008-01-22 05:31 libm-2.3.6.so-rw-r-r- 1 dennis dennis 1134282 2008-01-22 05:32 libm.alr

44、wxrwxrwx 1 dennis dennis 9 2008-12-22 15:38 libm.so - libm.so.6lrwxrwxrwx 1 dennis dennis 13 2008-12-22 15:38 libm.so.6 - libm-2.3.6.sodennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ ls -l libc.-*-rwxr-xr-x 1 dennis dennis 1435660 2008-01-22 05:48 libc-2.3.6.so-rw-r-r- 1 dennis

45、 dennis 2768280 2008-01-22 05:31 libc.a-rw-r-r- 1 dennis dennis 195 2008-01-22 05:34 libc.solrwxrwxrwx 1 dennis dennis 13 2008-12-22 15:38 libc.so.6 - libc-2.3.6.so 4個文件中的.a文件是靜態庫文件,是不需要拷貝的。另外3個文件是: 實際的共享鏈接庫:libLIBRARY_NAME-GLIBC_VERSION.so。當然需要拷貝。 主修訂版本的符號鏈接,指向實際的共享鏈接庫:libLIBRARY_NAME.so.MAJOR_REVI

46、SION_VERSION,程序一旦鏈接了特定的鏈接庫,將會參用該符號鏈接。程序啟動時,加載器在加載程序前,會檢索該文件。所以需要拷貝。 與版本無關的符號鏈接,指向主修訂版本的符號連接(libc.so是唯一的例外,他是一個鏈接命令行:libLIBRARY_NAME.so,是為編譯程序時提供一個通用條目)。這些文件在程序被編譯時會被用到,但在程序運行時不會被用到,所以不必拷貝它。關于共享庫的2個符號鏈接的作用的特別說明:當我們使用gcc hello.c -o hello -lm編譯程序時,gcc會根據-lm的指示,加頭(lib)添尾(.so)得到libm.so,從而沿著與版本無關的符號鏈接(lib

47、m.so - libm.so.6)找到libm.so.6并記錄在案(hello的ELF頭中),表示hello需要使用libm.so.6這個庫文件所代表的數學庫中的庫函數。而當hello被執行的時候,動態鏈接庫加載器會從hello的ELF頭中找到libm.so.6這個記錄,然后沿著主修訂版本的符號鏈接(libm.so.6 - libm-2.3.6.so)找到實際的共享鏈接庫libm-2.3.6.so,從而將其與hello作動態鏈接。可見,與版本無關的符號鏈接是供編譯器使用的,主修訂版本的符號鏈接是供動態鏈接庫加載器使用的,而實際的共享鏈接庫則是供應用程序使用的。通過以上分析,我們只需要拷貝3個庫

48、(每個庫各1個主修訂版本的符號鏈接和1個實際的共享鏈接庫)以及動態鏈接庫加載器(1個符號鏈接和1個實體文件)。步驟如下:dennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ mkdir /work/nfs_root/fs_mini3/lib dennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp libcrypt-* /work/nfs_root/fs_mini3/libdennisdennis-desktop:/wor

49、k/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp -l libcrypt.so.* /work/nfs_root/fs_mini3/libdennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp libm-* /work/nfs_root/fs_mini3/libdennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp -l libm.so.* /work/nfs_root/

50、fs_mini3/libdennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp libc-* /work/nfs_root/fs_mini3/libdennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib$ cp -l libc.so.* /work/nfs_root/fs_mini3/lib dennisdennis-desktop:/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/li

51、b$ cp -l ld-* /work/nfs_root/fs_mini3/lib 四、手工構建/etc目錄 /etc目錄存放的是系統程序的主配置文件,因此需要哪些配置文件取決于要運行哪些系統程序。即使最小的系統也一定會運行1號用戶進程init,所以我們至少要手工編寫init的主配置文件inittab。busybox的inittab文件的語法、語義與傳統的SYSV的inittab有所不同。 inittab文件中每個條目用來定義一個需要init啟動的子進程,并確定它的啟動方式,格式為:。例如:ttySAC0:askfirst:-/bin/sh 表示子進程要使用的控制臺,若省略則使用與init進程

52、一樣的控制臺 表示運行級別,busybox init程序這個字段沒有意義 表示init進程如何控制這個子進程 sysinit:系統啟動后最先執行,只執行一次,init進程等待它結束后才繼續執行其它動作 wait:系統執行完sysinit條目后執行,只執行一次,init進程等待它結束后才繼續執行其它動作 once:系統執行完wait條目后執行,只執行一次,init進程不等待它結束 respawn:啟動完once進程后,init進程監測發現子進程退出時,重新啟動它 askfirst:啟動完respawn進程后,與respawn類似,不過init進程先輸出” Please press Enter t

53、o activate this console“,等用戶輸入回車后才啟動子進程 shutdown:當系統關機時 restart:Busybox中配置了CONFIG_FEATURE_USE_INITAB,并且init進程接收到SIGUP信號時執行,先重新讀取、解析/etc/inittab文件,再執行restart程序 ctrlaltdel:按下ctrl+alt+del鍵時執行,不過在串口控制臺中無法輸入它 表示進程對應的二進制文件。如果前面有-號,表示該程序是“可以與用戶進行交互的”我們制作最簡單的/etc/inittab文件,其內容如下::sysinit:/etc/init.d/rcS:ask

54、first:-/bin/sh:ctrlaltdel:/sbin/reboot:shutdown:/bin/umount -a r 制作最簡單的腳本程序文件/etc/init.d/rcS,其內容如下: #!/bin/shifconfig eth0 7修改shell腳本文件/etc/init.d/rcS的權限,以使其可被執行:# chmod a+x /etc/init.d/rcS五、手工構建最簡化的/dev目錄 在linux機器上,執行ls /dev可看到幾百個設備文件,我需要手工創建它們嗎?maybe,我只需要手工創建幾個設備文件!我怎么知道我應該創建哪幾個設備文件呢?管它呢,先看看開發板上可愛

55、的linux的反應再說。 啟動Linux操作系統,顯示: VFS: Mounted root (nfs filesystem).Freeing init memory: 112KWarning: unable to open an initial console. 這說明,內核已經成功掛載根文件系統,但卻未能成功啟動第1個用戶進程init。通過錯誤消息“unable to open an initial console”搜索內核源代碼,找到init/main.c文件。748 static int noinline init_post(void)749 750 free_initmem();75

56、1 unlock_kernel();752 mark_rodata_ro();753 system_state = SYSTEM_RUNNING;754 numa_default_policy();755 756 if (sys_open(const char _user *) /dev/console, O_RDWR, 0) 0)757 printk(KERN_WARNING Warning: unable to open an initial console.n);758 759 (void) sys_dup(0);760 (void) sys_dup(0);761 762 if (ram

57、disk_execute_command) 763 run_init_process(ramdisk_execute_command);764 printk(KERN_WARNING Failed to execute %sn,765 ramdisk_execute_command);766 767 768 /*769 * We try each of these until one succeeds.770 *771 * The Bourne shell can be used instead of init if we are772 * trying to recover a really

58、 broken machine.773 */774 if (execute_command) 775 run_init_process(execute_command);776 printk(KERN_WARNING Failed to execute %s. Attempting 777 defaults.n, execute_command);778 779 run_init_process(/sbin/init);780 run_init_process(/etc/init);781 run_init_process(/bin/init);782 run_init_process(/bi

59、n/sh);783 784 panic(No init found. Try passing init= option to kernel.);785 顯然,內核錯誤是由175行不能打開/dev/console所致。通過查看已經安裝好的linux機器的/dev/console設備文件,可知其是字符設備文件,主設備號為5,次設備號為1: dennisdennis-desktop:/work/nfs_root/fs_mini3/etc$ ls -l /dev/consolecrw 1 root root 5, 1 2010-04-08 08:40 /dev/console 因此,我們使用下面的命令

60、創建它: HYPERLINK mailto:dennisdennis-desktop:/work/nfs_root/fs_mini3/dev$ dennisdennis-desktop:/work/nfs_root/fs_mini3/dev$ sudo mknod console c 5 1 還需要創建其它設備文件嗎?只有天知道!再看看linux的反應。 VFS: Mounted root (nfs filesystem).Freeing init memory: 112Kinit: cant open /dev/null: No such file or directory 這次我們有經驗了

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論