Linux內(nèi)核和驅(qū)動(dòng)的區(qū)別是什么?
Linux設(shè)備驅(qū)動(dòng)屬于內(nèi)核的一部分,Linux內(nèi)核的一個(gè)模塊可以以兩種方式被編譯和加載:
(1)直接編譯進(jìn)Linux內(nèi)核,隨同Linux啟動(dòng)時(shí)加載。
(2)編譯成一個(gè)可加載和刪除的模塊。
驅(qū)動(dòng)程序向內(nèi)核添加了一些函數(shù),是內(nèi)核的一部分。例如Open(), Release(), Read(), Write()。這些函數(shù)由內(nèi)核在適當(dāng)?shù)臅r(shí)候來(lái)調(diào)用,可以用來(lái)完成硬件訪問(wèn)等操作。驅(qū)動(dòng)程序占kernel源代碼超過(guò)50%。
內(nèi)核中printk()函數(shù)的設(shè)計(jì)目的并不是為了和用戶交流,它實(shí)際上是內(nèi)核的一種日志機(jī)制,用來(lái)記錄下日志信息或者給出警告提示。如果syslogd 和klogd 守護(hù)進(jìn)程在運(yùn)行的話,則不管是否向控制臺(tái)輸出,消息都會(huì)被追加進(jìn)/var/log/messages 文件。klogd只處理內(nèi)核消息,syslogd 處理其他系統(tǒng)消息,比如應(yīng)用程序。
設(shè)備驅(qū)動(dòng)的并發(fā)控制
自旋鎖不會(huì)引起調(diào)用者睡眠,如果自旋鎖已經(jīng)被別的執(zhí)行單元保持,調(diào)用者就一直循環(huán)查看是否該自旋鎖的保持者已經(jīng)釋放了鎖,“自旋”就是“在原地打轉(zhuǎn)”。自旋鎖適合于保持時(shí)間非常短的情況,它可以在任何上下文使用。
信號(hào)量則引起調(diào)用者睡眠,它把進(jìn)程從運(yùn)行隊(duì)列上拖出去,除非獲得鎖。信號(hào)量適合于保持時(shí)間較長(zhǎng)的情況,會(huì)只能在進(jìn)程上下文使用。
如果被保護(hù)的共享資源需要在中斷上下文訪問(wèn)(包括底半部即中斷處理句柄和頂半部即軟中斷),就必須使用自旋鎖。
設(shè)備驅(qū)動(dòng)的內(nèi)存與IO訪問(wèn)
內(nèi)核虛擬內(nèi)存映射到連續(xù)的物理內(nèi)存。
CPU 通常并沒(méi)有為這些已知的外設(shè)I/O內(nèi)存資源的物理地址預(yù)定義虛擬地址范圍,驅(qū)動(dòng)程序并不能直接通過(guò)物理地址訪問(wèn)I/O 內(nèi)存資源,而必須將它們映射到核心虛地址空間內(nèi)(通過(guò)頁(yè)表),然后才能根據(jù)映射所得到的核心虛地址范圍,通過(guò)訪內(nèi)指令訪問(wèn)這些I/O內(nèi)存資源。Linux 在io.h 頭文件中聲明了函數(shù)ioremap(),用來(lái)將I/O 內(nèi)存資源的物理地址映射到核心虛地址空間(3GB-4GB)。
驅(qū)動(dòng)中使用的地址是虛擬地址。外設(shè)的IO地址需要映射到虛擬地址。