当前位置:首页 » 操作系统 » linux虚拟地址

linux虚拟地址

发布时间: 2022-06-11 15:34:26

A. linux下32位虚拟地址空间是多少

64位的linux采用4级页表,支持的最大物理内存为64T。 对于虚拟地址空间的划分,将0x0000,0000,0000,0000 – 0x0000,7fff,ffff,f000这128T地址用于用户空间;而0xffff,8000,0000,0000以上的128T为系统空间地址。 具体的不是一两句能说清楚了。

B. Linux下怎样在进程中获取虚拟地址对应的物理地址

Linux文件目录中的/proc记录着当前进程的信息,称其为虚拟文件系统。在/proc下有一个链接目录名为self,这意味着哪一个进程打开了它,self中存储的信息就是所链接进程的。self中有一个名为page_map的文件,专门用来记录所链接进程的物理页号信息。这样通过/proc/pid/page_map文件,允许一个用户态的进程查看到每个虚拟页映射到的物理页

/proc/pid/page_map中的每一项都包含了一个64位的值,这个值内容如下所示。每一项的映射方式不同于真正的虚拟地址映射,其文件中遵循独立的对应关系,即虚拟地址相对于0x0经过的页面数是对应项在文件中的偏移量

* /proc/pid/pagemap. This file lets a userspace process find out which
physical frame each virtual page is mapped to. It contains one 64-bit
value for each virtual page, containing the following data (from
fs/proc/task_mmu.c, above pagemap_read):

* Bits 0-54 page frame number (PFN) if present//present为1时,bit0-54表示物理页号
* Bits 0-4 swap type if swapped
* Bits 5-54 swap offset if swapped
* Bit 55 pte is soft-dirty (see Documentation/vm/soft-dirty.txt)
* Bit 56 page exclusively mapped (since 4.2)
* Bits 57-60 zero
* Bit 61 page is file-page or shared-anon (since 3.5)
* Bit 62 page swapped
* Bit 63 page present//如果为1,表示当前物理页在内存中;为0,表示当前物理页不在内存中

在计算物理地址时,只需要找到虚拟地址的对应项,再通过对应项中的bit63判断此物理页是否在内存中,若在内存中则对应项中的物理页号加上偏移地址,就能得到物理地址

通过程序获取物理地址并验证写时拷贝技术

#include <stdio.h>


#include <stdlib.h>


#include <sys/types.h>


#include <unistd.h>


#include <sys/stat.h>


#include <fcntl.h>


#include <stdint.h>


//计算虚拟地址对应的地址,传入虚拟地址vaddr,通过paddr传出物理地址
void mem_addr(unsigned long vaddr, unsigned long *paddr)
{
int pageSize = getpagesize();//调用此函数获取系统设定的页面大小

unsigned long v_pageIndex = vaddr / pageSize;//计算此虚拟地址相对于0x0的经过的页面数
unsigned long v_offset = v_pageIndex * sizeof(uint64_t);//计算在/proc/pid/page_map文件中的偏移量
unsigned long page_offset = vaddr % pageSize;//计算虚拟地址在页面中的偏移量
uint64_t item = 0;//存储对应项的值

int fd = open("/proc/self/pagemap", O_RDONLY);。。以只读方式打开/proc/pid/page_map
if(fd == -1)//判断是否打开失败
{
printf("open /proc/self/pagemap error ");
return;
}

if(lseek(fd, v_offset, SEEK_SET) == -1)//将游标移动到相应位置,即对应项的起始地址且判断是否移动失败
{
printf("sleek error ");
return;
}

if(read(fd, &item, sizeof(uint64_t)) != sizeof(uint64_t))//读取对应项的值,并存入item中,且判断读取数据位数是否正确
{
printf("read item error ");
return;
}

if((((uint64_t)1 << 63) & item) == 0)//判断present是否为0
{
printf("page present is 0 ");
return ;
}

uint64_t phy_pageIndex = (((uint64_t)1 << 55) - 1) & item;//计算物理页号,即取item的bit0-54

*paddr = (phy_pageIndex * pageSize) + page_offset;//再加上页内偏移量就得到了物理地址
}

const int a = 100;//全局常量

