歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> Linux文化

OSKit包裝系統驅動程序 第五章


第五章 OSKit的應用實例--一個簡單系統的設計與實現


1. 設計目的

OSKit是一個用來幫助我們研發操作系統的工具,如果你想更好的掌握它,除了對其本身進行分析之外,還有一個更加實際的方法,那就是利用這個工具開發一個我們自己的操作系統。

我們開發這個系統的初衷主要是為了學習,因此並沒有想把它設計成像Windows、UNIX那麼復雜。我們的目標是很明確的,那就是在大致搞明白OSKit應當如何使用之後,做一次嘗試,用較短的時間,設計出一個具有一些最基本功能的系統。這對於我們課題組的每名成員來說,都意味著挑戰。


2. 系統的功能

這個系統支持些什麼?這是在開始設計之前我們要首先確定的一個問題。下面列出了一些我們希望實現的功能。
通過Multiboot或者LILO進行系統引導:這個系統可以通過所有支持Multiboot的引導程序進行引導,或者通過引導Linux的LILO進行引導。引導方式可以根據用戶的要求,選擇是通過軟盤還是硬盤。
多線程:用戶可以通過我們提供的系統調用,創建或殺死自己的線程。由於並不支持文件系統,因此新的線程恐怕只能是一個函數了。從理論上講,我們可以讓這個系統支持很多線程,但因為這僅僅是一個簡單的演示性系統,因此我們把線程數限制在32個,當然這個數字也可根據用戶的需求任意更改。
進程間通信:這個系統可以支持一些簡單的進程間通信機制,比如信號量、消息隊列等等。
外設:在眾多的外設之中,我們選擇了應用范圍比較廣的串口。利用目前OSKit所提供的機制,支持更多的設備是不成問題的,但加在這個系統中意義並不十分的大。另外,需要強調的是,訪問串口的方法,是由我們自己規定,不允許用戶更改。
簡單的內存管理:應用程序需要的內存可以通過malloc函數動態申請。


3. 總體構想

在該操作系統中,我們規定用戶只能創建用戶級線程,所有對於核心的操作都將由系統來完成。線程采用RR調度算法,也就是時間片輪轉法,並允許搶占,線程在該系統中有四種狀態,它們是運行態、阻塞態、睡眠態和就緒態,用戶可以設定和改變線程的優先級。在線程中用戶可以動態申請內存,但是需要由用戶來釋放。線程間提供簡單的通信機制,包括信號量和消息隊列。

在設備方面,對於終端,本系統將提供簡單的輸入輸出功能。而對於串口的功能,本系統可以完整的實現,也就是說,用戶既可以從串口讀也可以向串口寫。

為了方便起見,我們為這個系統起一個很簡單的名字,叫acos,這個名字並沒有什麼實際的意義,僅僅為了叫起來方便。

雖然OSKit已經為我們提供了很多設計操作系統所必須的功能,比如內存分配中的malloc函數,通過Multiboot引導等等。然而,仍有許多工作是要由我們自己完成。


4. 我們自己所完成的工作:

4.1 系統的啟動

這裡我們所說的系統啟動,並不是指通常人們所說的通過軟盤或硬盤引導,而是在引導結束之後,操作系統的核心進程如何啟動第一個用戶進程。通常,在UNIX系統中,內核啟動之後,內核程序會去執行文件系統上的init程序,這個程序是整個操作系統中的第一個用戶進程,剩下的進程,都必須通過這個進程才能啟動。在acos中,我們規定,用戶必須要提供一個acos_init()函數,系統在啟動初始化工作全部完成之後,acos_init()函數將被作為系統中的第一個進程啟動。這之後的工作,就完全由用戶來完成了。

當進程acos_init() 結束時,整個系統也將終止運行。

在acos_init()啟動之前,究竟還有哪些事情需要做呢?下面我們就列出要做的事情:

對整個系統進行初始化,注冊設備,檢測設備,初始化設備需要的數據結構,初始化線程庫,創建線程需要的數據結構,初始化使串口能在多線程環境下正常工作的數據結構。

4.2 線程管理

所謂操作系統的線程管理,一般包括了一下的三大部分:線程的創建,線程間通信和線程調度。

線程的創建包括了初始化線程和創建線程的屬性。

線程間通信中,我們使用了信號量,條件變量。

在線程調度中,用戶線程只能使用時間片輪轉法作為調度算法,並且規定在調度過程中調度算法不允許更改。

4.3 外設(串口)

