新聞中心
在操作系統(tǒng)中,地址管理是非常重要的一部分。Linux系統(tǒng)也不例外。在Linux系統(tǒng)中,每一個(gè)進(jìn)程都是有自己的虛擬地址空間的。虛擬地址和線性地址是兩個(gè)非常重要的概念。虛擬地址是進(jìn)程所見到的地址,而線性地址是真實(shí)的物理地址。本文將詳細(xì)介紹Linux中虛擬地址與線性地址的區(qū)別及原理。

創(chuàng)新互聯(lián)主要從事成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)磐安,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792
一、 基本概念
1. 物理地址
物理地址是指CPU通過總線發(fā)送出去的地址,它描述的是真實(shí)的內(nèi)存地址空間。它是由硬件提供的,是用于表示物理內(nèi)存地址的。
2. 線性地址
線性地址是在操作系統(tǒng)中使用的地址,也可以稱之為虛擬地址。它是由操作系統(tǒng)提供,對(duì)于進(jìn)程來說是唯一且私有的地址空間,可以被分配、映射、保護(hù)等。在x86架構(gòu)下,我們通常使用CR3寄存器來存儲(chǔ)當(dāng)前進(jìn)程的頁目錄表的物理地址,通過線性地址和頁表映射,最終得到物理地址。
3. 虛擬地址
虛擬地址是進(jìn)程中使用的地址,它存在于應(yīng)用程序的虛擬地址空間中。當(dāng)應(yīng)用程序訪問該地址時(shí),操作系統(tǒng)會(huì)將虛擬地址翻譯成真實(shí)的物理地址。虛擬地址空間的大小并不取決于物理內(nèi)存的大小,而是取決于操作系統(tǒng)的指定。每一個(gè)進(jìn)程都有自己的虛擬地址空間。
二、 虛擬地址和線性地址的關(guān)系
虛擬地址到線性地址的轉(zhuǎn)換是由操作系統(tǒng)負(fù)責(zé)的。它基本上是通過分頁機(jī)制來實(shí)現(xiàn)的。在Linux系統(tǒng)中,每個(gè)進(jìn)程都有一個(gè)64位的線性地址空間,可以使用高級(jí)語言編寫的程序能夠使用這個(gè)地址空間中的任何一個(gè)地址。因?yàn)檫@個(gè)地址空間是私有的,所以每個(gè)進(jìn)程都能夠使用它的全部地址,不同進(jìn)程之間的地址不會(huì)沖突。
當(dāng)進(jìn)程需要訪問虛擬地址時(shí),操作系統(tǒng)會(huì)根據(jù)該虛擬地址所在的頁表找到對(duì)應(yīng)的物理地址,然后再讀取實(shí)際的數(shù)據(jù)??梢哉f,虛擬地址是一個(gè)看不見的地址,而線性地址則是一個(gè)真實(shí)的地址。
三、 虛擬地址和線性地址的實(shí)現(xiàn)
在Linux系統(tǒng)中,虛擬地址和線性地址的實(shí)現(xiàn)主要依靠了x86架構(gòu)的分頁機(jī)制。在x86架構(gòu)下,CPU通過地址總線發(fā)送的是線性地址,而真正的存儲(chǔ)數(shù)據(jù)的物理地址被隱藏在該線性地址背后。
為了將虛擬地址轉(zhuǎn)換為線性地址,Linux內(nèi)核維護(hù)了一個(gè)叫做頁表的數(shù)據(jù)結(jié)構(gòu)。頁表中記錄了進(jìn)程中的虛擬地址和線性地址的映射關(guān)系。當(dāng)進(jìn)程訪問虛擬地址時(shí),操作系統(tǒng)會(huì)根據(jù)該虛擬地址所在的頁表找到對(duì)應(yīng)的線性地址,然后再使用x86分頁機(jī)制將該線性地址翻譯成物理地址。
具體的轉(zhuǎn)換流程如下:
1. CPU將虛擬地址發(fā)送給MMU(Memory Management Unit)。
2. MMU通過CR3寄存器中保存的頁表地址找到對(duì)應(yīng)的頁表。
3. MMU使用虛擬地址中的頁表索引查找對(duì)應(yīng)的頁目錄項(xiàng),從而找到虛擬地址映射的物理頁框號(hào)。
4. 然后將物理頁框號(hào)與虛擬地址中的偏移量相加,得到實(shí)際的物理地址。
5. CPU通過總線將真實(shí)的物理地址發(fā)送給存儲(chǔ)器,讀取數(shù)據(jù)。
四、
本文簡要介紹了Linux中虛擬地址和線性地址的概念、關(guān)系和實(shí)現(xiàn)原理。由于虛擬地址的存在,使得在不同的進(jìn)程中,同樣的虛擬地址可以映射到不同的物理地址,保證了每個(gè)進(jìn)程都具有私有的地址空間。而Linux內(nèi)核使用x86分頁機(jī)制將虛擬地址轉(zhuǎn)化為實(shí)際的物理地址,實(shí)現(xiàn)了地址的隔離和保護(hù),確保了操作系統(tǒng)的穩(wěn)定性和安全性。
相關(guān)問題拓展閱讀:
- 典型嵌入式linux軟件部分由哪些模塊組成?他們的功能及相互聯(lián)系? Bootloader分為哪兩階段?分
典型嵌入式linux軟件部分由哪些模塊組成?他們的功能及相互聯(lián)系? Bootloader分為哪兩階段?分
典型的嵌入式系統(tǒng),軟件部分從下到上,分別是boot,kernel,rootfs,fsimg和上層應(yīng)用。
起到的作用分別是,首孫引導(dǎo)內(nèi)核,啟動(dòng)內(nèi)核,掛載根文件系統(tǒng),掛載實(shí)際文件系統(tǒng),開啟上層應(yīng)用主循環(huán)。
你問的這些問題者茄鏈,每一點(diǎn)都可以單獨(dú)拿出來,長篇大論的講很久了。建議去納團(tuán)網(wǎng)上先看相關(guān)的資料。貪多求快是不好的,一個(gè)知識(shí)點(diǎn)一個(gè)知識(shí)點(diǎn)的掌握。
從軟件硬件設(shè)計(jì)特點(diǎn)簡單描述嵌入式產(chǎn)品開發(fā)設(shè)計(jì)流程。
項(xiàng)目論證階段:項(xiàng)目的可行性分析并形成可行性研究報(bào)告。
系統(tǒng)方案階段:對(duì)產(chǎn)品需求加以分析、細(xì)化,并抽象出需要完成的功能列表,明確定義所要完成的任務(wù)。
系統(tǒng)設(shè)計(jì)階段:軟件開發(fā)部分完成軟件需求分析,形成軟件總體設(shè)計(jì)方案,軟件開發(fā)接口規(guī)范等;硬件部分完成硬件總體設(shè)計(jì)方案,接口定義及說明等。
產(chǎn)品詳細(xì)設(shè)計(jì)階段:完成軟/硬件的詳細(xì)設(shè)計(jì),編制代碼,形成軟件各模塊的設(shè)計(jì)說明;硬件部分各單板的原理圖,PCB和料單,同時(shí)完成產(chǎn)品的結(jié)構(gòu)設(shè)計(jì)。
制造聯(lián)試階段:完成產(chǎn)品的系統(tǒng)調(diào)試和可靠性測試,并形成相應(yīng)的系統(tǒng)調(diào)試報(bào)告和可靠性測試報(bào)告。
典型嵌入式Linux軟件部分由哪些模塊組成?它的功能和相互關(guān)系是什么?
Bootloader、嵌入式Linux內(nèi)核、嵌入式文件系統(tǒng)組成。Bootloader完成硬件設(shè)備的初始化以及引導(dǎo)內(nèi)核加載,內(nèi)核通過文件系統(tǒng)來管理對(duì)整個(gè)系統(tǒng)中的所有的數(shù)據(jù)和文件。
BootLoader分為哪兩個(gè)階段?分別實(shí)現(xiàn)了哪些功能?
stage1和stage2兩個(gè)階段。
完成的工作:
硬件設(shè)備初始化。
為加載Bootloader的stage2準(zhǔn)備RAM空間。
拷貝Bootloader的stage2到RAM空間中。
設(shè)置堆棧。
跳轉(zhuǎn)到stage2的C入口點(diǎn)。
stage2完成櫻盯陸的工作:
初始化本階段要使用到的硬件設(shè)備。
監(jiān)測系統(tǒng)內(nèi)存映射。
將內(nèi)核映像和根文件系統(tǒng)映像從Flash設(shè)備上復(fù)制到RAM空間中。
設(shè)置內(nèi)核啟動(dòng)參數(shù)。
調(diào)用啟動(dòng)內(nèi)核。
簡述嵌入式文件系統(tǒng)的種類和管理機(jī)制。
Ext2fs文件系統(tǒng) 2.基于Flash的文件系統(tǒng) 3.基于RAM的文件系統(tǒng) 4.網(wǎng)絡(luò)文件系統(tǒng)。
Linux引入了虛擬文件系統(tǒng)vfs(virtual file system),為各類文件系統(tǒng)提供一個(gè)統(tǒng)一的應(yīng)用編程接口。
如何理解消費(fèi)類電子產(chǎn)品開發(fā)的可裁剪性和可移植性,并以Linux系統(tǒng)為例進(jìn)行說明。
Linux來說,假如我們用不到以太網(wǎng)設(shè)備,我們可以將該設(shè)備的驅(qū)動(dòng)程序以及相關(guān)庫文件等都去掉以縮小體積。
Linux可以在不同架構(gòu)的CPU平臺(tái)上運(yùn)行。
詳細(xì)描述嵌入式Linux軟件開發(fā)的編譯開發(fā)環(huán)境和編譯開發(fā)工具。
開發(fā)環(huán)境:首先宿主機(jī)上需要安裝Linux操作系統(tǒng)。需要為這個(gè)Linux系統(tǒng)安裝以下三個(gè)部分:
函數(shù)庫(glibc):是Linux下C語言的主要函數(shù)庫。
編譯器(gcc):可以將C,C++,匯編源程序和目標(biāo)程序編譯、鏈接成可執(zhí)行文件。
系統(tǒng)頭文件(glibc_header):系統(tǒng)相關(guān)功能的頭文件。
編譯開發(fā)工具:編輯器有Vi和Emacs;編譯器為GCC,是GUN推出的功能強(qiáng)大、性能優(yōu)越的多平臺(tái)編譯器;調(diào)試器為GDB,可以方便的設(shè)置斷點(diǎn)、單步跟蹤等調(diào)試功能;項(xiàng)目管理器“make”,用來控制編譯或者重復(fù)編譯,自動(dòng)管理軟件編譯內(nèi)容、方式和時(shí)機(jī)。
基于S3C2410嵌入式Linux的開發(fā)的邏輯空間和物理空間如何對(duì)應(yīng)?詳細(xì)描述脊頃之。
在支持MMU的32位處理器平臺(tái)上,Linux系統(tǒng)中的物理存儲(chǔ)空則悔間和虛擬存儲(chǔ)空間的地址范圍分別都是從0x到0xFFFFFFFF,共4GB,但物理存儲(chǔ)空間與虛擬存儲(chǔ)空間布局完全不同。Linux運(yùn)行在虛擬存儲(chǔ)空間,并負(fù)責(zé)把系統(tǒng)中實(shí)際存在的遠(yuǎn)小于4GB的物理內(nèi)存根據(jù)不同需求映射到整個(gè)4GB的虛擬存儲(chǔ)空間中。
n 物理存儲(chǔ)空間布局
Linux的物理存儲(chǔ)空間布局與處理器相關(guān),詳細(xì)情況可以從處理器用戶手冊(cè)的存儲(chǔ)空間分布表(memory map)相關(guān)章節(jié)中查到,我們這里只列出嵌入式處理器平臺(tái)Linux物理內(nèi)存空間的一般布局,如圖18-4所示。
圖18-4 Linux物理內(nèi)存空間一般布局示意圖
說明:
1)更大node號(hào)n不能大于MAX_NUMNODES-1。
2)MAX_NUMNODES表示系統(tǒng)支持的最多node數(shù)。在ARM系統(tǒng)中,Sharp芯片最多支持16個(gè)nodes,其他芯片最多支持4個(gè)nodes。
3)numnodes是當(dāng)前系統(tǒng)中實(shí)際的內(nèi)存node數(shù)。
4)在不支持CONFIG_DISCONTIGMEM選項(xiàng)的系統(tǒng)中,只有一個(gè)內(nèi)存node。
5)更大bank號(hào)m不能大于NR_BANKS-1。
6)NR_BANKS表示系統(tǒng)中支持的更大內(nèi)存bank數(shù),一般等于處理器的RAM片選數(shù)。在ARM系統(tǒng)中,Sharp芯片最多支持16個(gè)banks,其他芯片最多支持8個(gè)banks。
7)mem_init()函數(shù)會(huì)將所有節(jié)點(diǎn)的頁幀位碼表所占空間、孔洞頁描述符空間及空閑內(nèi)存頁都釋放掉。
n虛擬存儲(chǔ)空間布局
在支持MMU的系統(tǒng)中,當(dāng)系統(tǒng)做完硬件初始化后就使能MMU功能,這樣整個(gè)系統(tǒng)就運(yùn)行在虛擬存儲(chǔ)空間中,實(shí)現(xiàn)虛擬存儲(chǔ)空間到物理存儲(chǔ)空間映射功能的是處理器的MMU,而虛擬存儲(chǔ)空間與5路存儲(chǔ)空間的映射關(guān)系則是由Linux內(nèi)核來管理的。32位系統(tǒng)中物理存儲(chǔ)空間占4GB空間,虛擬存儲(chǔ)空間同樣占4GB空間,Linux把物理空間中實(shí)際存在的遠(yuǎn)遠(yuǎn)小于4GB的內(nèi)存空間映射到整個(gè)4GB虛擬存儲(chǔ)空間中除映射I/O空間之外的全部空間,所以虛擬內(nèi)存空間遠(yuǎn)遠(yuǎn)大于物理內(nèi)存空間,這就說同一塊物理內(nèi)存可能映射到多處虛擬內(nèi)存地址空間上,這正是Linux內(nèi)存管理職責(zé)所在。圖18-5列出了Linux內(nèi)核中虛擬內(nèi)存空間的一般布局(其實(shí)I/O空間也在其中,通常占用高端內(nèi)存空間,在此未標(biāo)出)。
圖18-5 Linux系統(tǒng)虛擬內(nèi)存空間一般布局示意圖
說明:
1)線性地址空間:是指Linux系統(tǒng)中從0x到0xFFFFFFFF整個(gè)4GB虛擬存儲(chǔ)空間。
2)內(nèi)核空間:內(nèi)核空間表示運(yùn)行在處理器更高級(jí)別的超級(jí)用戶模式(supervisor mode)下的代碼或數(shù)據(jù),內(nèi)核空間占用從0xC到0xFFFFFFFF的1GB線性地址空間,內(nèi)核線性地址空間由所有進(jìn)程共享,但只有運(yùn)行在內(nèi)核態(tài)的進(jìn)程才能訪問,用戶進(jìn)程可以通過系統(tǒng)調(diào)用切換到內(nèi)核態(tài)訪問內(nèi)核空間,進(jìn)程運(yùn)行在內(nèi)核態(tài)時(shí)所產(chǎn)生的地址都屬于內(nèi)核空間。
3)用戶空間:用戶空間占用從0x到0xBFFFFFFF共3GB的線性地址空間,每個(gè)進(jìn)程都有一個(gè)獨(dú)立的3GB用戶空間,所以用戶空間由每個(gè)進(jìn)程獨(dú)有,但是內(nèi)核線程沒有用戶空間,因?yàn)樗划a(chǎn)生用戶空間地址。另外子進(jìn)程共享(繼承)父進(jìn)程的用戶空間只是使用與父進(jìn)程相同的用戶線性地址到物理內(nèi)存地址的映射關(guān)系,而不是共享父進(jìn)程用戶空間。運(yùn)行在用戶態(tài)和內(nèi)核態(tài)的進(jìn)程都可以訪問用戶空間。
4)內(nèi)核邏輯地址空間:是指從PAGE_OFFSET(3G)到high_memory(物理內(nèi)存的大小,更大896)之間的線性地址空間,是系統(tǒng)物理內(nèi)存映射區(qū),它映射了全部或部分(如果系統(tǒng)包含高端內(nèi)存)物理內(nèi)存。內(nèi)核邏輯地址空間與圖18-4中的系統(tǒng)RAM內(nèi)存物理地址空間是一一對(duì)應(yīng)的(包括內(nèi)存孔洞也是一一對(duì)應(yīng)的),內(nèi)核邏輯地址空間中的地址與RAM內(nèi)存物理地址空間中對(duì)應(yīng)的地址只差一個(gè)固定偏移量(3G),如果RAM內(nèi)存物理地址空間從0x地址編址,那么這個(gè)偏移量就是PAGE_OFFSET。
5)低端內(nèi)存:內(nèi)核邏輯地址空間所映射物理內(nèi)存就是低端內(nèi)存(實(shí)際物理內(nèi)存的大小,但是小于896),低端內(nèi)存在Linux線性地址空間中始終有永久的一一對(duì)應(yīng)的內(nèi)核邏輯地址,系統(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) ((unsignedlong)(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)))。
6)高端內(nèi)存:低端內(nèi)存地址之上的物理內(nèi)存是高端內(nèi)存(物理內(nèi)存896之上),高端內(nèi)存在Linux線性地址空間中沒有沒有固定的一一對(duì)應(yīng)的內(nèi)核邏輯地址,系統(tǒng)初始化過程中不會(huì)為這些內(nèi)存建立映射頁表將其固定映射到Linux線性地址空間,而是需要使用高端內(nèi)存的時(shí)候才為分配的高端物理內(nèi)存建立映射頁表,使其能夠被內(nèi)核使用,否則不能被使用。高端內(nèi)存的物理地址于現(xiàn)行地址之間的轉(zhuǎn)換不能使用上面的__pa(x)和__va(x)宏。
7)高端內(nèi)存概念的由來:如上所述,Linux將4GB的線性地址空間劃分成兩部分,從0x到0xBFFFFFFF共3GB空間作為用戶空間由用戶進(jìn)程獨(dú)占,這部分線性地址空間并沒有固定映射到物理內(nèi)存空間上;從0xC到0xFFFFFFFF的第4GB線性地址空間作為內(nèi)核空間,在嵌入式系統(tǒng)中,這部分線性地址空間除了映射物理內(nèi)存空間之外還要映射處理器內(nèi)部外設(shè)寄存器空間等I/O空間。0xC~high_memory之間的內(nèi)核邏輯地址空間專用來固定映射系統(tǒng)中的物理內(nèi)存,也就是說0xC~high_memory之間空間大小與系統(tǒng)的物理內(nèi)存空間大小是相同的(當(dāng)然在配置了CONFIG_DISCONTIGMEMD選項(xiàng)的非連續(xù)內(nèi)存系統(tǒng)中,內(nèi)核邏輯地址空間和物理內(nèi)存空間一樣可能存在內(nèi)存孔洞),如果系統(tǒng)中的物理內(nèi)存容量遠(yuǎn)小于1GB,那么內(nèi)核現(xiàn)行地址空間中內(nèi)核邏輯地址空間之上的high_memory~0xFFFFFFFF之間還有足夠的空間來固定映射一些I/O空間??墒牵绻到y(tǒng)中的物理內(nèi)存容量(包括內(nèi)存孔洞)大于1GB,那么就沒有足夠的內(nèi)核線性地址空間來固定映射系統(tǒng)全部物理內(nèi)存以及一些I/O空間了,為了解決這個(gè)問題,在x86處理器平臺(tái)設(shè)置了一個(gè)經(jīng)驗(yàn)值:896MB,就是說,如果系統(tǒng)中的物理內(nèi)存(包括內(nèi)存孔洞)大于896MB,那么將前896MB物理內(nèi)存固定映射到內(nèi)核邏輯地址空間0xC~0xC+896MB(=high_memory)上,而896MB之后的物理內(nèi)存則不建立到內(nèi)核線性地址空間的固定映射,這部分內(nèi)存就叫高端物理內(nèi)存。此時(shí)內(nèi)核線性地址空間high_memory~0xFFFFFFFF之間的128MB空間就稱為高端內(nèi)存線性地址空間,用來映射高端物理內(nèi)存和I/O空間。896MB是x86處理器平臺(tái)的經(jīng)驗(yàn)值,留了128MB線性地址空間來映射高端內(nèi)存以及I/O地址空間,我們?cè)谇度胧较到y(tǒng)中可以根據(jù)具體情況修改這個(gè)閾值,比如,MIPS中將這個(gè)值設(shè)置為0xB(512MB),那么只有當(dāng)系統(tǒng)中的物理內(nèi)存空間容量大于0xB時(shí),內(nèi)核才需要配置CONFIG_HIGHMEM選項(xiàng),使能內(nèi)核對(duì)高端內(nèi)存的分配和映射功能。什么情況需要?jiǎng)澐殖龈叨宋锢韮?nèi)存以及高端物理內(nèi)存閾值的設(shè)置原則見上面的內(nèi)存頁區(qū)(zone)概念說明。
8)高端線性地址空間:從high_memory到0xFFFFFFFF之間的線性地址空間屬于高端線性地址空間,其中VMALLOC_START~VMALLOC_END之間線性地址被vmalloc()函數(shù)用來分配物理上不連續(xù)但線性地址空間連續(xù)的高端物理內(nèi)存,或者被vmap()函數(shù)用來映射高端或低端物理內(nèi)存,或者由ioremap()函數(shù)來重新映射I/O物理空間。PKMAP_BASE開始的LAST_PKMAP(一般等于1024)頁線性地址空間被kmap()函數(shù)用來永久映射高端物理內(nèi)存。FIXADDR_START開始的KM_TYPE_NR*NR_CPUS頁線性地址空間被kmap_atomic()函數(shù)用來臨時(shí)映射高端物理內(nèi)存,其他未用高端線性地址空間可以用來在系統(tǒng)初始化期間永久映射I/O地址空間。
悶農(nóng)雪
捉騰歪
菠脫失
linux 虛擬地址 線性地址的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux 虛擬地址 線性地址,Linux中虛擬地址與線性地址的區(qū)別及原理簡介,典型嵌入式linux軟件部分由哪些模塊組成?他們的功能及相互聯(lián)系? Bootloader分為哪兩階段?分的信息別忘了在本站進(jìn)行查找喔。
成都服務(wù)器租用選創(chuàng)新互聯(lián),先試用再開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)提供簡單好用,價(jià)格厚道的香港/美國云服務(wù)器和獨(dú)立服務(wù)器。物理服務(wù)器托管租用:四川成都、綿陽、重慶、貴陽機(jī)房服務(wù)器托管租用。
分享文章:Linux中虛擬地址與線性地址的區(qū)別及原理簡介 (linux 虛擬地址 線性地址)
鏈接URL:http://m.fisionsoft.com.cn/article/coegdig.html


咨詢
建站咨詢
