电子商务网站如何进行维护和推广建设部网站官网挂证通报
news/
2025/9/27 18:36:49/
文章来源:
电子商务网站如何进行维护和推广,建设部网站官网挂证通报,官方网站找oem做洗发水厂家,贵阳网站建设odenetARM32位系统的内存布局图
32位操作系统的内存布局很经典#xff0c;很多书籍都是以32位系统为例子去讲解的。32位的系统可访问的地址空间为4GB#xff0c;用户空间为1GB ~ 3GB#xff0c;内核空间为3GB ~ 4GB。 为什么要划分为用户空间和内核空间呢#xff1f;
一般处理器…ARM32位系统的内存布局图
32位操作系统的内存布局很经典很多书籍都是以32位系统为例子去讲解的。32位的系统可访问的地址空间为4GB用户空间为1GB ~ 3GB内核空间为3GB ~ 4GB。 为什么要划分为用户空间和内核空间呢
一般处理器会把运行模式分为好几个比如x86分为rang0 ~ rang3级别。ARMv7架构中又分为好几个模式比如svc模式是给内核用的usr模式是给用户态使用的。
当一个进程执行系统调用时会陷入到内核态中这个时候运行模式就从usr模式转换为svc模式这就是我们常说的内核态。处于内核态的进程是可以访问内核空间的。所以就根据CPU的运行模式划分了两个空间。
我们先看下1GB的内核空间是怎么划分的32位的系统中通常配置的物理内存通常是大于1GB的所以物理内存会划分为两部分低端内存称为线性映射区高端内存称为高端映射区。那这个分界线是怎么计算的呢在ARM32中分界线为760M。低端内存会做一比一映射到3GB ~ 3GB760M。
这里讲的线性映射就是直接把物理内存的地址映射到线性映射区中假设物理内存的DDR起始地址是0映射的时候就有一个偏移量这个偏移量就是0XC0000000page offset。线性映射的地址我们就可以很方便的完成虚拟地址到物理地址的转换只需要加减一个offset就可以。
高端内存的映射就没有线性映射那么简单了使用高端内存时需要完成动态映射。
我们先看下1GB的内核空间剩下都做什么使用了。 vmalloc区域分配的内存在虚拟地址是连续的物理页面可以是离散的。vmalloc大概占用了200M物理内存。 fixmapFix map中的fix指的是固定的意思那么固定什么东西呢其实就是虚拟地址是固定的也就是说有些虚拟地址在编译compile-time的时候就固定下来了而这些虚拟地址对应的物理地址不是固定的是在kernel启动过程中被确定的。 vectorvector区域用于映射CPU vector page大小一页4KB从0xffff0000 - 0xffff1000。
接下来看下3GB用户空间的划分方式一个进程要运行起来必然要有自己的代码段和数据段这部分在加载的时候就会被映射到虚拟地址。 堆空间:从进程的开始到1GB的这部分我们称为堆空间这部分主要是给malloc使用的。 mmap空间:1GB到3GB这部分是给mmap空间使用的mmap可以用来映射文件也可以映射匿名页面。通常用户态分配大段内存的时候Linux通常会使用mmap来完成分配。
从进程的角度看内存布局
readelf 查看程序段
接下来我们通过一个C语言程序学习下内存布局这个例子很简单用malloc函数分配了内存内存然后使用memset将该区域清零。
使用gcc编译为elf后可以使用readelf 查看该程序包含那些段。
#include stdio.h
#include string.h
#include stdlib.h#define SIZE (100 * 1024)
void main()
{char* buf malloc(SIZE);memset(buf, 0x58, SIZE);while(1)sleep(10000);
}gcc -static memory_process.c -o memory_process.elf我们知道通常Linux中流行的可执行文件的格式就是elf。使用gcc编译的elf就是我们讲的elf文件目标文件除了包含了编译后的机器指令代码还包含其他链接信息比如符号表调试信息字符串等通常这些信息会根据不同的属性存放在不同的段section中这里我们只关注常见的段 。 .init程序初始化的代码段。 .text代码段程序编译完后的机器指令。 .data:初始化过的全局的静态变量还有一些局部的静态变量。 .rodata只读变量字符串常量等。 .bss未初始化的全局变量以及初始化为零的变量。
readelf 查看程序头
使用-l参数读下程序头program header它是用来描述OS是如何被映射到进程的虚拟地址空间的。 之前我们看到的30个段在这里分成了7个族并且显示每个族都包含那些段这里我们只关注叫load的族其他族主要是在程序装载的时候起到辅助作用。
第一个族里面包含inittext段他的执行权限是只读可执行的RE。起始地址0x0000000000400000大小是0x00000000000b5986。
另外一个族主要包含data和bss段他的执行权限是可读写RW。起始地址0x00000000006b6120大小是0x00000000000051b8。
进程映射的过程 地址本段在虚拟内存中的地址范围对应vm_area_struct中的vm_start和vm_end。 权限本段的权限; r-读w-写x-执行 p-私有;对应vm_flags。 偏移地址即本段映射地址在文件中的偏移对于有名映射指本段映射地址在文件中的偏移,对应vm_pgoff对于匿名映射为vm_area_struct-vm_start。 主设备号与次设备号所映射的文件所属设备的设备号对应vm_file-f_dentry-d_inode-i_sb-s_dev。匿名映射为0。其中fd为主设备号00为次设备号。 文件索引节点号对应vm_file-f_dentry-d_inode-i_ino与ls –i显示的内容相符。匿名映射为0。 映射的文件名对有名映射而言是映射的文件名对匿名映射来说是此段内存在进程中的作用。[stack]表示本段内存作为栈来使用[heap]作为堆来使用其他情况则为无。
smaps 可以查看更多的内容
➜ example cat /proc/5823/smaps
00400000-004b6000 r-xp 00000000 08:01 2319863 /home/zhongyi/code/example/memory_process.elf
Size: 728 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 640 kB
Pss: 640 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 640 kB
Private_Dirty: 0 kB
Referenced: 640 kB
Anonymous: 0 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
THPeligible: 0
VmFlags: rd ex mr mw me dw sd
006b6000-006bc000 rw-p 000b6000 08:01 2319863 /home/zhongyi/code/example/memory_process.elf
Size: 24 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 24 kB
Pss: 24 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 8 kB
Private_Dirty: 16 kB
Referenced: 24 kB
Anonymous: 16 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
THPeligible: 0
VmFlags: rd wr mr mw me dw ac sd
006bc000-006bd000 rw-p 00000000 00:00 0
Size: 4 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 4 kB
Pss: 4 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 4 kB
Referenced: 4 kB
Anonymous: 4 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
THPeligible: 0
VmFlags: rd wr mr mw me ac sd
010cc000-010ef000 rw-p 00000000 00:00 0 [heap]
Size: 140 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 108 kB
Pss: 108 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 108 kB
Referenced: 108 kB
Anonymous: 108 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
THPeligible: 0
VmFlags: rd wr mr mw me ac sd
7ffd5e0db000-7ffd5e0fc000 rw-p 00000000 00:00 0 [stack]
Size: 132 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 16 kB
Pss: 16 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 16 kB
Referenced: 16 kB
Anonymous: 16 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
THPeligible: 0
VmFlags: rd wr mr mw me gd ac
7ffd5e100000-7ffd5e103000 r--p 00000000 00:00 0 [vvar]
Size: 12 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 0 kB
Pss: 0 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 0 kB
Anonymous: 0 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
THPeligible: 0
VmFlags: rd mr pf io de dd sd
7ffd5e103000-7ffd5e105000 r-xp 00000000 00:00 0 [vdso]
Size: 8 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 4 kB
Pss: 0 kB
Shared_Clean: 4 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 4 kB
Anonymous: 0 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
THPeligible: 0
VmFlags: rd ex mr mw me de sd
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
Size: 4 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 0 kB
Pss: 0 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 0 kB
Anonymous: 0 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
THPeligible: 0
VmFlags: ex 堆里面匿名页面分配了108个物理内存但我们的测试程序只分配了100k物理内存这里匿名页面比分配的要大这是因为进程在装载的时候也要消耗一些匿名页面。
010cc000-010ef000 rw-p 00000000 00:00 0 [heap]
Size: 140 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Rss: 108 kB
Pss: 108 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 108 kB
Referenced: 108 kB
Anonymous: 108 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
FilePmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
Locked: 0 kB
THPeligible: 0
VmFlags: rd wr mr mw me ac sd 根据以上信息可以绘制出测试程序内存的布局图。 测试程序进程的elf这里只列出了常用的段。代码段的VMA属于page cache映射这里把init段text段rodata段分为一个族因为他们具有相同的权限在进程加载的时候会映射到代码段的VMA中。
数据段的VMA属于匿名映射bssdata段具有相同的权限在OS加载时会映射到数据段的VMA中。
从数据段开始的地方就属于堆空间我们在程序中用malloc分配了100K空间这100K大小也是在堆空间有对应的位置存在。
另外就是栈的VMA进程有属于自己的VMA的栈。
以上就介绍了进程的ELF如何和进程的地址空间映射起来的。
64位系统的布局图
64位系统可以访问的空间就变得很大了。不过是ARM还是X86实际的物理地址都不会用到64根地址线通常是使用了48根地址线。而且划分的用户空间和内核空间都是非常大的。 大家可以看这张图把空间分为了三部分一部分是内核空间一部分是非规范区域大家都不使用的最后是用户空间。 用户空间0x0000_0000_0000_0000到0x0000_ffff_ffff_ffff一共有256TB。 非规范区域 内核空间0xffff_0000_0000_0000到0xffff_ffff_ffff_ffff。一共有256TB。
内核空间又做了如下细分 vmalloc区域vmalloc函数使用的虚拟地址空间kernel image也在vmalloc区域内核镜像的起始地址 KIMAGE_ADDR TEXT_OFFSET TEXT_OFFSET是内存中的内核镜像相对内存起始位置的偏移。 vmemmap区域内存的物理地址如果不连续的话就会存在内存空洞稀疏内存vmemmap就用来存放稀疏内存的page结构体的数据的虚拟地址空间。 PCI I/O区域pci设备的I/O地址空间 Modules区域内核模块使用的虚拟地址空间 normal memory线性映射区范围是【0xffff_8000_0000_0000, 0xffff_ffff_ffff_ffff】, 一共有128TB, 但这里代码对应的是memblock_start_of_DRAM()和memblock_end_of_DRAM()函数。 memory根据实际物理内存大小做了限制所以memroy显示了实际能够访问的内存区。 MLM(__phys_to_virt(memblock_start_of_DRAM()), (unsigned long)high_memory))
high_memory __va(memblock_end_of_DRAM() - 1) 1;最终是通过dts或acpi中配置的memory节点确定的。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/919801.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!