華為的鴻蒙系統(tǒng)開源之后第一個想看的模塊就是 FS 模塊,想了解一下它的 IO 路徑與 linux 的區(qū)別。現(xiàn)在鴻蒙開源的倉庫中有兩個內核系統(tǒng),一個是 liteos_a 系統(tǒng),一個是 liteos_m 系統(tǒng)。兩者的區(qū)別主要是適應的場景不一樣,liteos_a 系統(tǒng)適用于硬件資源更加豐富的場景,比如 CPU 更強,內存更大;而 liteos_m 系統(tǒng)則適用于 IoT 設備,相對來說硬件資源比較弱一些。所以我們就拿 liteos_a 系統(tǒng)來分析一下它的 IO 棧吧,畢竟它應對的場景更加復雜一些。
鴻蒙系統(tǒng) liteos_a Kernel 的下載地址在這:https://gitee.com/openharmony/kernel_liteos_a。
1.FS 源碼結構
下載內核源碼后發(fā)現(xiàn) fs 目錄下似乎缺少很多東西。
當時覺得好奇怪,啥都沒有,那它的 shell 相關命令是怎么使用 fs 模塊進行讀寫的呢?于是發(fā)現(xiàn)鴻蒙的 FS 模塊主要是從 Nuttx (注:Nuttx 是 Apache 正在孵化的實時操作系統(tǒng)內核)那里借用了 FS 的相關實現(xiàn)。這是從內核的 fs.h 引用的路徑發(fā)現(xiàn)的,它引用的路徑內容如下:
../../../../../third_party/NuttX/include/nuttx/fs/fs.h
所以我們需要找到這個模塊,在 gitee 的倉庫中搜索 Nuttx 發(fā)現(xiàn)的確有這個倉庫,所以我們需要聯(lián)合兩個倉庫的代碼一起解讀 IO 棧的源碼。Nuttx 的倉庫地址為:https://gitee.com/openharmony/third_party_NuttX。
我們來看一下 Nuttx 的目錄結構:
可以發(fā)現(xiàn) FS 的具體實現(xiàn)都在這個 Nuttx 倉庫內。接下來我們來看看鴻蒙系統(tǒng)的 IO 棧吧,因為 IO 棧的路徑比較多,所以我們選取塊設備(block device)的路徑來分析。
2. IO 整體架構
鴻蒙系統(tǒng)關于塊設備的 IO 棧路徑整體架構如下圖所示:
整體 IO 流程如下:
上層應用會在用戶態(tài)下調用 read / write 接口,這會觸發(fā)系統(tǒng)調用(syscall)進入內核態(tài);
系統(tǒng)調用往下調用 VFS 的接口,如 read 則對應 read,write 對應 write;
VFS 這層會根據 fd 對應的 file 結構拿出超級塊的 inode,利用這個 inode 繼續(xù)往下調用具體 driver 的 read / write 接口;
在塊設備的場景下,它是利用字符設備的驅動作為它的代理,也就是 driver 下面的 bch。鴻蒙系統(tǒng)的設備驅動中并沒有塊設備的驅動,所以它做了一層 block_proxy,無論是字符設備還是塊設備的 IO 都會經過 bch 驅動。數據所位于的扇區(qū)以及偏移量(offset)計算位于這層;
IO 往下走會有一層緩存,叫 bcache。bcache 采用紅黑樹管理這些緩存的數據;
IO 再往下走就是塊設備的驅動,內核沒有通用的塊設備驅動實現(xiàn),它應該是由不同的廠商來實現(xiàn)的。
3.鴻蒙 IO 流程源碼解讀
讀寫流程大致一樣,我們就看一下鴻蒙的讀數據流程吧。由于函數的源碼比較長,全貼出來也不太好,所以太長的源碼我只將關鍵的部分截出。
3.1 上層應用讀取數據
上層應用調用 read 接口,這個是系統(tǒng)的 POSIX 接口,read 接口原型如下:
#includessize_t read(int fd, void *buf, size_t count);
3.2 VFS
上層應用在用戶態(tài)調用 read 接口后會觸發(fā)系統(tǒng)調用,這個系統(tǒng)調用在 Kernel 的如下文件中進行注冊:
syscall/fs_syscall.c
對應的系統(tǒng)調用函數為
237 行的 read 調用的是 VFS 這層的 read,VFS 這層的 read 函數實現(xiàn)位于 Nuttx 項目的如下路徑:
fs/vfs/fs_read.c
read函數從 fd (文件描述符)中獲取對應的 file 對象指針,然后在調用 file_read 接口。file_read 也和 read 函數位于同一個文件下。它從 file 對象中獲取了超級塊的 inode 對象,然后使用這個 inode 調用 bch 驅動的 read 函數。
3.3 bch 驅動
bch 驅動是一個字符設備驅動,它被用來當做上層與塊設備驅動的中間層。注冊塊設備驅動時會調用 block_proxy 來做代理轉換,它的實現(xiàn)位于:
fs/driver/fs_blockproxy.c
當打開(open)一個塊設備時,內核會判斷 inode 是否是塊設備類型,如果是則調用 block_proxy 來做轉換處理。 當上層調用 u.i_ops->read 時,它對應的是 bch_read,它的實現(xiàn)位于:
drivers/bch/bchdev_driver.c
bch_read 會接著調用 bchlib_read,這個函數的實現(xiàn)位于:
drivers/bch/bchlib_read.c
它會根據偏移(offset)計算出在哪個扇區(qū)進行讀數據,如果要讀取的數據只是某個扇區(qū)的一部分,則它會先利用 bchlib_readsector 將這個扇區(qū)全部讀出來,然后再把對應的那部分數據拷貝到內存并返回。 bchlib_readsector 的實現(xiàn)位于如下位置:
drivers/bch/bchlib_cache.c
它會先將位于內存的臟數據下刷,等臟數據都下刷完成后才會利用 los_disk_read 把數據從磁盤上讀上來。 los_disk_read 的實現(xiàn)位于 kernel 的如下位置:
fs/vfs/disk/disk.c
這 los_disk_read 這層會有一層緩存,叫 bcache。它會把每次 IO 的扇區(qū)緩存到內存中,緩存的組織方式為紅黑樹。它是有大小限制的,不是無限增長,具體大小與內存大小有關。 los_disk_read 在讀數據之前會先從 bcache 緩存中查找有沒有對應的緩存扇區(qū),如果有則直接將這個扇區(qū)返回,如果沒有則調用真正塊設備的 read 函數。這個 read 函數在內核中沒有對應的實現(xiàn),所以它是跟隨每個塊設備的驅動的不同而不同。
整個讀數據流程源碼分析就到這里。
鴻蒙系統(tǒng)的 IO 棧分支比較多,這次的源碼解讀選用了塊設備的分支進行分析,希望可以幫助大家更好的理解鴻蒙系統(tǒng)。最后我還想做一下鴻蒙系統(tǒng)與 Linux 關于 IO 棧的對比。
4.鴻蒙 IO 棧與 Linux IO 棧的對比
如果有研究過 linux IO 棧的同學應該能體會到鴻蒙的 IO 棧是比較簡單。先來看一下 Linux 的 IO 棧整體架構圖:
所以,我們對比一下鴻蒙系統(tǒng)和 Linux IO 棧的主要區(qū)別吧:
鴻蒙沒有 pagecache。所以鴻蒙的系統(tǒng)調用加不加 O_SYNC 應該是一樣的,都是直接下到磁盤。
鴻蒙沒有通用塊層和 IO 調度層。在 Linux 中通用塊層是用來將連續(xù)的塊請求組成一個 bio 結構體,便于對接下層的調度管理。調度層的目的則是用來減少 IO 尋址時間,在這層也有多種調度算法可以選擇,如 cfq/deadline/noop 等。我覺得鴻蒙不是沒有這兩層,而是還沒有做,目前只是 IoT 的適用場景。等明年適用于手機的時候再看看,我覺得應該也會做相關的處理,只不過不一定與 Linux 的處理一樣。
鴻蒙的驅動層次不夠完整,需要用字符設備的驅動來代理塊設備的驅動,不知道這是基于什么考慮。
鴻蒙 bcache 的作用與 linux 的 pagecache 作用基本一致,只不過它們在 IO 棧上所在的位置不一樣。
編輯:hfy
-
Linux
+關注
關注
87文章
11352瀏覽量
210543 -
鴻蒙系統(tǒng)
+關注
關注
183文章
2638瀏覽量
66776 -
IO棧
+關注
關注
0文章
2瀏覽量
559
發(fā)布評論請先 登錄
相關推薦
意法半導體展示IO-Link收發(fā)器和低邊功率開關的組合應用
電流倒灌揭秘:IO口損壞與系統(tǒng)故障的真相
![電流倒灌揭秘:<b class='flag-5'>IO</b>口損壞與<b class='flag-5'>系統(tǒng)</b>故障的真相](https://file.elecfans.com/web2/M00/50/DA/pYYBAGLH6TyAB71EAAAPQ7KgtYA038.png)
λ-IO:存儲計算下的IO棧設計
![λ-<b class='flag-5'>IO</b>:存儲計算下的<b class='flag-5'>IO</b><b class='flag-5'>棧</b>設計](https://file1.elecfans.com/web3/M00/00/AF/wKgZO2dNHbaAIkp-AAAM3550zYU863.png)
RoCE與IB對比分析(二):功能應用篇
![RoCE與IB<b class='flag-5'>對比分析</b>(二):功能應用篇](https://file1.elecfans.com/web2/M00/0B/B4/wKgZomc249eAbmf1AAA9YnA6DaM760.png)
華納云監(jiān)視Linux磁盤IO性能命令:iotop,iostat,vmstat,atop,dstat,ioping
亞信電子于IAS 2024展出最新IO-Link主站&設備軟件協(xié)議棧解決方案
![亞信電子于IAS 2024展出最新<b class='flag-5'>IO</b>-Link主站&設備軟件協(xié)議<b class='flag-5'>棧</b>解決方案](https://file1.elecfans.com/web2/M00/06/C0/wKgZombqf5uATC9PAAH9TLys4gM271.png)
Linux網絡協(xié)議棧的實現(xiàn)
![<b class='flag-5'>Linux</b>網絡協(xié)議<b class='flag-5'>棧</b>的實現(xiàn)](https://file1.elecfans.com/web2/M00/06/C6/wKgaombfpT-AeVQcAACjr17dpiQ190.png)
網關和路由器的對比分析
一體式IO與分布式IO:工業(yè)控制系統(tǒng)的兩種架構
![一體式<b class='flag-5'>IO</b>與分布式<b class='flag-5'>IO</b>:工業(yè)控制<b class='flag-5'>系統(tǒng)</b>的兩種架構](https://file1.elecfans.com/web2/M00/FD/ED/wKgaomaXfAKAQqW9AAz1XZeTcnQ637.png)
初識IO-Link及IO-Link設備軟件協(xié)議棧
![初識<b class='flag-5'>IO</b>-Link及<b class='flag-5'>IO</b>-Link設備軟件協(xié)議<b class='flag-5'>棧</b>](https://file1.elecfans.com/web2/M00/FA/AE/wKgaomaLpjKAfsHsAABZHFeDt4Q438.png)
初識IO-Link及IO-Link設備軟件協(xié)議棧
![初識<b class='flag-5'>IO</b>-Link及<b class='flag-5'>IO</b>-Link設備軟件協(xié)議<b class='flag-5'>棧</b>](https://file1.elecfans.com/web2/M00/F9/9D/wKgZomaLUNqAUDQ6AATSbLoa6xU520.png)
評論