1. 程式人生 > >Linux程序的虛擬地址空間

Linux程序的虛擬地址空間

1.以32位系統為例,Linux系統中每個程序共有3GB的使用者地址空間,當用戶呼叫系統呼叫時,核心執行緒會代表程序執行,此時是在核心空間內執行的,故所有程序共享1GB的核心空間. 所以,總的來說,每個程序可用的地址空間共有4GB

2.程序的3GB使用者地址空間由下圖所示:
這裡寫圖片描述

可以看出,程序的使用者地址空間從0x00000000--0xbfffffff(2^30+2^31),依次是程式碼段,資料段,堆,堆疊

3.地址對映:

一個程式在經過編譯、連線之後形成的地址空間是一個虛擬的地址空間,只有當程式執行的時候才會分配具體的物理空間.由此我們可以得知,程式的虛擬地址相對來說是固定的,而實體地址則隨著每一次程式的執行而有所不同.

對於核心空間而言,它與實體記憶體之間存在一個簡單的線性關係,即存在3GB的偏移量.在Linux核心中,這個偏移量叫做PAGE_OFFSET.如果核心的某個實體地址為x,那麼對應的核心虛地址就為x+PAGE_OFFSET.

對於使用者空間而言,它與實體記憶體之間的對映遠不止這麼簡單.與核心空間和物理空間的線性對映不同的是,分頁機制將虛擬使用者空間和實體地址空間分成大小相同的頁,然後再通過頁表將虛擬頁和物理頁塊對映起來.

4.虛擬地址空間舉例:
使用者地址空間:

#include <stdio.h>

int data_var = 0;
int bss_var;

int
main(int argc, char *argv[]) { static int static_data_var = 0; static int static_bss_var, static_bss_var2, static_bss_var3; int *malloc_var = malloc(sizeof(int)); int stack_data_var = 0; int stack_bss_var; printf("address main function: %p\n", main); printf("address data: %p\n"
, &data_var); printf("address bss: %p\n", &bss_var); printf("address static data: %p\n", &static_data_var); printf("address static bass data: %p\n", &static_bss_var); printf("address static bass data2: %p\n", &static_bss_var2); printf("address static bass data3: %p\n", &static_bss_var3); printf("address malloc: %p\n", malloc_var); printf("address stack data: %p\n", &stack_data_var); printf("address stack bss data: %p\n", &stack_bss_var); return 0; } 執行結果: address main function: 0x804844d address data: 0x804a028 address bss: 0x804a03c address static data: 0x804a02c address static bass data: 0x804a030 address static bass data2: 0x804a034 address static bass data3: 0x804a038 address malloc: 0x99b9008 address stack data: 0xbfc17104 address stack bss data: 0xbfc17108 執行結果表明: 資料段中儲存的是:已經初始化了的全域性變數, static靜態變數(不管是已經顯示初始化了的還是沒有初始化的) bss段中儲存的是:沒有初始化的全域性變數 堆中儲存的是:類似malloc這樣的函式申請時的動態變數 堆疊中儲存的是:函式內部定義的變數(不管是已經初始化了的還是沒有初始化的)

核心地址空間:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>

//必選
//模組許可宣告
MODULE_LICENSE("GPL");
//模組載入函式

static int mm_init(void)
{

    void *getpage_addrres, *kmalloc_address, *vmalloc_address;

    getpage_addrres = __get_free_page(GFP_KERNEL);

    kmalloc_address = kmalloc(sizeof(int), GFP_KERNEL);

    vmalloc_address = vmalloc(sizeof(int));

    printk("address get_page: %p\n", getpage_addrres);

    printk("address kmalloc: %p\n", kmalloc_address);

    printk("address vmalloc: %p\n", vmalloc_address);

    printk(KERN_ALERT "mm_init success\n");

    return 0;
}
//模組解除安裝函式
static void mm_exit(void)
{
    printk(KERN_ALERT "mm_exit success\n");
}
//模組註冊
module_init(mm_init);
module_exit(mm_exit);
//可選
MODULE_AUTHOR("edsionte Wu");
MODULE_DESCRIPTION("This is a simple example!\n");
MODULE_ALIAS("A simplest example");

執行結果:
address get_page: e1291000
address kmalloc: e11f8780
address vmalloc: f8430000

結果表明:

    核心空間的地址都是大於0xc0000000的,也即從(2^31+2^30)開始

相關推薦

linux程序地址空間

          要了解程序的地址空間先要了解虛擬記憶體。虛擬記憶體:它是一個抽象概念,它為每個程序提供一個假象,每個程序都獨佔地使用主存。每個程序看到的記憶體都是一致的,稱為虛擬地址空間。          程序的地址空間:作業系統在管理記憶體時,每個程序都有一個獨立的程

程序虛擬地址空間程序建立

程序建立: 解釋一下fork函式:   在Linux中fork函式是很重要的函式,它從已經存在的程序中建立一個新程序,新程序稱為子程序,原程序稱為父程序。     #include<unistd.h>     pid_t fork(void);    返回

程序虛擬地址空間 程式編譯連結過程

1..程式編譯、連結、執行的過程。 (1)預編譯階段**** 生成*.i檔案。 處理原始碼檔案,即以“#”開始的預編譯指令。 有展開巨集;去註釋;新增行號;保留所有#pragma編譯指令。

Linux下的程序1——程序概念,程序切換,上下文切換,虛擬地址空間

程序概述   當一個可執行程式在現代系統上執行時,作業系統會提供一種假象——好像系統上只有這個程式在執行,看上去只有這個程式在使用處理器,主存和IO裝置。   處理器看上去就像在不間斷的一條接一條的執行程式中的指令,即改程式的程式碼和資料是系統儲存器中唯一的

