Linux內(nèi)存管理和尋址詳細(xì)介紹
1.概念
內(nèi)存管理模式
段式:內(nèi)存分為了多段,每段都是連續(xù)的內(nèi)存,不同的段對(duì)應(yīng)不用的用途。每個(gè)段的大小都不是統(tǒng)一的,會(huì)導(dǎo)致內(nèi)存碎片和內(nèi)存交換效率低的問題。
頁式:內(nèi)存劃分為多個(gè)內(nèi)存頁進(jìn)行管理,如在 Linux 系統(tǒng)中,每一頁的大小為 4KB
。由于分了頁后,就不會(huì)產(chǎn)生細(xì)小的內(nèi)存碎片。但是仍然也存在內(nèi)存碎片問題。
段頁式:段式和頁式結(jié)合。
地址類型劃分
邏輯地址:程序所使用的地址,通常是沒被段式內(nèi)存管理映射的地址,稱為邏輯地址
線性地址:通過段式內(nèi)存管理映射的地址,稱為線性地址,也叫虛擬地址
虛擬地址:通過段式內(nèi)存管理映射的地址,稱為線性地址,也叫虛擬地址
物理地址:物理內(nèi)存地址
說明:
Inetel處理器中,邏輯地址是「段式內(nèi)存管理」轉(zhuǎn)換前的地址,線性地址則是「頁式內(nèi)存管理」轉(zhuǎn)換前的地址。
段式內(nèi)存管理映射而成的地址不再是“物理地址”了,Intel 就稱之為“線性地址”(也稱虛擬地址)。于是,段式內(nèi)存管理先將邏輯地址映射成線性地址,然后再由頁式內(nèi)存管理將線性地址映射成物理地址。
linux內(nèi)存主要是頁式內(nèi)存管理,同時(shí)也有涉及段式機(jī)制。當(dāng)前Linux內(nèi)核所采取的辦法是使段式映射的過程實(shí)際上不起什么作用。
Intel最早處理器80286是純段式管理,80386段式和頁式均存在。
2.頁式管理
x86架構(gòu)32位cpu
? 二級(jí)頁表選址方式,一個(gè)內(nèi)存頁4KB大小,一級(jí)頁目錄表1024項(xiàng),二級(jí)頁表1024項(xiàng),一個(gè)頁表項(xiàng)4字節(jié)。一級(jí)頁目錄表項(xiàng)全部分配,二級(jí)頁表在需要的時(shí)候創(chuàng)建。(局部性原理)。
虛擬地址32位
10+10+12,分別索引1級(jí)頁表號(hào),2級(jí)頁表項(xiàng),記錄物理基地址的偏移地址。使用PAE機(jī)制之后32bit系統(tǒng)支持最大的內(nèi)存是64GB(地址是32+4=36位)。
線性地址尋址物理地址步驟
先根據(jù)10位尋址1級(jí)頁表號(hào),1級(jí)頁表號(hào)中記錄了2級(jí)頁表的地址
找到2級(jí)頁表地址后,接著根據(jù)虛擬地址的另10位尋找2級(jí)頁表中表項(xiàng)的位置
找到2級(jí)頁表的表項(xiàng)之后,表項(xiàng)中記錄了該虛擬地址映射物理地址的起始地址,表項(xiàng)的大小是4字節(jié)32bit
根據(jù)找到的物理地址的起始地址結(jié)合虛擬地址的后12位作為偏移計(jì)算出最終的物理地址
x86架構(gòu) 64位cpu
存在更多級(jí)頁表
全局頁目錄項(xiàng) PGD(Page Global Directory上層頁目錄項(xiàng) PUD(Page Upper Directory)中間頁目錄項(xiàng) PMD(Page Middle Directory)頁表項(xiàng) PTE(Page Table Entry)
線性地址尋址物理地址步驟
線性地址為48bit,最大物理地址為52bit,實(shí)際物理內(nèi)存地址總線寬度是40bit,也就是支持1TB物理內(nèi)存x86_64有四級(jí)頁表,原理同x86系統(tǒng),也是一層層的尋址CR3寄存器保存最高層一級(jí)表的起始物理地址,因此尋址首先就是要獲取到CR3寄存器中的值每個(gè)PTE表項(xiàng)的大小是8個(gè)字節(jié)也就是64bit
TLB
在 CPU 芯片中,加入了一個(gè)專門存放程序最常訪問的頁表項(xiàng)的 Cache,這個(gè) Cache 就是 TL(Translation Lookaside Buffer) 。通常稱為頁表緩存、轉(zhuǎn)址旁路緩存、快表等。那么在CPU的內(nèi)存管理單元MMU尋址時(shí),會(huì)先查 TLB,如果沒找到,才會(huì)繼續(xù)查常規(guī)的頁表。
專有名詞
PDT:頁目錄表,多級(jí)頁表一級(jí)頁表,32bit系統(tǒng)有1024個(gè)頁目錄
PTT:頁表項(xiàng)表,多級(jí)頁表二級(jí)頁表,32bit系統(tǒng)有每個(gè)頁目錄下有1024個(gè)頁表項(xiàng),每個(gè)表項(xiàng)4個(gè)字節(jié)
PDE:頁表的基址,是PDT中一項(xiàng)
PTE:是頁的基址,是PTT中一項(xiàng)
GDT:全局描述符表,邏輯地址轉(zhuǎn)為線性地址用到
LDT:局部描述符表,邏輯地址轉(zhuǎn)為線性地址用到
3.地址劃分
32系統(tǒng)
內(nèi)核1G: 0xC0 00 00 01 - 0xFF FF FF FF
用戶3G: 0x00 00 00 00 - 0xC0 00 00 00
0xC0 00 00 00 == 3G
64位系統(tǒng):
內(nèi)核128T: 0xFF FF 80 00 00 00 00 00 - 0xFF FF FF FF FF FF FF FF (高位)
0xFF FF 7F FF FF FF FF FF - 0xFF FF FF FF FF FF FF FF(自己計(jì)算)
用戶128T: 0x00 00 00 00 00 00 00 00 - 0x00 00 7F FF FF FF FF FF (低位)
0x00 00 80 00 00 00 00 00 - 0x00 00 80 00 00 00 00 00 (自己計(jì)算)
? 0x00 00 7F FF FF FF FF FF == 127T
? 疑問:64位系統(tǒng)128T是分界線是127T?
訪問權(quán)限
進(jìn)程在用戶態(tài)時(shí),只能訪問用戶空間內(nèi)存
只有進(jìn)入內(nèi)核態(tài)后,才可以訪問內(nèi)核空間的內(nèi)存
PAE機(jī)制
? CPU位寬指的是一個(gè)時(shí)鐘周期內(nèi)CPU能處理的二進(jìn)制位數(shù),普通場(chǎng)景中32位系統(tǒng)CPU的地址總線可以是32位,但是引入了PAE機(jī)制之后,16位CPU的地址總線位寬可以是20位(物理內(nèi)存1M),32位CPU的地址總線可以是36位(物理內(nèi)存64GB),64位CPU的地址總線位寬可以是40位(物理內(nèi)存1TB)。因此我們不能簡(jiǎn)單的說32位系統(tǒng)只支持最大4GB的內(nèi)存條。
4. 調(diào)試
程序寄存器
cs:是代碼段寄存器
ds:是數(shù)據(jù)段寄存器
ss:是堆棧段寄存器
es:是擴(kuò)展段寄存器
fs:是標(biāo)志段寄存器 32位之后才有
gs:是全局段寄存器 32位之后才有
示例一個(gè)內(nèi)核宕機(jī)的日志:
RIP: 0010:[
RSP: 0018:ffff886241737d98 EFLAGS: 00010246
RAX: ffff880034814d40 RBX: ffff881fc6248740 RCX: 0000000000000200
RDX: 0000000000000000 RSI: 0000000000000286 RDI: ffff881fc6381858
RBP: ffff886241737d98 R08: ffff886241734000 R09: 0000000000000000
R10: ffff880034814d40 R11: 0000000000000200 R12: ffff881fc62487a0
R13: 0000000000000000 R14: 00007fff86cb6260 R15: ffff881fc6381858
FS: 00007f78b59b8720(0000) GS:ffff885ffe3c0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f690a057180 CR3: 0000006208985000 CR4: 00000000003627e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
查看程序寄存器
使用GDB隨意調(diào)試一個(gè)linux 32位上的ELF32的可執(zhí)行文件,使用info r命令查看一下寄存器情況:
段寄存器有0x23和0x2b兩種情況:
十六進(jìn)制:0023
二進(jìn)制:0000000000100 0 11 - 段序號(hào):4 - 表類型:GDT - 特權(quán)級(jí):Ring3
十六進(jìn)制:002B
二進(jìn)制:0000000000101 0 11 - 段序號(hào):5 - 表類型:GDT - 特權(quán)級(jí):Ring3
段序號(hào):從第四位開始 表類型:第三位 特權(quán)級(jí):第1、2位
Linux下沒有找到可以直接用什么命令或者工具查看GDT的方式,于是去源代碼中尋找答案:
看到了嗎,這兩項(xiàng)所描述的段和Windows一樣,基地址為0,大小為4GB。
Windows和Linux都選擇了通過這種方式架空了CPU的分段內(nèi)存管理機(jī)制。
但需要說明一下的時(shí),雖然兩個(gè)操作系統(tǒng)都是這種情況,但并不意味著段機(jī)制徹底沒用到,CPU的任務(wù)管理TSS還是需要用到,這一點(diǎn)大家知道就行了,在linux64位系統(tǒng)下分段機(jī)制不被待見,但是操作系統(tǒng)仍然會(huì)保持先分段再分頁的尋址方式。
結(jié)語
到此這篇關(guān)于Linux內(nèi)存管理和尋址詳細(xì)介紹的文章就介紹到這了,更多相關(guān)Linux內(nèi)存管理和尋址內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
linux中vim如何刪除當(dāng)前文件中的所有內(nèi)容
這篇文章主要介紹了linux中vim如何刪除當(dāng)前文件中的所有內(nèi)容問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11Linux下新增用戶、指定用戶組、家目錄、獲取sudo權(quán)限方式
這篇文章主要介紹了Linux下新增用戶、指定用戶組、家目錄、獲取sudo權(quán)限方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04Linux下安裝軟件包報(bào)依賴等相關(guān)問題的解決方法
大家好,本篇文章主要講的是Linux下安裝軟件包報(bào)依賴等相關(guān)問題的解決方法,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話,記得收藏一下2021-12-12apache開啟.htaccess及.htaccess的使用方法
今天本地調(diào)試PHP程序,用到了.htaccess,而默認(rèn)配置里面開啟.htaccess,在網(wǎng)上找到了開啟.htaccess的可行方法,供朋友們借鑒。2010-12-12CentOS7安裝mysql5.7解壓縮版簡(jiǎn)明教程
這篇文章主要介紹了CentOS7安裝mysql5.7解壓縮版,簡(jiǎn)單介紹了CentOS7環(huán)境下的mysql5.7壓縮版下載、解壓、安裝、配置、密碼設(shè)置等相關(guān)命令及操作技巧,需要的朋友可以參考下2018-03-03Linux下php連接SQLServer 2000數(shù)據(jù)庫的配置方法
Linux服務(wù)器中的php程序能夠連接到Windows服務(wù)器中的SQL Server 2000數(shù)據(jù)庫,這里分享下配置方法,需要的朋友可以參考下2013-06-06