在UNIX系統中,所有的設備都可以通過文件系統進行訪問,讀、寫設備就像讀寫文件一樣。在我們設計的這個acos中,並沒有對文件系統提供支持,也不提供像讀寫文件系統一樣的方法來訪問設備。但是,我們提供一套基本的函數,供用戶線程對串口進行讀寫操作,這些函數專門用於處理串口。

一個設備在同一時刻只能被一個線程使用,因此,在使用設備以前要申請,只有申請成功的線程才能夠使用設備。


5. 使用方法

5.1 安裝

使用者需要在Linux下鍵入 tar -zxvf acos-0.0.1.tar.gz 。

./setup ,詳細的安裝信息請參見README文件。

5.2 使用

根據我們所提供的API手冊編寫自己的應用程序,然後將這些應用程序的源文件編譯成一個filename.o,用戶通過執行acbuild filename.o命令將該應用程序與操作系統內核相鏈接。根據你所希望使用的引導方法執行mkXXXimage命令生成所需要的核心映像,選擇恰當的裝入程序裝入啟動核心映像。

5.3 用戶編程接口

如果您對操作系統的概念有所了解,並詳細閱讀了我們為您提供的技術文檔之後,便可以利用用戶編程接口自行開發了。以下我將向各位詳細介紹每個接口所提供的功能,希望對您能有所幫助。

5.3.1 管理線程的API :

線程創建
ac_thread_create ( void *name, void *arg, int *out_thread_id );
設置線程的優先級
ac_thread_setprio(int thread_id, int pri);
撤銷線程
ac_thread_cancel(int thread_id);
線程休眠
ac_thread_sleep(ac_s64_t millisecond);
將該線程與某一個線程相關聯
ac_thread_join(int tid, void **status);

5.3.2 管理互斥量的API

初始化互斥量
ac_mutex_init ( ac_pthread_mutex_t* mutex,
ac_pthread_mutexattr_t* attr);
設置互斥量協議
ac_mutexattr_setprotocol ( ac_pthread_mutexattr_t* attr,
int protocol);
設置互斥量類型
ac_mutexattr_settype ( ac_pthread_mutexattr_t* attr,
int type);
初始化互斥量屬性
ac_mutexattr_init(ac_pthread_mutexattr_t* attr);
互斥量加鎖
ac_mutex_lock(ac_pthread_mutex_t *mutex);
互斥量解鎖
ac_mutex_unlock(ac_pthread_mutex_t *mutex);
撤銷互斥量
ac_mutex_destroy(ac_pthread_mutex_t *mutex);

5.3.3 管理IPC的API

消息發送( IPC機制 )
ac_ipc_send ( int thread_id, void* msg, ac_size_t msgsize,
ac_s32_t timeout);
3.2消息接受( IPC機制 )
ac_ipc_recv(int thread_id, void* msg, ac_size_t msgsize,
ac_size_t *actual, ac_s32_t timeout);
消息等待( IPC機制 )
ac_ipc_wait(int *src_id, void *msg, ac_size_t msgsize,
ac_size_t *actual, ac_s32_t timeout);
接受同步消息
ac_ipc_reply(int desthread, void *msg, ac_size_t msg_size);
發送同步消息
ac_ipc_call(int dst, void *send_msg, ac_size_t send_msg_size,
void *recv_msg, ac_size_t recv_msg_size,
ac_size_t *actual,ac_s32_t timeout);

5.3.4 管理條件變量的API

條件變量初始化
ac_cond_init(ac_pthread_cond_t *cond,
ac_pthread_condattr_t* attr);
某線程等待條件變量
ac_cond_wait(ac_pthread_cond_t *cond,
ac_pthread_mutex_t *mutex);
喚醒等待該條件變量的線程
ac_cond_signal(ac_pthread_cond_t *cond);
符合條件變量的線程廣播:
ac_cond_broacast(ac_pthread_cond_t *cond);

5.3.5 硬件部分

打開串口
ac_serial_open(int serial_num, ac_u32_t flags);
監聽串口
ac_serial_listen(int serial_num, ac_u32_t flags);
關閉串口
ac_serial_close(ac_ttystream_t* a_stream);
從串口讀
ac_serial_read(ac_ttystream_t* s, void *buf, ac_u32_t len,
ac_u32_t *out_actual);
往串口寫
ac_serial_write(ac_ttystream_t* s, const void *buf,
ac_u32_t len, ac_u32_t *out_actual);

5.4 應用程序示例

為了讓使用者能夠對我們的這個小系統有更加深入的了解,我們制作了一些例子供使用者參考。這些例子包括最簡單的"Hello World",串口讀寫、線程調度、線程間通信,哲學家算法等等。

應用程序的示例可以在examples目錄下找到。


Copyright © Linux教程網 All Rights Reserved