int main()
{
int b = 100;//局部变量
static c = 100;//局部静态变量
const int d = 100;//局部常量
char *str = "Hello World!";

unsigned long phy = 0;//物理地址

char *p = (char*)malloc(100);//动态内存

int pid = fork();//创建子进程
if(pid == 0)
{
//p[0] = '1';//子进程中修改动态内存
mem_addr((unsigned long)&a, &phy);
printf("pid = %d, virtual addr = %x , physical addr = %x ", getpid(), &a, phy);
}
else
{
mem_addr((unsigned long)&a, &phy);
printf("pid = %d, virtual addr = %x , physical addr = %x ", getpid(), &a, phy);
}

sleep(100);
free(p);
waitpid();
return 0;
}

测试结果如下:

全局常量:符合写时拷贝技术

子进程修改动态内存

*其实想要知道虚拟地址对应的物理地址,通过这样的方式也可以得到物理地址而不用操作MMU。。。*

以上就是Linux下怎样在进程中获取虚拟地址对应的物理地址的全文介绍,希望对您学习和使用linux系统开发有所帮助.

C. linux虚地址空间理论上的大小

在多任务操作系统中,每个进程都运行在属于自己的内存沙盘中。这个沙盘就是虚拟地址空间(Virtual Address Space),在32位模式下它是一个4GB的内存地址块。在Linux系统中, 内核进程和用户进程所占的虚拟内存比例是1:3,而Windows系统为2:2(通过设置Large-Address-Aware Executables标志也可为1:3)。这并不意味着内核使用那么多物理内存,仅表示它可支配这部分地址空间,根据需要将其映射到物理内存。

虚拟地址通过页表(Page Table)映射到物理内存,页表由操作系统维护并被处理器引用。内核空间在页表中拥有较高特权级,因此用户态程序试图访问这些页时会导致一个页错误(page fault)。在Linux中,内核空间是持续存在的,并且在所有进程中都映射到同样的物理内存。内核代码和数据总是可寻址,随时准备处理中断和系统调用。与此相反,用户模式地址空间的映射随进程切换的发生而不断变化。

D. linux系统怎么设置虚拟机的ip地址

1.有界面的方式 1.点击虚拟机–>设置–>将网络适配器改为桥接模式 2.回到主页面,点击右上角的两个小电脑,断开链接,然后选择VPN Connections–>config vpn 选择system eth0 ...
2.没有界面,远程连接的方式 找到/etc/sysconfig/network-scripts目录,里面有一个ifcfg-etho...
3.用ssh方式连入虚拟机 SSH是一种网络协议,用于计算机之间的加密登录,ssh命令

E. linux中虚拟地址和物理地址怎样映射

虚拟就是虚拟的,不是实际真是的物理地址。你可以认为,这两个地址之间没关系。
这个虚拟是通过系统和硬件的双重工作,做的一种点对点的映射(当然实际内存分配是按照页来处理)。
也就是软件不需要考虑内存数据的物理地址,只需要用虚拟地址做数据存储处理就行了。

这样一个好处是,软件不需要自己做内存分配,也不需要考虑别的软件的内存占用问题。操作系统会根据当前的内存使用情况,动态的分配内存空间。虚拟内存地址还一个好处是因为是虚拟的,所以内存并不一定非要在物理内存中。可以存放在任何位置,比如把暂时不用的数据放进硬盘上的虚拟内存,腾出真实的物理内存交给程序运行而提高多程序时运行的效率。而且因为每个软件的虚拟内存地址都是从 0 开始,每个软件的寻址都是独立而且顺序的。程序编写和运行时,都好像是机器里面只有自己一个程序在运行,程序开发起来也很容易。软件不需要考虑内存分配的问题,也不需要担心内存不足和两个程序抢同一片内存导致系统整个崩溃的情况。

F. 如何在linux虚拟机修改ip地址

您好,方法
1、依次打开之前拷贝的三个虚拟机,查看当前的IP;
2、进入虚拟机配置IP的配置文件目录;
cd /etc/sysconfig/network-scripts/
3、进入目录后,查看当前目录下的文件,输入命令ls;
4、切换root权限,并输入密码;
5、开始修改配置文件,输入命令:vim ifcfg-eth0,进入配置文件;
6、修改IP为11节点、DNS信息;
7、保存配置文件信息;
8、重启网络服务,输入命令: /etc/init.d/network restart;
9、服务重启成功;
10、查看当前虚拟机的IP地址,输入命令:ifconfig;
由于Slave1虚拟机是从Master中复制来的,则其对应的物理网卡是一样的;
接下来将修改Slave1的网卡信息;
11、点击Slave1虚拟机右下角的小电脑,即网络适配器,点击网络适配器--移除,进行移除网络配置;
12、点击添加--下一步--下一步,完成,开始添加网络适配器;
13、查看物理网络地址:ifconfig,可以看出现在的物理网卡地址与Master节点不同;
14、用同等方法进行配置Slave2。

