成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux ARM的存儲(chǔ)分布那些事

存儲(chǔ) 存儲(chǔ)軟件
對(duì)于那些支持中斷向量重映射的cpu,該區(qū)域用來撲獲0地址的非法訪問,即null指針。針對(duì)arm體系,他是支持中斷向量重映射,該區(qū)域一般保留不用,用來撲獲null指針。

linux arm 內(nèi)存分布總覽

地址范圍大小,虛擬轉(zhuǎn)物理的接口函數(shù),各個(gè)區(qū)域?qū)?yīng)的分配函數(shù),該區(qū)域有什么作用,使用場(chǎng)合等等。

首先開始第一個(gè)區(qū)域:CPUvector page null pointer trap

該區(qū)域的大小是一個(gè)page頁的大小,對(duì)于那些不支持中斷向量重映射的cpu,該區(qū)域用來存儲(chǔ)對(duì)應(yīng)的中斷向量表;

對(duì)于那些支持中斷向量重映射的cpu,該區(qū)域用來撲獲0地址的非法訪問,即null指針。針對(duì)arm體系,他是支持中斷向量重映射,該區(qū)域一般保留不用,用來撲獲null指針。

上圖是linux的arm的虛擬地址分布總覽,我們按從低地址到高地址的順序逐個(gè)描述,每項(xiàng)的描述包括如下的內(nèi)容的組和:

第二個(gè)區(qū)域:應(yīng)用程序地址空間

地址大小范圍屬于[0x1000, 0xbf000000],我知道每個(gè)應(yīng)用進(jìn)程都有如下幾個(gè)段:text段即存儲(chǔ)代碼段,data段即存儲(chǔ)初始化的數(shù)據(jù)段,bss段即存儲(chǔ)未初始化的數(shù)據(jù)段,堆(malloc,free),棧(往下生長(zhǎng))。他們的地址分布如下:

圖1

在應(yīng)用程序加載到內(nèi)存后,會(huì)為每個(gè)段,分一個(gè)vma的內(nèi)核結(jié)構(gòu)體,并且為每個(gè)段都分配了虛擬地址(虛擬地址和大小都存儲(chǔ)在vma結(jié)構(gòu)體中),當(dāng)可執(zhí)行程序的各個(gè)段在加載的時(shí)候,就會(huì)給其分配虛擬地址,每個(gè)段對(duì)應(yīng)內(nèi)核的一個(gè)vma結(jié)構(gòu),程序所有段對(duì)應(yīng)的vma,都掛在程序?qū)?yīng)的進(jìn)程的struct mm結(jié)構(gòu)中,但并未給他分配實(shí)際的物理地址,待cpu實(shí)際去訪問它時(shí),才會(huì)去實(shí)際建立物理到vma指定的虛擬地址映射,并且將對(duì)應(yīng)的段內(nèi)容從elf文件中拷貝到相應(yīng)的物理內(nèi)存中。

譬如當(dāng)cpu要訪問text段時(shí),這個(gè)時(shí)候并未建立相應(yīng)的映射表,所以會(huì)產(chǎn)生page fault異常,從而在異常處理中,linux的內(nèi)存管理系統(tǒng)會(huì)為其分配物理內(nèi)存, 并從二進(jìn)制可執(zhí)行程序的elf文件讀取text段到物理內(nèi)存,并且為該進(jìn)程對(duì)應(yīng)的頁表建立該物理頁到虛擬地址的映射,這樣cpu就可以訪問該進(jìn)程的text段,并且執(zhí)行對(duì)應(yīng)的指令了。

stack跟heap都一樣,在cpu有實(shí)際的訪問時(shí),才會(huì)分配物理內(nèi)存,并建立物理到對(duì)應(yīng)的虛擬地址(在程序加載時(shí),vma中就已經(jīng)分配了虛擬地址)映射。這樣做,就可以節(jié)省程序運(yùn)行時(shí)實(shí)際物理內(nèi)存的使用。而不是程序一開始就建立了所有物理到虛擬的映射,從而導(dǎo)致物理內(nèi)存被大量不必要的消耗。

