天天看點

linux0.11字元裝置的讀寫過程分析

首先要知道linux系統/dev目錄下的各種裝置檔案(檔案屬性c打頭)并不占用空間,你可以發現他們的大小為0位元組,他們的差別在于檔案的i節點的成員i_zone[0]的值不同,該值辨別不同的裝置号。比如tty0檔案的裝置号為0x0400,tty1裝置号為0x0401,hd0裝置号為0x0300,hd1裝置号為0x0301等。而這個裝置号裡面又包含兩部分内容:高位元組辨別不同類裝置,比如tty0和hd0分别為0x04,0x03,低位元組辨別同一類裝置不同序号。

接下來對linux0.11打開的第一個檔案tty0的過程進行分析:

1. main.c檔案:執行open("/dev/tty0",O_RDWR,0),調用該函數将觸發系統調用sys_open()。

2. open.c檔案:進入該系統調用函數sys_open,首先配置設定一個檔案句柄fd(第一個檔案為0,其實是檔案表到索引),然後為這個打開的檔案在檔案表(file_table.c定義的一個數組)中尋找一個有效的空閑項,将這個空閑項的檔案指針添加到目前程序結構的flip成員中(flip成員為一個指針數組),并将檔案引用次數+1。接着調用open_namei函數擷取tty0裝置檔案的i_node指針。最後将該指針賦給檔案表的f_inode成員。至此,tty0檔案打開完畢,并将其inode資訊儲存于current程序的flips數組指針的fd索引項中。接下來開始對該tty進行寫操作。

3. main.c檔案:調用printf函數執行列印輸出,在該函數中将調用write函數,又将觸發sys_write系統調用。

4. read_write.c檔案:進入sys_write系統調用函數,首先根據傳遞進來的檔案句柄fd擷取目前程序的檔案結構指針(file=current->filp[fd])),然後根據檔案結構指針的f_inode成員的i_mode成員判斷檔案的類型(根據前面open所擷取到類型,這裡應為i_mode=0x0400),判斷為字元裝置,是以調用字元裝置讀寫函數rw_char。(可以發現如果是塊裝置則調用block_write函數,如果是普通則調用file_write函數,當然讀其他裝置是同樣道理。這也印證了linux平台下一切皆檔案的思想)

5. char_dev.c檔案:進入rw_char函數,根據傳遞進來的裝置号(0x0400)擷取對應讀寫函數指針(裝置号高位元組0x04對應函數指針數組crw_table[]的rw_ttyx成員項),然後将執行rw_ttyx函數,該函數又調用tty_write底層函數。

6. tty_io.c檔案:進入tty_write函數,根據傳遞進來的裝置号低位元組(裝置序号,這裡為0x00)擷取tty_struct指針,根據該檔案開頭處定義的已初始化的tty結構數組tty_table,該指針将指向tty_table數組第一項(tty控制台),tty_write函數最後執行tty->write語句将調用con_write函數對顯示器進行寫操作。

7. console.c檔案:con_write函數。

繼續閱讀