我們知道Linux是分為兩種狀態 用戶態和內核態,Linux內核需要跑在硬件平臺上,硬件平臺也有自己的狀態。這里還是ARM,ARM有其中處理器的模式。
用戶模式(user):用戶程序運行的模式。系統模式(system):特權模式。一般中斷模式(IRQ):普通中斷模式。快速中斷模式(FIQ):快速中斷模式。管理模式(supervisor):操作系統的內核通常運行在該模式下。數據訪問終止模式(abort):當數據或者指令預取終止時進入該模式,用于虛擬存儲及存儲保護。未定義指令模式(undefined):當未定義的指令執行時進入該模式,可用于支持硬件協處理器的軟件仿真。
Linux內核的用戶態和內核態兩種模式分別對應的用戶模式和管理模式。
這里還是以32位,對應4GB,內核一般內核:用戶按照1:3的比例分配。這也是可以修改的。
我們知道分頁機制,賦予了每個進程都有尋址4GB的空間,因為每個進程都有自己的進程表。
內核空間是從3GB開始,lowmem這段空間其實就是我們常說的線性映射區。(為啥虛擬地址明明在高位卻是low,繼續看)所謂的線性映射區,就是物理內存線性地映射到這段內核空間的區域中。在 ARM32 平臺上,物理地址[0:760MB]的這一部分內存被線性映射到[3GB :3GB+760MB]的虛擬地址上(因為其物理地址在低位)。
線性映射區的虛擬地址和物理地址相差PAGE_OFFSET,即3GB。內核中有相關的宏來實現線性映射區的虛擬地址到物理地址的查找,例如pa(x)和va(x)。
其中,__pa()把線性映射區的虛擬地址轉換為物理地址,轉換公式很簡單,即用虛擬地址減去PAGE_OFFSET(3GB),然后加上PHYS_OFFSET(這個值在有的ARM平臺上為0,在ARM Vexpress平臺上為0x6000_0000)。
物理內存被分成了兩部分,低端的部分用在線性映射區,線性映射區就是這里的“lowmem”區域。剩下的高端部分的物理內存被稱為高端內存(High Memory),內核要使用它,必須通過高端映射的方式來訪問。
內核通常把低于760MB的物理內存稱為線性映射內存(Normal Memory),而高于760MB以上的稱為高端內存。 (這個高端是針對內核內存來說,780到1G)
這個分給內核的1G分成了高端和線性。
高端780到1G是干啥呢?剩下的264MB虛擬地址空間是保留給vmalloc機制、fixmap和高端異常向量表等使用的。內核很多驅動使用vmalloc機制來分配連續虛擬地址的內存,因為有的驅動不需要連續物理地址的內存;除此以外,vmalloc機制還可以用于高端內存的臨時映射。一個32位的系統中,實際支持的內存數量會超過內核線性映射的長度,但是內核要具有對所有內存的尋找能力。
(這里我想的是雖然在內核,但是我內核還是要對整個內存有個控制能力,這里就是體現,在vmalloc機制就可以干這個:個人看法,有糾正的大佬在評論區告訴小的一下)
編譯器在編譯目標文件并且鏈接完成之后,就可以知道內核映像文件最終的大小,接下來將其打包成二進制文件,該操作由arch/arm/kernel/vmlinux.ld.S 控制,其中也劃定了內核的內存布局。
內核image本身占據的內存空間從_text段到_end段,并分為如下幾個段。text段:_text和_etext為代碼段的起始和結束地址,包含了編譯后的內核代碼。init段:init_begin和init_end為init段的起始和結束地址,包含了大部分內核模塊初始化的數據。data段:_sdata和_edata為數據段的起始和結束地址,保存大部分內核的已初始化的變量。BSS段:bss_start和bss_stop為BSS段的開始和結束地址,包含初始化為0的所有靜態全局變量。
上述幾個段的大小在編譯鏈接時根據內核配置來確定,因為每種配置的代碼段和數據段長度都不相同,這取決于要編譯哪些內核模塊,但是起始地址_text 總是相同的。內核編譯完成之后,會生成一個System.map文件,查詢這個文件可以找到這些符號的具體數值。
-
處理器
+關注
關注
68文章
19340瀏覽量
230202 -
Linux
+關注
關注
87文章
11316瀏覽量
209815 -
內存
+關注
關注
8文章
3034瀏覽量
74132 -
進程
+關注
關注
0文章
203瀏覽量
13965
發布評論請先 登錄
相關推薦
評論