Linux程序虛擬地址空間

1.以32位系統為例,Linux系統中每個程序共有3GB的使用者地址空間,當用戶呼叫系統呼叫時,核心執行緒會代表程序執行,此時是在核心空間內執行的,故所有程序共享1GB的核心空間. 所以,總的來說,每個程序可用的地址空間共有4GB 2.程序的3GB使用者地址空

Linux虛擬地址空間布局

border 指令 AS 庫函數 app 創建 cell 由於 機會 在多任務操作系統中,每個進程都運行在屬於自己的內存沙盤中。這個沙盤就是虛擬地址空間(Virtual Address Space),在32位模式下它是一個4GB的內存地址塊。在Linu

Linux虛擬地址空間布局以及進程棧和線程棧總結(轉)

開始 系統初始 後來 文本 lov fault 和數 ps命令 變量大小 一:Linux虛擬地址空間布局 (轉自:Linux虛擬地址空間布局) 在多任務操作系統中,每個進程都運行在屬於自己的內存沙盤中。這個沙盤就是虛擬地址空間(Virtual Address Spac

淺析實體記憶體、虛擬記憶體和程序地址空間

   ●在一個系統中,程序是和其他程序共享CPU和主存資源。但是共享資源會造成一些不可避免的問題,例如由於儲存器不夠而         程序無法執行,亦或是儲存器被外來的惡意程序破壞等。 早期的記憶體管理機制:  分派方式

Linux下的4G虛擬地址空間

在windows下4G 地址空間中低2G,0x00000000-0x7FFFFFFF 是使用者地址空間,4G地址空間中高2G,0x80000000-0xFFFFFFFF 是 系統地址空間。訪問 系統地址空間需要程式有ring0的許可權。而Linux對4G空間的劃分不同與windows。linu

Linux下4G虛擬地址空間的分佈

我們現在所寫的原始碼並不是我們所說的程式,從C程式碼(.c/.cpp)---->連結程式(.exe)是要經過以下幾個過程才能真正的執行連結的; C源程式--->預編譯處理(.c/.cpp)-->編譯,優化程式(.s)--->彙編程式(.o)---&g

Linux虛擬地址空間佈局

     在多工作業系統中,每個程序都執行在屬於自己的記憶體沙盤中。這個沙盤就是虛擬地址空間(Virtual Address Space),在32位模式下它是一個4GB的記憶體地址塊。在Linux系統中, 核心程序和使用者程序所佔的虛擬記憶體比例是1:3,而Windows系統為2:2(通過設定Large-

一次外場宕機引發對linux記憶體管理的進一步思考--Linux虛擬地址空間如何分佈

0x01 緣由         外場一次伺服器宕機,一群人baba的上去圍觀,分析問題,大部分是猜測,通過回退版本後只解決了問題表象,內在的真實原因沒確定。伺服器上執行著JAVA程式和C程式,到底是什麼導致這次宕機事故。通過分析日誌發現有類似如下錯誤: test_me

Linux虛擬地址空間分佈

在多工作業系統中,每個程序都執行在屬於自己的記憶體沙盤中。這個沙盤就是虛擬地址空間(Virtual Address Space),在32位模式下它是一個4GB的記憶體地址塊。在Linux系統中, 核心程序和使用者程序所佔的虛擬記憶體比例是1:3,而Windo

編譯後的程式是如何在作業系統(linux)中執行的,虛擬地址空間到實際實體記憶體的訪問

Linux中,每個程序通過一個task_struct結構體描述,每個程序地址虛擬空間通過一個mm_struct描述,c語言中每個段空間通過vm_area_struct描述,關係如下, 當執行

程序虛擬地址空間,堆疊、堆、資料段、程式碼段

上圖是程序的虛擬地址空間示意圖。 堆疊段:   1. 為函式內部的區域性變數提供儲存空間。   2. 進行函式呼叫時,儲存“過程活動記錄”。   3. 用作暫時儲存區。如計算一個很長的算術表示式時,可以將部分計算結果壓入堆疊。 資料段(靜態儲存區):   包括BSS段的資料段,BSS段儲存未初始化的全域性

程序虛擬地址空間分配概述

一、為什麼進行記憶體空間的分配 在任何程式設計環境及語言中,記憶體管理都十分重要。在目前的計算機系統或嵌入式系統中,記憶體資源仍然是有限的。因此在程式設計中,有效地管理記憶體資源是程式設計師首先考慮的

linux 內存地址空間管理 mm_struct

clone mod ppr head actual rom __user 虛擬 tom http://blog.csdn.net/yusiguyuan/article/details/39520933 Linux對於內存的管理涉及到非常多的方面,這篇文章首先從對進程虛擬地址

Linux驅動虛擬地址和物理地址的映射

沒有 映射 跟著 申請 不能 物理地址 技術 存在 ngs 一般情況下,Linux系統中,進程的4GB內存空間被劃分成為兩個部分------用戶空間和內核空間,大小分別為0~3G,3~4G。 用戶進程通常情況下,只能訪問用戶空間的虛擬地址,不能訪問到內核空間。 每個

4G虛擬地址空間佈局

4G虛擬地址空間佈局     4G的虛擬記憶體空間: 其中1G是屬於核心空間,另外的3G屬於使用者空間 所有的程序都擁有屬於自己的使用者空間,但卻共享一個核心空間   現在我們從上向下開始分析 首先是使用者空間: ①:128M大

c++ 編譯連結執行原理及虛擬地址空間佈局

當我們寫好.c/.cpp檔案時 此時檔案還不能執行 因為他要經過以下的四步才可以執行   .c/.cpp(生成.i)     編譯(生成.s)      彙編(生成.o)  &nbs