SylixOS 下的IO系統調用
SylixOS標準I/O基本介紹
1.1 簡介
I/O 系統又稱作輸入輸出系統,SylixOS 兼容POSIX標準輸入輸出系統,SylixOS的I/O概念繼承了UNIX操作系統的I/O概念,認為一切皆為文件。與UNIX操作系統相同, SylixOS中的文件也分為不同的類型。
1.2 兩種I/O類型
I/O系統分為 ORIG 型驅動結構和 NEW_1 型驅動結構,如圖 1.1和圖 1.2。
圖 1.1 ORIG 型驅動結構
圖 1.2 NEW 型驅動結構
文件描述符表:
typedef struct {
PLW_FD_ENTRY FDDESC_pfdentry; / 文件結構
BOOL FDDESC_bCloExec; / FD_CLOEXEC /
ULONG FDDESC_ulRef; / 對應文件描述符的引用計數/
} LW_FD_DESC;
文件結構結構體:
typedef struct {
PLW_DEV_HDR FDENTRY_pdevhdrHdr; / 設備頭 /
PCHAR FDENTRY_pcName; / 文件名
PCHAR FDENTRY_pcRealName; / 去除符號鏈接的真實文件名 /
LW_LIST_LINE FDENTRY_lineManage; / 文件控制信息遍歷表 /
#define FDENTRY_pfdnode FDENTRY_lValue
LONG FDENTRY_lValue; / 驅動程序內部數據 /
/ 如果為 NEW_1 驅動fd_node/
INT FDENTRY_iType; / 文件類型 (根據驅動判斷)
INT FDENTRY_iFlag; / 文件屬性 /
INT FDENTRY_iAbnormity; / 文件異常 /
ULONG FDENTRY_ulCounter; / 總引用計數器 /
off_t FDENTRY_oftPtr; / 文件當前指針 /
/ 只有 NEW_1 或更高級驅動使用 /
BOOL FDENTRY_bRemoveReq; / 刪除請求 /
} LW_FD_ENTRY;
文件節點:
typedef struct {
LW_LIST_LINE FDNODE_lineManage; / 同一設備 fd_node 鏈表/
LW_OBJECT_HANDLE FDNODE_ulSem; / 內部操作鎖 /
dev_t FDNODE_dev; / 設備 /
ino64_t FDNODE_inode64; / inode (64bit 為了兼容性) /
mode_t FDNODE_mode; / 文件 mode /
uid_t FDNODE_uid; / 文件所屬用戶信息 /
gid_t FDNODE_gid;
off_t FDNODE_oftSize; / 當前文件大小 /
struct __fd_lockf FDNODE_pfdlockHead; / 第一個鎖 /
LW_LIST_LINE_HEADER FDNODE_plineBlockQ;
/ 當前有阻塞的記錄鎖隊列 /
BOOL FDNODE_bRemove; /是否在文件未關閉時有 unlink */
ULONG FDNODE_ulLock; /*鎖定, 不允許寫, 不允許刪除 */
ULONG FDNODE_ulRef; /* fd_entry 引用此 fd_node 數量*/
PVOID FDNODE_pvFile; / 驅動使用此變量標示文件 /
PVOID FDNODE_pvFsExtern; / 文件系統擴展使用 /
} LW_FD_NODE;
rootfs 節點:
typedef struct lw_rootfs_node {
LW_LIST_LINE RFSN_lineBrother; / 兄弟節點 /
struct lw_rootfs_node RFSN_prfsnFather; / 父系節點 /
PLW_LIST_LINE RFSN_plineSon; / 兒子節點 /
INT RFSN_iOpenNum; / 打開次數 /
size_t RFSN_stAllocSize; / 此節點占用內存大小 /
mode_t RFSN_mode; / 模式 /
time_t RFSN_time; / 創建時間 /
INT RFSN_iNodeType; / 節點類型 /
uid_t RFSN_uid;
gid_t RFSN_gid;
LW_ROOTFS_NODE_VALUE RFSN_rfsnv; / 節點的內容 /
PCHAR RFSN_pcLink; / 鏈接目標 (不是鏈接文件為 0) */
} LW_ROOTFS_NODE;
設備頭:
typedef struct {
LW_LIST_LINE DEVHDR_lineManage; / 設備頭管理鏈表 /
UIN×××6 DEVHDR_usDrvNum; / 設備驅動程序索引號 /
PCHAR DEVHDR_pcName; / 設備名稱 /
UCHAR DEVHDR_ucType; / 設備 dirent d_type /
atomic_t DEVHDR_atomicOpenNum; / 打開的次數 /
PVOID DEVHDR_pvReserve; / 保留 /
} LW_DEV_HDR;
- 基本流程
系統設備註冊流程如圖 3.1:
(1) struct file_operations fileop,設備文件操作控制塊,先對 fileop成員函數賦值,調用iosDrvInstallEx2(&fileop,設備類型),將返回“驅動程序索引號”。
(2) API_IosDrvInstallEx2(struct file_operations *pfileop, INT iType),搜索全局 _S_deventryTbl(默認64)表,查找未使用的驅動程序控制塊,返回該數組下標,關聯設備文件操作控制塊函數。
(3) 設備創建,API_IosDevAddEx(PLW_DEV_HDR pdevhdrHdr, CPCHAR pcDevName, INT iDrvNum, UCHAR ucType),將API_IosDrvInstallEx2所產生的驅動索引號與具體的設備頭關聯,創建新的文件系統節點rootFsMakeDev,最後將該設備添加進設備管理鏈表_S_plineDevHdrHeader進行管理;
圖 3.1 系統設備創建過程
文件I/O系統 open函數流程如圖 3.2:
(1) Open函數實際上調用_IoOpen,_IoOpen 先檢查文件名的合法性;
(2) 調用ioFullFileNameGet()函數,通過 cpcName 查找到設備註冊到文件系統中的節點,返回該節點對應的驅動設備頭;
(3) 然後通過獲取的設備頭和設備名調用iosFdNew()創建新的文件結構並鏈入到全局文件結構頭表中_S_plineFileEntryHeader;
(4) 從全局文件描述符表數組中_G_fddescTbl查找到未使用的最小文件描述符表,返回該數組下表作為文件描述符,將該文件描述表關聯上新創建的文件結構,將新創建的文件結構關聯上設備頭;
(5) 調用iosOpen(),從獲取到的設備頭中獲取對應設備的設備驅動程序索引號,並通過該索引號從全局驅動表中查找到對應的設備open函數,使用該函數,如果是NEW_1型驅動將返回對應的文件節點;
(6) 將調用驅動open函數返回的驅動內部數據關聯上文件結構,使用函數iosFdSet();
圖 3.2 標準open調用過程
SylixOS 下的IO系統調用