第三個(gè)區(qū)域:模塊地址

該區(qū)域用來為內(nèi)核模塊分配地址,譬如在insmod一個(gè)驅(qū)動(dòng)模塊時(shí),會(huì)通過如下的流程:sysinit_module-->load_module-->layout_and_allocate-->move_module-->module_alloc_update_bounds-->module_alloc來為模塊的各個(gè)段分配虛擬地址

圖2

line42可見:就指定了模塊的虛擬地址范圍為:[MODULES_VADDR,MODULES_END] = [0xbf000000,0xbfe00000],總計(jì)14MB。注意此時(shí)__vmalloc_node_range進(jìn)行了實(shí)際的物理內(nèi)存分配,并且建立了物理到虛擬地址的映射。

第四個(gè)區(qū)域:PKMAP地址段

該區(qū)域跟fixmap區(qū)域都是用來將高端物理內(nèi)存頁映射到內(nèi)核的線性地址范圍,以使內(nèi)核能夠訪問他。但為什么還要分兩個(gè)區(qū)域呢?他們有什么異同?

kmap和fixmap驅(qū)動(dòng)的地址范圍都是有限的,所以不能長(zhǎng)久持有,最好使用完后,就盡快的釋放。

其中kmap區(qū)域的API函數(shù)為:kmap/kunmap,該函數(shù)可以休眠,在地址資源緊張的時(shí)候就會(huì)發(fā)生休眠。

fixmap區(qū)域的api函數(shù)為:kmap_atomic/__kunmap_atomic,該函數(shù)為每個(gè)cpu都保留一個(gè)地址槽,并且該函數(shù)是原子的,不會(huì)休眠。使用kmap_atomic影射高端物理內(nèi)存頁,處理完后(并且該處理不應(yīng)該休眠,同時(shí)kmap_atomic還會(huì)禁止搶占),就應(yīng)該盡快調(diào)用__kunmap_atomic進(jìn)行釋放。所以該函數(shù)可以在中斷上下文中使用

kmap地址段的開始虛擬地址和大小在trunk/arch/arm/mm/mmu.c中的kmap_init函數(shù)就指定了。

關(guān)于kmap的詳細(xì)分析,見我的另一篇blog文章。

第五個(gè)區(qū)域:內(nèi)核地址空間的直接映射區(qū),即linux內(nèi)核的低端內(nèi)存區(qū)

該區(qū)域也稱為內(nèi)核邏輯地址空間  是指從PAGE_OFFSET(3G)到high_memory之間的線性地址空間,是系統(tǒng)物理內(nèi)存映射區(qū),它映射了全部或部分(如果系統(tǒng)包含高端內(nèi)存)物理內(nèi)存。內(nèi)核邏輯地址空間與系統(tǒng)RAM內(nèi)存物理地址空間是一一對(duì)應(yīng)的,內(nèi)核邏輯地址空間中的地址與RAM內(nèi)存物理地址空間中對(duì)應(yīng)的地址只差一個(gè)固定偏移量(3G),如果RAM內(nèi)存物理地址空間從0x00000000地址編址,那么這個(gè)偏移量就是PAGE_OFFSET(0xc0000000)。

系統(tǒng)初始化過程中將低端內(nèi)存永久映射到了內(nèi)核邏輯地址空間,為低端內(nèi)存建立了虛擬映射頁表。低端內(nèi)存內(nèi)物理內(nèi)存的物理地址與線性地址之間的轉(zhuǎn)換可以通過__pa(x)和__va(x)兩個(gè)宏來進(jìn)行:

#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) __pa(x)將內(nèi)核邏輯地址空間的地址x轉(zhuǎn)換成對(duì)應(yīng)的物理地址,相當(dāng)于__virt_to_phys((unsigned long)(x)),

__va(x)則相反,把低端物理內(nèi)存空間的地址轉(zhuǎn)換成對(duì)應(yīng)的內(nèi)核邏輯地址,相當(dāng)于((void *)__phys_to_virt((unsigned long)(x)))