G. linux 为什么采用虚拟地址

不光Linux用的是是虚拟内存地址,Windows也是用虚拟内存地址,CPU的保护模式下访问内存都是用的虚拟内存地址,这是CPU保护模式下的内存管理方式决定的,只有在实模式下才会直接访问物理内存。

H. linux 怎样查看绑定的虚拟ip

你说的虚拟IP地址是不是指虚拟机,虚拟机的设置 《Linux就该这么学》第一章节中图1-21 你选择的模式是哪一种,就是那种IP地址
桥接模式 NAT模式 仅主机模式
打开Linux终端
2.输入命令,并且执行ifconfig
3.查看结果,其中inet addr 就是本机ip地址

I. linux 虚拟地址,到底怎么理解

不是仅仅 Linux 是这么设计的,整个现代流行的操作系统都是这么设计的。
应用程序被读入内存后,为了保证系统的统一性,所有的程序都有同样的一套寻址规范。这个寻址就是虚拟地址。这个虚拟地址是系统提供转换的,不是程序的工作。

如果系统不提供这个功能,那么应用程序就需要自己去寻找没有被使用的内存,以及还要自己去处理内存容量的问题,而且如果程序调用外部的一些函数库,这些函数库也需要分配内存,这会导致应用程序的设计难度非常大,每个应用程序实际上就是一个操作系统了。多个程序共同运行导致内存使用混乱也很容易出现。
应用程序申请内存,使用的是操作系统的内存分配功能。这样操作系统可以根据实际情况给应用程序内存,程序不需要考虑因为内存位置不同而必须不同编写的难度。而且操作系统还可以提供虚拟内存等等各种方式来扩充内存,这样的内存对于应用程序来说是不需要考虑的,一切都有系统打理。

使用虚拟地址后,对于应用程序来说,他的内存使用不需要考虑其他的程序占用,也不需要考虑内存容量的问题,也不需要考虑内存块位置,函数库的调用也都扔给操作系统打理。这使得应用程序不需要考虑具体如何管理内存,只需要考虑作为应用程序的应用部分。

而且,因为内存是虚拟的,应用程序一些函数调用,操作系统可以把多个应用程序的调用都用同一套数据来处理,这样,既可以节约内存使用(就是启动100个应用程序,也只需要内存里有一套函数库而已),也可以做到外部函数库和应用程序没有直接关联,纯粹是由系统做虚拟地址过渡。

至于为什么 4G ,这是传统+一些兼容的考虑。
以前没有这个技术时,每个程序都可以完全使用整个系统,整个空间是连续的。到了这种虚拟地址的方式后,每个程序还是有自己“独立”的一整套内存地址。但每个程序内存使用量肯定不一样。那么多少内存空间才完全够用呢?当时因为正好使用了 32 位系统。那么就把整个 32 位环境支持的 4G 内存容量作为这个极限。
不过因为内存地址是虚拟的。实际应用程序要用内存,是需要先申请的,所以只有程序申请后,真实内存才会被占用。这个 4G 只是在算法上作为极限。

不过因为 4G 也是硬件极限。所以 4G 以外的地址都是不能使用的,这就导致另一个问题,一些硬件有存储器,有些硬件需要存储空间做交互(比如 PCI ,比如各种硬件,比如 AGP 显卡)。这些存储区域怎么处理?
所以,Windows Vista 的 32 位版在 4G 内存的机器上曾经报出只有 3.5G (有的机器甚至只有 3.25G 可以用)。就是这个问题的解决办法导致的:把硬件的内存用虚拟地址的方式,放到虚拟地址的最后面。这样应用程序调用硬件存储时,可以直接按照内存的方式读写。这样应用程序就很好的统一了存储界面:只有 4G 的内存范围,不存在其他方式的存储调用方式(硬盘需要用读写功能读取到内存后才能处理,而不是直接进行处理)。这样应用程序的开发就很简单,而且整个内存的使用每个程序都一样。不存在各种硬件的原因而不同导致的需要重新设计内存管理算法。操作系统也能根据实际应用程序的需要随时分配数据,也可以根据每个程序的运行情况,区别的提供物理内存或者虚拟的内存。

这么设计最大的一个好处是,硬件环境和应用程序是无关的,中间由操作系统做转换。而且应用程序互相之间也没有影响,就好象整个内存都由他自己一个程序使用一样。

