新聞中心
內(nèi)存映射是Linux C應(yīng)用程序開發(fā)中的重要技術(shù)之一。它可以在用戶空間和內(nèi)核空間間建立一種映射關(guān)系,并使得程序可以直接訪問內(nèi)核中的某些數(shù)據(jù)結(jié)構(gòu)和文件系統(tǒng)。本文將介紹在,并闡述它們的實現(xiàn)原理和使用方法。

創(chuàng)新互聯(lián)于2013年開始,先為宜豐等服務(wù)建站,宜豐等地企業(yè),進行企業(yè)商務(wù)咨詢服務(wù)。為宜豐企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
1.匿名內(nèi)存映射
匿名內(nèi)存映射是一種最簡單的內(nèi)存映射技術(shù),它可以在程序內(nèi)部映射一塊未命名的內(nèi)存區(qū)域。使用該技術(shù)需要調(diào)用mmap函數(shù),并指明所需的映射地址、映射大小、映射方式等參數(shù)。
匿名內(nèi)存映射在Linux C應(yīng)用開發(fā)中常用于創(chuàng)建共享內(nèi)存區(qū)域,使得多個進程可以共享同一塊內(nèi)存,并進行數(shù)據(jù)交換。在匿名內(nèi)存映射技術(shù)中,當一個進程寫入共享內(nèi)存時,其它進程都可以立即看到這個變化。
2.文件內(nèi)存映射
文件內(nèi)存映射是Linux C應(yīng)用中另一個常用的內(nèi)存映射技術(shù),它可以將文件映射到進程的地址空間,并可直接在內(nèi)存中讀寫文件。使用該技術(shù)需要調(diào)用mmap函數(shù),指定所需映射的文件和映射方式等參數(shù)。
文件內(nèi)存映射在Linux C應(yīng)用開發(fā)中廣泛應(yīng)用于文件操作和數(shù)據(jù)結(jié)構(gòu)處理等場景。在文件內(nèi)存映射技術(shù)中,使用者可以直接訪問內(nèi)存中的數(shù)據(jù),而無需進行文件讀寫操作,極大地方便了應(yīng)用程序的開發(fā)和實現(xiàn)。
3.共享內(nèi)存映射
共享內(nèi)存映射是Linux C應(yīng)用中非常常用的內(nèi)存映射技術(shù)之一,它可以將內(nèi)存區(qū)域映射到多個進程中,并實現(xiàn)數(shù)據(jù)共享。共享內(nèi)存映射技術(shù)需要調(diào)用shm_open和mmap這兩個函數(shù)。
共享內(nèi)存映射技術(shù)在Linux C應(yīng)用程序開發(fā)中廣泛應(yīng)用于多進程協(xié)作和數(shù)據(jù)共享等場景。通過共享內(nèi)存映射技術(shù),多個進程可以共享一個變量或數(shù)據(jù)結(jié)構(gòu),從而實現(xiàn)進程間數(shù)據(jù)交換和通信。
4.循環(huán)緩沖區(qū)內(nèi)存映射
循環(huán)緩沖區(qū)內(nèi)存映射是一種特殊的內(nèi)存映射技術(shù),它是通過內(nèi)存映射方式實現(xiàn)循環(huán)隊列的操作。使用該技術(shù)需要調(diào)用mmap函數(shù),并指明所需的映射地址、大小、映射方式等參數(shù)。
循環(huán)緩沖區(qū)內(nèi)存映射技術(shù)在Linux C應(yīng)用中廣泛應(yīng)用于數(shù)據(jù)傳輸和隊列處理等場景。該技術(shù)能夠?qū)崿F(xiàn)高效的數(shù)據(jù)傳輸和存儲,從而提高程序的效率和性能。
結(jié)語
內(nèi)存映射技術(shù)是Linux C應(yīng)用程序開發(fā)中非常重要的技術(shù)之一。本文介紹了在Linux C應(yīng)用中常用的幾種內(nèi)存映射技術(shù),包括匿名內(nèi)存映射、文件內(nèi)存映射、共享內(nèi)存映射和循環(huán)緩沖區(qū)內(nèi)存映射,并闡述了它們的實現(xiàn)原理和使用方法。通過內(nèi)存映射技術(shù),我們可以更加高效地處理數(shù)據(jù)和實現(xiàn)多進程協(xié)作,從而提高程序的效率和性能。
相關(guān)問題拓展閱讀:
- 怎么理解linux下內(nèi)存的三級映射?請大俠指教
- 內(nèi)存映射的相關(guān)信息
怎么理解linux下內(nèi)存的三級映射?請大俠指教
邏輯地址-線性地址-物理睜豎激地址
分段纖談,分頁
再詳細點需要閱讀書籍吧,這個也不光是linux,而是386硬悉襪件決定的,建議看下匯編方面的。
內(nèi)存映射的相關(guān)信息
4.1示例代碼
通過前面的理論分析,我們通過編寫一個簡單的程序,來分析內(nèi)核是如何把線性地址映射到物理地址的。
#cattest.c
#include
voidtest(void)
{
printf(hello,world.\n);
}
intmain(void)
{
test();
}
這段代碼很簡單,我們故意要main調(diào)用test函數(shù),就是想看下test函數(shù)的虛擬地址是如何映射成物理地址的。
4.2段式映射分析
我們先編譯,在反匯編下test文件
#gcc-otesttest.c
#objdump-dtest
:
:55push%ebp
:89e5mov%esp,%ebp
804836b:83ec08sub$0x8,%esp
804836e:83ec0csub$0xc,%esp
:push$0x
:e835ffffffcall80482b0
804837b:83c410add$0x10,%esp
804837e:c9leave
804837f:c3ret
:
:55push%ebp
:89e5mov%esp,%ebp
:83ec08sub$0x8,%esp
:83e4f0and$0xfffffff0,%esp
:bmov$0x0,%eax
804838e:83c00fadd$0xf,%eax
:83c00fadd$0xf,%eax
:c1e804shr$0x4,%eax
:c1e004shl$0x4,%eax
804839a:29c4sub%eax,%esp
804839c:e8c7ffffffcall
80483a1:c9leave
80483a2:c3ret
80483a3:90nop
從上述結(jié)果可以看到,ld給test()函數(shù)分配的地址為0x.在elf格式的可執(zhí)行文件代碼中,ld的實際位置總是從0x開始安排程序
的代碼段,對每個程序都是這樣。至于程序在執(zhí)行時在物理內(nèi)存中的實際位置就要由內(nèi)核在為其建立內(nèi)存映射時臨時做出安排,具體地址則
取決段虧于當時所分配到的物理內(nèi)存頁面。假設(shè)該程序已經(jīng)運行,整個映射機制都已經(jīng)建立好,尺燃派并且CPU正在執(zhí)行main()中的call這條指
令,要轉(zhuǎn)移到虛擬地址0x去運行.下面將詳細介紹這個虛擬地址轉(zhuǎn)換為物理地址的映射過程.
首先是段式映射階段。由于0x是一個程序的入口,更重要的是在執(zhí)行的過程中是由CPU中的指令計數(shù)器EIP所指向的,所以在代碼段中
。因此,i386CPU使用代碼段寄存器CS的當前值作為段式映射的選擇子,也就是用它作為在段描述表的下標.那么CS的值是多少呢?
用GDB調(diào)試下test:
(gdb)inforeg
eax0x1016
ecx0x11
edx0x9d915c
ebx0x9d6ff
esp0xbfedb4800xbfedb480
ebp0xbfedb4880xbfedb488
esi0xbfedb
edi0xbfedb4c
eip0x804836e0x804836e
eflags0x282642
cs0x73115
ss0x7b123
ds0x7b123
es0x7b123
fs0x00
gs0x3351
可以看到CS的值為0x73,我們把它分解成二進制:
更低2位為3,說明RPL的值為3,應(yīng)為我們這個程序本省就是在用戶空間,RPL的值自然為3.
第3位為0表示這個下標在GDT中。
高13位為14,所以段描述符在GDT表的第14個表項中,我陵賀們可以到內(nèi)核代碼中去驗證下:
在i386/a/segment.h中:
#defineGDT_ENTRY_DEFAULT_USER_CS14
#define__USER_CS(GDT_ENTRY_DEFAULT_USER_CS*8+3)
可以看到段描述符的確就是GDT表的第14個表項中。
我們?nèi)DT表看看具體的表項值是什么,GDT的內(nèi)容在arch/i386/kernel/head.S中定義:
ENTRY(cpu_gdt_table)
.quad0x00/*NULLdescriptor*/
.quad0x00/*0x0breserved*/
.quad0x00/*0x13reserved*/
.quad0x00/*0x1breserved*/
.quad0x00/*0x20unused*/
.quad0x00/*0x28unused*/
.quad0x00/*0x33TLSentry1*/
.quad0x00/*0x3bTLSentry2*/
.quad0x00/*0x43TLSentry3*/
.quad0x00/*0x4breserved*/
.quad0x00/*0x53reserved*/
.quad0x00/*0x5breserved*/
.quad0x00cf9a000000ffff/*0x60kernel4GBcodeat0x*/
.quad0x00cfffff/*0x68kernel4GBdataat0x*/
.quad0x00cffa000000ffff/*0x73user4GBcodeat0x*/
.quad0x00cffffff/*0x7buser4GBdataat0x*/
.quad0x00/*0x80TSSdescriptor*/
.quad0x00/*0x88LDTdescriptor*/
/*SegmentsusedforcallingPnPBIOS*/
.quad0x00c09a/*0x9032-bitcode*/
.quad0x00809a/*0x9816-bitcode*/
.quad0x00/*0xa016-bitdata*/
.quad0x00/*0xa816-bitdata*/
.quad0x00/*0xb016-bitdata*/
/*
*TheAPMsegmentshavebytegranularityandtheirbases
*andlimitsaresetatruntime.
*/
.quad0x00409a/*0xb8APMCScode*/
.quad0x00009a/*0xc0APMCS16code(16bit)*/
.quad0x00/*0xc8APMDSdata*/
.quad0x00/*0xd0-unused*/
.quad0x00/*0xd8-unused*/
.quad0x00/*0xe0-unused*/
.quad0x00/*0xe8-unused*/
.quad0x00/*0xf0-unused*/
.quad0x00/*0xf8-GDTentry31:double-faultTSS*/
.quad0x00cffa000000ffff/*0x73user4GBcodeat0x*/
我們把這個值展開成二進制:
根據(jù)上述對段描述符表項值的描述,可以得出如下結(jié)論:
B0-B15,B16-B31是0,表示基地址全為0.
L0-L15,L16-L19是1,表示段的上限全是0xffff.
G位是1表示段長度單位均為4KB。
D位是1表示對段的訪問都是32位指令
P位是1表示段在內(nèi)存中。
DPL是3表示特權(quán)級是3級
S位是1表示為代碼段或數(shù)據(jù)段
type為1010表示代碼段,可讀,可執(zhí)行,尚未收到訪問
這個描述符指示了段從0地址開始的整個4G虛存空間,邏輯地址直接轉(zhuǎn)換為線性地址。
所以在經(jīng)過段式映射后就把邏輯地址轉(zhuǎn)換成了線性地址,這也是在linux中,為什么邏輯地址等同于線性地址的原因了。
4.3頁式映射分析
現(xiàn)在進入頁式映射的過程了,Linux系統(tǒng)中的每個進程都有其自身的頁面目錄PGD,指向這個目錄的指針保存在每個進程的mm_struct數(shù)據(jù)結(jié)構(gòu)
中。每當調(diào)度一個進程進入運行的時候,內(nèi)核都要為即將運行的進程設(shè)置好控制寄存器cr3,而MMU的硬件則總是從cr3中取得指向當前頁面目
錄的指針。當我們在程序中要轉(zhuǎn)移到地址0x去的時候,進程正在運行,cr3早以設(shè)置好,指向我們這個進程的頁面目錄了。先將線性
地址0x展開成二進制:
1000
對照線性地址的格式,可見更高10位為二進制的,也就是十進制的32,所以MMU就以32為下標在其頁面目錄中找到其目錄項。這個
目錄項的高20位指向一個頁面表,CPU在這20位后添上12個0就得到頁面表的指針。找到頁面表以后,CPU再來看線性地址中的中間10位,
,即十進制的72.于是CPU就以此為下標在頁表中找相應(yīng)的表項。表項值的高20位指向一個物理內(nèi)存頁面,在后邊添上12個0就得到物
理頁面的開始地址。假設(shè)物理地址在0x620230的,線性地址的更低12位為0x368.那么test()函數(shù)的入口地址就為0x620230+0x368=0x620238
linux c內(nèi)存映射的介紹就聊到這里吧,感謝你花時間閱讀本站內(nèi)容,更多關(guān)于linux c內(nèi)存映射,Linux C應(yīng)用中常用的內(nèi)存映射技術(shù),怎么理解linux下內(nèi)存的三級映射?請大俠指教,內(nèi)存映射的相關(guān)信息的信息別忘了在本站進行查找喔。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗。專業(yè)提供云主機、虛擬主機、域名注冊、VPS主機、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
名稱欄目:LinuxC應(yīng)用中常用的內(nèi)存映射技術(shù)(linuxc內(nèi)存映射)
本文鏈接:http://m.5511xx.com/article/dhdjddj.html


咨詢
建站咨詢
