Linux驅動中的ioremap
時間:2024-01-19 來源:華清遠見
要回答“Linux驅動開發過程中操作外設寄存器前為什么需要對外設寄存器地址調用ioremap函數?”這個問題,需要從操作系統內核怎樣對內存進行管理說起。
# 一、操作系統為什么需要對內存進行管理?
操作系統的核心工作就是支持多任務并發或并行執行,不管是并發還是并行宏觀上均認為多任務同時執行,而操作系統運用進程形式組織任務,也就形成了多進程同時運行的情形,任何進程和操作系統內核的運行都需要依賴于一定量的內存,也就意味著多進程和操作系統內核需要同時占用內存的不同部分,這樣才能相互不干擾,包括進程間不相互干擾、進程與內核不相互干擾,為了確保互不干擾也為了內存這種稀缺資源的高效利用,整個計算機系統必須對內存進行合理規劃使用(業內稱為內存管理),這一重要工作自然由操作系統內核這個關鍵角色去完成,因此內存管理成為操作系統內核這個特殊程序的核心工作之一!!!
# 二、操作系統怎樣進行內存管理?
現代操作系統借助于一種特殊的硬件裝置來進行內存管理,這種硬件裝置稱為MMU(內存管理單元)。管理思路類似于某些一線城市上車牌號,需要車牌號的人首先參與搖號獲得購買車牌號的資格號(虛擬號),然后再購買實際的車牌號(實際號或物理號)。為了公平起見,這個城市給每個行政區固定數目的虛擬號(假設均為從0開始的連續1200個虛擬號),作為城市的管理方,同時也為了與普通民眾進行區分,為政府公務人員也準備固定數目的虛擬號(假設均為從1200開始的連續400個虛擬號),假設每次這個城市售賣5000個車牌,任何想要購買車牌的人,必須先按角色(普通民眾還是公務人員)和行政區(普通民眾所在住地)在指定地點參與搖號,首先獲得虛擬號,然后車管所會為這些虛擬號與未售完的實際車牌號建立關聯,這樣每個行政區和政府部門各獲得一張虛擬號與實際車牌號的對應表格,位于此表格中虛擬號對應人員獲得最終的購買實際車牌的權利,搖到虛擬號的人可以在指定地點的某臺機器上輸入自己虛擬號查閱自己是否擁有最終車牌的購買權,這臺機器就類似于MMU這個硬件裝置,可以幫助人們查閱各自虛擬號和實際車牌號的關聯表,以便獲知得到購買權以及可以購買的實際車牌號。以上過程中各行政區與政府部分各用各的虛擬號,互不干擾!!!
操作系統采用類似思路,首先為每個進程和操作系統內核安排一塊虛擬空間(假想的、無法實際存儲二進制位的、每個字節編號類似于購買車牌過程中的虛擬號),借助于各自虛擬空間每個字節的地址值(虛擬地址),來爭取最終實際內存(物理內存,其每個字節的地址值被稱為物理地址)的使用權。由于各個進程執行過程中代碼中全部使用各自虛擬空間的虛擬地址,這樣萬一地址值計算、使用錯誤只涉及自身虛擬空間,100%避免了干擾其它進程和內核,而每次使用內存前將代碼中的虛擬地址傳給CPU,CPU將之傳給MMU這個特殊硬件裝置,MMU則完成查閱操作系統內核為這個進程創建的頁表(虛擬地址與物理地址關聯表)將獲得的虛擬地址轉換為物理地址,最后使用實際內存。而內核比較特殊,在計算機運行內核的初期,由于MMU還未能正常工作,所以代碼中均使用物理地址,一旦MMU開始正常工作的后期(設備驅動代碼和所有進程的運行)代碼中均使用虛擬地址,因此內核后期使用內存與各個進程類似,只是使用其自身的頁表。

為了區分內核和進程使用的虛擬地址范圍,32位計算機平臺,操作系統:

1. 為各個進程準備的虛擬空間的地址值范圍是0x00000000 ~ 0xBFFFFFFF(大小3G Bytes)
2. 為內核自身準備的虛擬空間的地址值范圍是0xC0000000 ~ 0xFFFFFFFF(大小1G Bytes)
# 三、ioremap
ARM系列處理器芯片內所有外設寄存器都是作為物理內存的一部分,只是這些物理內存的作用已經固定,不能作為其它程序執行過程中可重復使用的運行內存用,各款芯片的使用手冊中注有所有這些外設寄存器的物理地址,在無操作系統的裸機開發過程中可以直接在外設驅動程序使用這些物理地址值訪問這些外設寄存器以達到操控外設的目的。但在有操作系統的驅動開發過程中,外設驅動程序的運行位于操作系統內核后期,代碼中只能使用虛擬地址,操作系統內核提供一個函數ioremap為這些外設寄存器的物理地址在內核的虛擬地址空間中安排容量相同的虛擬地址空間相關聯,從而得到對應的虛擬地址,并在內核頁表中添加一條關聯記錄,方便在驅動程序運行過程中方便MMU通過查詢內核頁表將外設虛擬地址轉換為芯片手冊中查到的物理地址以便達到訪問外設寄存器的目的,而在驅動開發的過程中則使用這些虛擬地址訪問外設寄存器以達到操控外設的目的!!!