PS:说了半天,我发现我自己也说不清楚其中的缘由……

J. Linux 虚拟地址空间如何分布

一个进程的虚拟地址空间主要由两个数据结来描述。一个是最高层次的:mm_struct,一个是较高层次的:vm_area_structs。最高层次的mm_struct结构描述了一个进程的整个虚拟地址空间。较高层次的结构vm_area_truct描述了虚拟地址空间的一个区间(简称虚拟区)。

1. MM_STRUCT结构

mm_strcut 用来描述一个进程的虚拟地址空间,在/include/linux/sched.h 中描述如下:

struct mm_struct {

struct vm_area_struct * mmap; /* 指向虚拟区间(VMA)链表 */

rb_root_t mm_rb; /*指向red_black树*/

struct vm_area_struct * mmap_cache; /* 指向最近找到的虚拟区间*/

pgd_t * pgd; /*指向进程的页目录*/

atomic_t mm_users; /* 用户空间中的有多少用户*/

atomic_t mm_count; /* 对"struct mm_struct"有多少引用*/

int map_count; /* 虚拟区间的个数*/

struct rw_semaphore mmap_sem;

spinlock_t page_table_lock; /* 保护任务页表和 mm->rss */

struct list_head mmlist; /*所有活动(active)mm的链表 */

unsigned long start_code, end_code, start_data, end_data;

unsigned long start_brk, brk, start_stack;

unsigned long arg_start, arg_end, env_start, env_end;

unsigned long rss, total_vm, locked_vm;

unsigned long def_flags;

unsigned long cpu_vm_mask;

unsigned long swap_address;

unsigned mpable:1;

/* Architecture-specific MM context */

mm_context_t context;

};

对该结构进一步说明如下:

在内核代码中,指向这个数据结构的变量常常是mm。

每个进程只有一个mm_struct结构,在每个进程的task_struct结构中,有一个指向该进程的结构。可以说,mm_struct结构是对整个用户空间的描述。

一个进程的虚拟空间中可能有多个虚拟区间(参见下面对vm_area_struct描述),对这些虚拟区间的组织方式有两种,当虚拟区较少时采用单链表,由mmap指针指向这个链表,当虚拟区间多时采用“红黑树(red_black
tree)”结构,由mm_rb指向这颗树。在2.4.10以前的版本中,采用的是AVL树,因为与AVL树相比,对红黑树进行操作的效率更高。

因为程序中用到的地址常常具有局部性,因此,最近一次用到的虚拟区间很可能下一次还要用到,因此,把最近用到的虚拟区间结构应当放入高速缓存,这个虚拟区间就由mmap_cache指向。

指针pgt指向该进程的页目录(每个进程都有自己的页目录,注意同内核页目录的区别),当调度程序调度一个程序运行时,就将这个地址转成物理地址,并写入控制寄存器(CR3)。

由于进程的虚拟空间及其下属的虚拟区间有可能在不同的上下文中受到访问,而这些访问又必须互斥,所以在该结构中设置了用于P、V操作的信号量mmap_sem。此外,page_table_lock也是为类似的目的而设置。

虽然每个进程只有一个虚拟地址空间,但这个地址空间可以被别的进程来共享,如,子进程共享父进程的地址空间(也即共享mm_struct结构)。所以,用mm_user和mm_count进行计数。类型atomic_t实际上就是整数,但对这种整数的操作必须是“原子”的。

另外,还描述了代码段、数据段、堆栈段、参数段以及环境段的起始地址和结束地址。这里的段是对程序的逻辑划分,与我们前面所描述的段机制是不同的。

mm_context_t是与平台相关的一个结构,对i386 几乎用处不大。

在后面对代码的分析中对有些域给予进一步说明。

2. VM_AREA_STRUCT 结构

vm_area_struct描述进程的一个虚拟地址区间,在/include/linux/mm.h中描述如下:

struct vm_area_struct

struct mm_struct * vm_mm; /* 虚拟区间所在的地址空间*/

unsigned long vm_start; /* 在vm_mm中的起始地址*/

unsigned long vm_end; /*在vm_mm中的结束地址 */

/* linked list of VM areas per task, sorted by address */

struct vm_area_struct *vm_next;

pgprot_t vm_page_prot; /* 对这个虚拟区间的存取权限 */

unsigned long vm_flags; /* 虚拟区间的标志. */

rb_node_t vm_rb;

