1. 程式人生 > 實用技巧 >課程學習總結報告

課程學習總結報告

這門課程剛開始的時候,孟老師將Linux核心與其他各個模組的關係用非常簡潔而又形象的圖畫表示出來,我認為,這張圖對任何一個Linux小白,都有非常好的引導意義,是Linux核心模型大的框架,如下圖所示。

經過大半個學期的學期,我也對Linux核心有了更多的認識。在我看來,作為作業系統最關鍵的一部分,Linux核心是連線計算機軟硬體的橋樑,起到了非常關鍵的承上啟下作用。向上延伸,它提供了各式各樣基礎且關鍵的API介面,供上層庫函式和程式通過系統呼叫來使用;向下延伸,它直接對接硬體設施。也就是說,Linux核心是一個“中介”,向“客戶”(應用程式)提供服務,並將“客戶”需求轉化為“施工方”(硬體)能夠理解的概念,以便專案落地。

對Linux核心模型再進一步瞭解,可以按照功能模組,再細分成程序管理、記憶體管理、虛擬檔案系統、網路系統和程序間通訊,如下圖所示。

1、程序管理:管理最核心的CPU資源,保證各個程序能夠合理地利用CPU資源完成自身任務。

2、記憶體管理:管理記憶體資源,使得記憶體被程序安全使用。

3、虛擬檔案系統:為方便對外設進行管理,將如硬碟、光碟等外設均抽象為虛擬檔案,Linux核心提供諸如open、write、read等介面函式對其統一管理。

4、網路系統:管理涉及網路操作的資源。

5、程序間通訊:為程序間交流資源提供渠道。

其中,程序管理為Linux核心最重要的部分,因為在作業系統中,程序是程式執行的動態實體,所有程序的工作開展都要依託於Linux核心的程序排程,其相互關係如下圖所示。

最終程式以程序的形式得到CPU資源而執行,當其需要調動下層資源時,會向Linux作業系統核心發出系統呼叫請求,執行環境從使用者態轉向核心態,在某個時間節點,完成預期功能,再返回使用者態繼續執行。

以上即為基於本人的有限認識對Linux系統概念模型的總結,接下來以“讀取檔案”的一系列流程為例,進一步完善對模型的認識

作業系統讀檔案hello.txt,大體可以劃分為如下流程:

1、為讀入檔案做準備

在例項程式執行到read函式時,軟中斷int 0x80通過中斷描述符表,跳到system_call,最後跳轉至system_read去執行.

int sys_read(unsigned int fd, char * buf, int count) {
  ……
  if (fd >= NR_OPEN || count < 0 || !(file = curren t-> file[fd]))    
  ……
return file_read(inode, file, buf, count); }

先檢查輸入引數的合理性,最後呼叫file_read函式讀取檔案。

2、確定要檔案內容的位置

int file_read(struct m_inode * inode, struct file * flip, char * buf, int count) { 
    …… 
    while(left) {
  if (nr = bmap(inode, (flip->f_pos)/BLOCK_SIZE))
           …… 
    } 
    ……
}

在while迴圈中,根據資料的實際組織方式,確定檔案內容在硬碟上的“塊號”。

3、將指定資料從硬碟讀至系統緩衝區

以硬體的“塊號”和“裝置號”為依據,從硬碟中將hello.txt對應的資料塊讀入緩衝區。

int file_read(struct m_inode * inode, struct file * flip, char * buf, int count) { 
    …… 
  if(!(bh=bread(inode->i_dev, nr))) …… }

inode->i_dev為硬碟裝置號,nr為具體塊號,bread函式為讀盤指令。一旦開始從硬碟讀取資料,程序便轉為不可中斷的狀態,直到資料全部讀入緩衝區。

從中可以看出,上層程式讀取檔案時無需知曉任何具體硬體知識,由Linux核心完成涉及到底層的資料操作。

4、將資料拷貝至程式執行的指定空間

先檢測是否讀完指定的資料量

int file_read(struct m_inode * inode, struct file * flip, char * buf, int count) { 
    …… 
  while(left) {
    ……
    nr = filp->f_pos % BLOCK_SIZE;
chars = MIN(BLOCK_SIZE - nr, left);
    ……
} …… }

若沒有讀完,更新left的值,確定具體還有多少沒有讀完

int file_read(struct m_inode * inode, struct file * flip, char * buf, int count) { 
    …… 
  while(left) {
    ……
    filp->f_pos += chars;
left -= chars;
    ……
} …… }

最後把已經讀出來的資料拷貝到使用者空間

int file_read(struct m_inode * inode, struct file * flip, char * buf, int count) { 
    …… 
  while(left) {
    ……
    if (bh) {
      char *p =nr + bh->b_data;
      while(chars-->0)
        put_fs_byte(*(p++), buf++);
        brelse(bh);
    }
    ……
} …… }

int file_read(struct m_inode * inode, struct file * flip, char * buf, int count) { 
    …… 
  while(left) {
    ……
    filp->f_pos += chars;
left -= chars;
    ……
} …… }

通過file_read函式中的while(left){……}迴圈,完成hello.txt檔案從硬碟到使用者執行空間的讀取。

課程總結:

在選這門課之前,我對Linux的認知僅限於一些諸如cd、ls等簡單的指令,對作業系統的認知也僅限於作業系統相關教材中抽象的文字描述,其他的東西一竅不通。通過這個學期的學習,通過老師們對實際的程式碼的講解,加深了我對作業系統的理解,大致知曉Linux是如何工作的,並且經過幾次實際的實驗操作,稍微有了跟蹤、除錯Linux系統的執行機制。

Linux作為一個廣受歡迎並普遍應用於各行各業的作業系統,無疑是非常成功的。其核心模組也是相當複雜,不甚晦澀。雖有老師們的悉心講解,但我感覺自己僅僅是摸到其新手門檻,要學習的知識浩如煙海,我瞭解到的僅是皮毛而已。

不過收穫還有非常之多的,特別是通過幾次實驗的實際操作,我學會了如何除錯核心,如何去逐步分析系統呼叫、如何去理解核心中的彙編程式碼等等。

感謝這門課程的學習,為我展示了計算機新世界的冰山一角!