虚拟地址 1.1 虚拟地址引入 先先来一个测试代码: 1 #include 2 #include 3 #include 4 #include...这个地址绝对不是物理地址,理论上修改了数据为300之后不可能在输出有100,访问一个地址怎么可能又是100也是300。这个地址在系统层面上称之为虚拟地址。...其实PCB和地址空间都是在物理内存里面的,只不过要访问初始化全局数据的时候,不在地址空间上保存,地址空间只会提供线性连续地址,让用户之后通过虚拟地址的地址空间,将虚拟地址转化到为了物理内存中。...,所以在地址空间的初始化数据中就有它的地址虚拟地址,页表的左侧也有它的虚拟地址,在页表右侧就有它对应的物理地址。...修改的只是子进程的物理地址和页表,而地址空间里面的依然是虚拟地址。子进程和父进程的虚拟地址是一样的,只是映射到物理内存到不同区域,所以对应看到的地址是一样的,但内容却不一样。
文章目录 一、虚拟地址空间布局架构 二、用户虚拟地址空间划分 一、虚拟地址空间布局架构 ---- 在 64 位的 Linux 操作系统中 , " ARM64 架构 " 并 不支持 64 位的虚拟地址..., 最大只支持 48 位的虚拟地址 , 64 位地址太大 , 并不需要那么大的内存空间 ; " ARM64 架构 " 中 , Linux 系统的 " 内核虚拟地址 “ 与 ” 用户虚拟地址 "...是等同的 ; 用户虚拟地址 : 0x 0000 0000 0000 0000 ~ 0x 0000 FFFF FFFF FFFF , 48 位有效地址 ; 内核虚拟地址 : 0x FFFF 0000...0000 0000 ~ 0x FFFF FFFF FFFF FFFF , 48 位有效地址 ; 二、用户虚拟地址空间划分 ---- Linux 操作系统 进程 的 " 用户虚拟空间 " 起始地址...4.12\arch\arm64\include\asm\memory.h#86 中 , 定义了 TASK_SIZE 与 TASK_SIZE_64 宏 ; VA_BITS 是编译内核时 , 选择的 " 虚拟地址空间
虚拟地址会通过硬件 MMU(内存管理单元)映射到实际的物理地址空间中,建立虚拟地址到物理地址的映射关系后,对虚拟地址的读写操作实际上就是对物理地址的读写操作,MMU 会将物理地址“翻译”为对应的物理地址...Linux 系统下,应用程序运行在一个虚拟地址空间中,所以程序中读写的内存地址对应也是虚拟地址,并不是真正的物理地址,譬如应用程序中读写 0x80800000 这个地址,实际上并不对应于硬件的 0x80800000...为什么需要引入虚拟地址呢?...针对以上的一些问题,就引入了虚拟地址机制。程序访问存储器所使用的逻辑地址就是虚拟地址,通过逻辑地址映射到真正的物理内存上。...所有应用程序运行在自己的虚拟地址空间中,使得进程的虚拟地址空间和物理地址空间隔离开来,这样做带来了很多的优点: ⚫ 进程与进程、进程与内核相互隔离。
上一节内容的学习我们知道了CPU是如何访问内存的,CPU拿到内存后就可以向其它人(kernel的其它模块、内核线程、用户空间进程、等等)提供服务,主要包括: 以虚拟地址(VA)的形式,为应用程序提供远大于物理内存的虚拟地址空间...Linux用户空间虚拟地址分布 ? 用户进程的代码区一般从虚拟地址空间的 0x08048000 开始,这是为了便于检查空指针。...Linux物理地址和虚拟地址的关系 ? Linux 将 4G 的线性地址空间分为2部分,0~3G 为 user space,3G~4G 为 kernel space。...由于开启了分页机制,内核想要访问物理地址空间的话,必须先建立映射关系,然后通过虚拟地址来访问。为了能够访问所有的物理地址空间,就要将全部物理地址空间映射到 1G 的内核线性空间中,这显然不可能。...虽然这样存在效率的问题,但是内核毕竟可以正常的访问所有的物理地址空间了。 到这里我们应该知道了 Linux 是如何用虚拟地址来映射物理地址的,最后我们用一张图来总结一下: ?
出现保护模式以后,提供虚拟地址空间对实际物理内存抽象虚拟,形成一一映射的关系。
我们这次来根据dump动手来实际转化一个虚拟地址到物理地址,此次的地址不是线性地址映射。...____________| | C:FFFFFF8008015000| A:C549F000 上面0xFFFFFF8008015000就是虚拟地址...= 0x1), 前期条件: 虚拟地址:0xFFFFFF8008015000 init_mm→pgd的值:0xFFFFFF9B4FCA7000 PGD_Index = 虚拟地址>>30位 = (0xFFFFFF8008015000...present的意思是页是否是有效的,无效代表虚拟到物理地址之间的转化无效,当访问虚拟地址的时候就会page fault protection :权限之类的,是否读写执行权限之类的。...如果你访问一段虚拟地址,页表中是无法执行的权限,但是你想执行这段代码就会出错 reference: 引用之类的 cache: cache是否有效。
【操作系统复习】 物理地址虚拟地址 物理地址和虚拟地址的区别 物理地址 逻辑地址 线性地址 为什么要分成物理地址和虚拟地址 物理内存及虚拟内存定义 为什么要有虚拟内存 虚拟内存的实现(可以在页式或段式内存管理的基础上实现...虚拟地址转换为物理地址的过程 快表是存储在哪里的 物理地址和虚拟地址的区别 操作系统有物理地址、逻辑地址、线性地址(也叫虚拟地址)三种地址 物理地址 在存储器里以字节为单位存储信息,为正确地存放或取得信息...,每一个字节单元给以一个唯一的存储器地址,称为物理地址(Physical Address),又叫实际地址或绝对地址。...叫法不同而已 编译器产生的地址 逻辑(虚拟)地址经过分段转化为线性地址 线性地址经过分页转为物理地址 地址转换流程 按照逻辑地址中的页号查快表 若该页已存在快表中,则由页架号和单元号形成绝对地址...若该页不在快表中,则再查主存页表,与单元号形成绝对地址,同时将该页登记到快表中 当快表填满后,又要登记新页时,则需要按照一定替换策略淘汰一个旧的登记项 快表是存储在哪里的 在操作系统中引入快表是为了加快地址映射速度
这个沙盘就是虚拟地址空间(Virtual Address Space),在32位模式下它是一个4GB的内存地址块。...这并不意味着内核使用那么多物理内存,仅表示它可支配这部分地址空间,根据需要将其映射到物理内存。 虚拟地址通过页表(Page Table)映射到物理内存,页表由操作系统维护并被处理器引用。...②生长方向:栈向低地址扩展(即”向下生长”),是连续的内存区域;堆向高地址扩展(即”向上生长”),是不连续的内存区域。这是由于系统用链表来存储空闲内存地址,自然不连续,而链表从低地址向高地址遍历。...8 保留区 位于虚拟地址空间的最低部分,未赋予物理地址。任何对它的引用都是非法的,用于捕捉使用空指针和小整型值指针引用内存的异常情况。...在32位X86架构的Linux系统中,用户进程可执行程序一般从虚拟地址空间0x08048000开始加载。该加载地址由ELF文件头决定,可通过自定义链接器脚本覆盖链接器默认配置,进而修改加载地址。
虚拟地址: 虚拟地址是CPU保护模式下的一个概念,保护模式是80286系列和之后的x86兼容CPU操作模式,在CPU引导完操作系统内核后,操作系统内核会进入一种CPU保护模式,也叫虚拟内存管理,在这之后的程序在运行时都处于虚拟内存当中...,虚拟内存里的所有地址都是不直接的,所以你有时候可以看到一个虚拟地址对应不同的物理地址,比如A进程里的call函数入口虚拟地址是0x001,而B也是,但是它俩对应的物理地址却是不同的,操作系统采用这种内存管理方法...,比如mov 0x4h8这个是虚拟地址,当我们要对这个虚拟地址里写数据时那么MMU会先判断CPU的分页状态寄存器里的标志状态是否被设定,如果被设定那么MMU就会捕获这个虚拟地址物理并在操作系统内核初始化好的内存映射表里查询与之对应的物理地址...,并将其转换成真正的实际物理地址,然后在对这个实际的物理地址给CPU,在由CPU去执行对应的命令,相反CPU往内存里读数据时比如A进程要读取内存中某个虚拟地址的数据,A进程里的指令给的是虚拟地址,MMU...首先会检查CPU的分页状态寄存器标志位是否被设置,如果被设置MMU会捕获这个虚拟地址并将其转换成相应的物理地址然后提交给CPU,在由CPU到内存中去取数据!
---- ---- 一、虚拟地址空间 1.虚拟地址的引出(看不到物理地址,只能看看虚拟地址喽) 1 #include 2 #include 3...首先一个变量肯定是只能有一个值的,但是地址只有一个,而变量的值却出现了两个,那么就必须说明一个结论,现在在内存中应该出现了两个变量了,因为一个变量是绝对不可能出现两个值的,所以我们可以推导出的结论就是内存中现在一定出现了两个全局变量...我们继续推导,一个变量在内存中绝对是只能有一个地址的,这是铁定的事实,也是一定正确的结论,那么我们打印出来的地址就肯定不是真实的地址,因为真实的地址只能对应真实的一个变量,也就是说,其实现在的内存中有两个全局变量...虚拟地址还有另外两个名字,分别叫做线性地址和逻辑地址 2.虚拟地址空间布局(系统角度:六个段。语言角度:五个段。) 1....在内存中是以字节为单位存储信息的,每一个字节单元都会有唯一一个内存物理地址,又叫实际地址、绝对地址或二进制地址,物理地址空间从0开始编号,每次按顺序增加1,所以虚拟地址空间是呈线性增长的。 2.
如果不使用段偏移表示地址的话则称为虚拟地址!...线性地址: 线性地址是逻辑地址到物理地址之间的一个中间层变换,程序代码会产生逻辑地址,或者说是段中的偏移地址,加上相应段的基地址就生成了一个线性地址,逻辑地址是如何知道自己的段基的址?...1.虚拟地址是CPU保护模式下的一个概念,保护模式是80286系列和之后的x86兼容CPU操作模式,在进入虚拟模式之前CPU以及Bootloader,操作系统内核均运行在实模式下,直接对物理地址进行操作...7.内存中有一个叫MMU(内存管理单元)的电子元件负责从操作系统已经初始化好的内存映射表里查询与虚拟地址对应的物理地址并转换, 8.逻辑地址由两部份组成,段标识符和段内偏移量。...线性地址是逻辑地址到物理地址之间的一个中间层变换,程序代码会产生逻辑地址,或者说是段中的偏移地址,加上相应段的基地址就生成了一个线性地址。
虚拟地址空间 虚拟地址空间是一个非常抽象的概念,先根据字面意思进行解释: 它可以用来加载程序数据(数据可能被加载到物理内存上,空间不够就加载到虚拟内存中) 它对应着一段连续的内存地址,起始位置为 0。...虚拟地址空间的大小也由操作系统决定,32位的操作系统虚拟地址空间的大小为 2^32 字节,也就是 4G,64 系统的操作系统虚拟地址空间大小为 2^64 字节,这是一个非常大的数,感兴趣的可以自己计算一下...其次,所谓“独立拥有的虚拟地址”是指对于每一个进程,都可以访问自己的0-4G的虚拟地址。虚拟地址是“虚拟”的,需要转化为“真实”的物理地址。 好比你有你的地址簿,我有我的地址簿。...内核用的896M虚拟地址是直接映射的,意思是只要把虚拟地址减去一个偏移量(3G)就等于物理地址。同样,这里指的还是寻址,实际使用前还是要分配内存。而且896M只是个最大值。...虚拟地址空间中用户区地址范围是 0~3G,里边分为多个区块: 保留区: 位于虚拟地址空间的最底部,未赋予物理地址。任何对它的引用都是非法的,程序中的空指针(NULL)指向的就是这块内存地址。
文章目录 1.虚拟地址空间简介 2.虚拟地址空间布局 参考文献 1.虚拟地址空间简介 虚拟地址空间(Virtual Address Space)是每一个程序被加载运行起来后,操作系统为进程分配的虚拟内存...每个进程所能访问的最大的虚拟地址空间由计算机的硬件平台决定,具体地说是由 CPU 的位数决定的。...比如 32 位的 CPU 决定了虚拟地址空间的大小为 0 - -1,即 0x00000000 - 0xFFFFFFFF,也就是我们常说的 4 GB 虚拟内存空间。...对于 Linux,4GB 的虚拟地址空间的默认分配状态如下: 2.虚拟地址空间布局 C/C++程序为编译链接后生成可执行的二进制文件,由多个段组成,一般包含代码段、数据段和 BSS 段等。...由于可执行文件段的数量较多,映射到虚拟地址空间时,由于段的大小往往并不是系统页大小的整数倍,多余部分也会占用一个页,这就会造成内存空间的浪费。
一般我们不需要从用户态得到进程虚拟地址对应的物理地址,因为一般来说用户进程是完全不关心物理地址的。 少数应用场景下,用户可能会关心,比如在用户态做DMA的场景(如DPDK之类的)。...从用户态得到虚拟地址对应的物理地址,我们不可能去walk进程的page table,也没有权限。不过还好内核给我们提供了一个接口,叫pagemap,而且,这个接口与硬件的体系架构无关。...在/proc/pid/下面有个文件叫pagemap,它会每个page,生成了一个64bit的描述符,来描述虚拟地址这一页对应的物理页帧号或者SWAP里面的便宜,详见文档: linux/Documentation...下面我们忽略swap的影响(假设关闭了swap或者page一直是pin的状态),从DPDK抄一段虚拟地址转换为物理地址的代码: #define phys_addr_t uint64_t #define...,之后加上virtaddr % page_size的页内偏移,得到最终的物理地址。
逻辑地址和物理地址的页内地址一样。 页面大小为 4KB ,为 10的 12 次方,意味着 12 位是 页内地址。 右侧 12 为位页内地址,页内地址完全不变。因此排除 C 和 D。
phys_to_virt只是计算出某个已知物理地址所对应的虚拟地址。将内核物理地址转化为虚拟地址。 virt_to_phys :将内核虚拟地址转化为物理地址。...(注意ioaddr是虚拟地址,而mmio_start是物理地址,它是BIOS得到的,肯定是物理地址,而保护模式下CPU不认物理地址,只认虚拟地址),ioaddr+0就是第一个寄存器的地址,ioaddr+...,我们把这个地址范围称为虚拟地址空间,该空间中的某一个地址我们称之为虚拟地址。...与虚拟地址空间和虚拟地址相对应的则是物理地址空间和物理地址,大多数时候我们的系统所具备的物理地址空间只是虚拟地址空间的一个子集。...5.3 虚拟地址与物理地址介绍 1)虚拟地址/物理地址 如果处理器没有MMU,CPU内部执行单元产生的内存地址信号将直接通过地址总线发送到芯片引脚,被内存芯片接收,这就是物理地址(physical address
进程的地址有三种,分别是虚拟地址(逻辑地址)、线性地址、物理地址。在分析之前先讲一下进程执行的时候,地址的解析过程。...然后根据cs的值选择idt表格中的一项,从而得到代码段的基地址和限长,用基地址加上ip指向的偏移得到一个线性地址,这个线性地址分为三个部分,分别是页目录索引,页表索引,物理地址偏移。...然后到页目录吧和页表中找到物理地址基地址,再加线性地址中的偏移部分,得到物理地址。下面我们看看这些内容是怎么设置的,使得执行的时候能正确找到我们想要的地址去执行代码。我们从fork函数开始。...用线性地址的首地址加上ip 中的偏移,得到线性地址,然后再通过页目录和页表得到物理 地址,物理地址还没有分配则进行缺页异常等处理。...然后计算进程的代码和数据的线性地址首地址和限长,写到ldt的描述符中。接着复制页表,但是不分配物理地址。最后把tss结构和ldt结构挂载到GDT中。fork函数就完成了。
在系统层面上,虚拟地址产生的原因之一也是因为软件应用的地址空间远大于实际物理空间。这个时候系统上的硬件或者软件除了需要完成业务,还要进行VA到PA的转换,让业务访问到实际的物理地址空间。...虚拟地址产生的另外一个原因就是给软件减负,在撸代码的时候不会关心变量具体存在那里,会不会和其它的地址范围发生冲突。 ?...为了实现虚拟地址到物理地址的转换,那么就需要硬件具有格外的资源存储VA2PA的转换关系,即页表。 ? 那么这个时候就会涉及粒度问题,对,就是最近互联网黑话“颗粒度”中的“粒度”。
这就得说下ARM64的虚拟地址空间布局了。再说ARM64之前,需要说下32位的虚拟地址空间。 ?...在32位机器上,整个4G地址空间被分为2份,用户空间占用0-3G, 内核空间占有3G-4G的1G空间。那到64位机器上,虚拟地址空间应该如何分布?...在ARM64上目前还不完全支持64位的虚拟地址,那是如何分配的呢?ARM支持多种位数的虚拟地址宽度,如下图是支持48位的虚拟地址宽度 ?...) 64位用户空间程序:TASK_SIZE=TASK_SIZE_64=1<<39 如果地址宽度是39位的话,虚拟地址空间分布如下: ?...这下清楚了ARM64位虚拟地址空间布局后,我们再回过头去看看我们出错的地址。
领取专属 10元无门槛券
手把手带您无忧上云