該區(qū)域的內(nèi)存分配函數(shù):kmalloc/kfree和__get_free_page都是從低端內(nèi)存來分配內(nèi)存

第六個(gè)區(qū)域:高端內(nèi)存vmalloc區(qū)

該區(qū)域是屬于linux內(nèi)核的高端內(nèi)存地址,該區(qū)域分配的虛擬地址是連續(xù)的,但對(duì)應(yīng)的物理地址則可能是不連續(xù)的。該區(qū)域的內(nèi)存分配api函數(shù)為:vmalloc/vfree, 該區(qū)域的api可以用來分配大片內(nèi)存,但對(duì)應(yīng)的物理內(nèi)存可能是不連續(xù)的。該函數(shù)會(huì)修改頁目錄映射表,因?yàn)橐獮閷?duì)應(yīng)的虛擬地址和物理地址建立映射關(guān)系。

另外vmalloc區(qū)域跟高端內(nèi)核(high_memory)有一個(gè)8MB的保留區(qū)域。端內(nèi)存的物理地址與線性地址之間的轉(zhuǎn)換不能使用上面的__pa(x)和__va(x)宏,關(guān)于該區(qū)域linux內(nèi)核的文檔:arm/memmory.txt有如下的描述:

  1. vmalloc() / ioremap() space
  2. Memory returned by vmalloc/ioremap will 
  3. be dynamically placed in this region. 
  4. Machine specific static mappings are also 
  5. located here through iotable_init(). 
  6. VMALLOC_START is based upon the value 
  7. of the high_memory variable, and VMALLOC_END 
  8. is equal to 0xff000000. 

第七個(gè)區(qū)域:DMA內(nèi)存映射區(qū)

該區(qū)域是為DMA分配內(nèi)存的,該段區(qū)域的開始地址和大小在

trunk/arch/arm/mm/dma-mapping.c中已經(jīng)指定了。

分別由consistent_base,DEFAULT_CONSISTENT_DMA_SIZE,

CONSISTENT_END指定該區(qū)域的開始地址,大小,結(jié)束地址。

該區(qū)域的內(nèi)存分配api函數(shù)為:dma_alloc_coherent/dma_free_coherent,

該分配函數(shù)會(huì)建立映射表,并且分配出來的物理地址是連續(xù)的。

dma_alloc_coherent的核心函數(shù)為:__dma_alloc。具體詳細(xì)的流程,

請(qǐng)見我的另外一篇blog。在調(diào)用這個(gè)api進(jìn)行dma內(nèi)存分配時(shí),

虛擬地址是從CONSISTENT_END高地址往consistent_base低地址方向分配的,

即第一次dma_alloc_coherent調(diào)用的返回值>第二次dma_alloc_coherent

調(diào)用的返回值。請(qǐng)看圖3一個(gè)實(shí)際的系統(tǒng)dma分配的內(nèi)存情況

另外dma分配函數(shù)分配的物理頁是屬于低端內(nèi)存,但他會(huì)通過__dma_alloc_remap函數(shù),將該物理頁重新映射到dma所屬的地址范圍。所以同一個(gè)物理頁存在兩個(gè)虛擬地址映射,因?yàn)樵撐锢眄搶?duì)應(yīng)的低端內(nèi)存地址在內(nèi)核初始化的時(shí)候,就已經(jīng)映射建立好了。

第八個(gè)區(qū)域:Fixmap映射區(qū)

該區(qū)域的開始地址和大小在trunk/arch/arm/include/asm/fixmap.h文件中指定了,

該區(qū)域的地址范圍:[0xfff00000,0xfffe0000],該區(qū)域是屬于最頂部的pte頁表中

(set_top_pte),他為系統(tǒng)中的每個(gè)cpu都保留了16個(gè)page頁的虛擬地址。

該區(qū)域有兩個(gè)特殊函數(shù):

  1. fix_to_virt/virt_to_fix  
  2. #define __virt_to_fix(x)(((x) - FIXADDR_START) >> PAGE_SHIFT) 