/*

* For areas with an address space and backing store,

* one of the address_space->i_mmap{,shared} lists,

* for shm areas, the list of attaches, otherwise unused.

*/

struct vm_area_struct *vm_next_share;

struct vm_area_struct **vm_pprev_share;

/*对这个区间进行操作的函数 */

struct vm_operations_struct * vm_ops;

/* Information about our backing store: */

unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE

units, *not* PAGE_CACHE_SIZE */

struct file * vm_file; /* File we map to (can be NULL). */

unsigned long vm_raend; /* XXX: put full readahead info here. */

void * vm_private_data; /* was vm_pte (shared mem) */

};

vm_flag是描述对虚拟区间的操作的标志,其定义和描述如下

标志名 描述

VM_DENYWRITE 在这个区间映射一个打开后不能用来写的文件。

VM_EXEC 页可以被执行。

VM_EXECUTABLE 页含有可执行代码。

VM_GROWSDOWN 这个区间可以向低地址扩展。

VM_GROWSUP 这个区间可以向高地址扩展。

VM_IO 这个区间映射一个设备的I/O地址空间。

VM_LOCKED 页被锁住不能被交换出去。

VM_MAYEXEC VM_EXEC 标志可以被设置。

VM_MAYREAD VM_READ 标志可以被设置。

VM_MAYSHARE VM_SHARE 标志可以被设置。

VM_MAYWRITE VM_WRITE 标志可以被设置。

VM_READ 页是可读的。

VM_SHARED 页可以被多个进程共享。

VM_SHM 页用于IPC共享内存。
VM_WRITE 页是可写的。

较高层次的结构vm_area_structs是由双向链表连接起来的,它们是按虚地址的降顺序来排列的,每个这样的结构都对应描述一个相邻的地址空间范围。之所以这样分割,是因为每个虚拟区间可能来源不同,有的可能来自可执行映象,有的可能来自共享库,而有的则可能是动态分配的内存区,所以对每一个由vm_area_structs结构所描述的区间的处理操作和它前后范围的处理操作不同。因此Linux
把虚拟内存分割管理,并利用了虚拟内存处理例程(vm_ops)来抽象对不同来源虚拟内存的处理方法。不同的虚拟区间其处理操作可能不同,Linux在这里利用了面向对象的思想,即把一个虚拟区间看成一个对象,用vm_area_structs描述了这个对象的属性,其中的vm_operation结构描述了在这个对象上的操作,其定义在/include/linux/mm.h中:

/*

* These are the virtual MM functions - opening of an area, closing and

* unmapping it (needed to keep files on disk up-to-date etc), pointer

* to the functions called when a no-page or a wp-page exception occurs.

*/

struct vm_operations_struct {

void (*open)(struct vm_area_struct * area);

void (*close)(struct vm_area_struct * area);

struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int unused);

};

vm_operations结构中包含的是函数指针;其中,open、close分别用于虚拟区间的打开、关闭,而nopage用于当虚存页面不在物理内存而引起的“缺页异常”时所应该调用的函数。

3.红黑树结构

Linux内核从2.4.10开始,对虚拟区的组织不再采用AVL树,而是采用红黑树,这也是出于效率的考虑,虽然AVL树和红黑树很类似,但在插入和删除节点方面,采用红黑树的性能更好一些,下面对红黑树给予简单介绍。
一颗红黑树是具有以下特点的二叉树:
每个节点着有颜色,或者为红,或者为黑
根节点为黑色
如果一个节点为红色,那么它的子节点必须为黑色
从一个节点到叶子节点上的所有路径都包含有相同的黑色节点数

热点内容
跳转页源码 发布:2024-09-17 03:13:05 浏览:543
html文件上传表单 发布:2024-09-17 03:08:02 浏览:784
聊天软件编程 发布:2024-09-17 03:00:07 浏览:726
linuxoracle安装路径 发布:2024-09-17 01:57:29 浏览:688
两个安卓手机照片怎么同步 发布:2024-09-17 01:51:53 浏览:207
cf编译后没有黑框跳出来 发布:2024-09-17 01:46:54 浏览:249
安卓怎么禁用应用读取列表 发布:2024-09-17 01:46:45 浏览:524
win10设密码在哪里 发布:2024-09-17 01:33:32 浏览:662
情逢敌手迅雷下载ftp 发布:2024-09-17 01:32:35 浏览:337
安卓如何让软件按照步骤自动运行 发布:2024-09-17 01:28:27 浏览:197