表示虛擬地址相對(duì)FIXADDR_START偏移的頁框數(shù),該返回值應(yīng)該屬于

[0,15]之間。

第九個(gè)區(qū)域:CPUvector page

該區(qū)域是用來映射cpu的中斷向量表,因?yàn)閘inux arm使用的高端向量,即cpu中斷產(chǎn)生時(shí),pc指針會(huì)自動(dòng)跳轉(zhuǎn)到0xffff0000+4*vector_num的地方。

圖4

line1107分配一個(gè)低端的物理內(nèi)存頁框,line1109 early_trap_init將中斷向量表的內(nèi)容拷貝到這個(gè)新分配的物理頁框中。

圖5

line1149-1153:將line1107行分配的物理頁映射到虛擬地址0xffff0000,為cpu中斷產(chǎn)生時(shí),做好準(zhǔn)備(對(duì)應(yīng)的地址有各自的跳轉(zhuǎn)代碼,來處理各自的中斷異常)。在這里這個(gè)物理頁同樣是存在兩個(gè)虛擬地址的映射,一個(gè)是低端虛擬地址的影射,一個(gè)是高端虛擬地址的映射

最后附一個(gè)我們實(shí)際使用中的contexA9雙核,ram為1GB大小的系統(tǒng)的linux內(nèi)存分布情況圖:

圖6

可以結(jié)合圖1和圖6一起分析來加深對(duì)linux的內(nèi)存分布情況的理解,至于圖1是怎么來的,就需要看上面每個(gè)段的具體分析。 

責(zé)任編輯:武曉燕 來源: 嵌入式ARM
相關(guān)推薦

2014-06-06 16:08:17

初志科技

2017-05-15 21:50:54

Linux引號(hào)

2021-07-09 05:49:53

分布式代碼算法

2019-11-19 14:48:00

Kafka文件存儲(chǔ)

2021-08-30 12:05:46

Linux字節(jié)對(duì)齊代碼

2021-08-06 11:50:49

Linux 字節(jié)對(duì)齊Linux 系統(tǒng)

2021-08-17 11:45:44

LinuxC語言字節(jié)

2011-09-19 15:40:35

2020-07-29 08:14:59

云計(jì)算云遷移IT

2017-11-20 09:00:34

Linux服務(wù)器時(shí)間同步

2011-05-19 16:47:50

軟件測(cè)試

2012-05-01 08:06:49

手機(jī)

2012-05-31 09:53:38

IT風(fēng)云15年

2013-12-12 17:50:36

開源系統(tǒng)Linux

2015-08-20 09:17:36

Java線程池

2015-09-14 09:28:47

2021-08-11 21:46:47

MySQL索引join

2017-03-08 08:53:44

Git命令 GitHub

2009-02-19 10:21:00

路由多WAN口

2015-08-13 10:54:46

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产精品欧美精品日韩精品 | 亚洲国产成人精品久久久国产成人一区 | 精品亚洲视频在线 | 日韩电影一区 | 国产视频久久久 | 国产高潮好爽受不了了夜色 | 成人欧美| 国产第一亚洲 | 欧美性一区二区三区 | 精品日韩一区 | 美女黄网 | 日韩一二三区视频 | 久久av资源网 | 在线2区 | 夜夜精品浪潮av一区二区三区 | 在线日韩 | 呦呦在线视频 | 亚洲成人精品 | 中文字幕在线播放第一页 | 成人免费看黄网站在线观看 | 涩涩视频在线播放 | 精品欧美乱码久久久久久 | 精品久久精品 | 日本免费黄色 | 91福利网| 国产激情在线观看 | 精国产品一区二区三区四季综 | 精品国产一区二区三区性色 | 黄网站免费在线观看 | 成人欧美一区二区三区色青冈 | 国产99久久精品一区二区永久免费 | 黄色国产大片 | 国产精品亚洲片在线播放 | 在线播放亚洲 | 日韩av成人 | 国产免费一区二区三区 | 天天宗合网 | 日本亚洲一区 | 一级毛片免费完整视频 | 国产精品99久久久久 | 精品日韩一区 |