百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

30分钟搞懂Linux内核内存映射,值得大神们收藏

wptr33 2025-01-23 21:51 22 浏览

一、内存映射基础知识

1、内核地址映射模型

比如:X86CPU采用段页式地址映射模型,进程代码地址为逻辑地址,经过段页式地址映射之后,才能够真正访问物理内存。32位Linux内核地址空间划分:0GB--3GB为用户空间,3GB--4GB为内核空间。32位和64位内核地址空间划分是不同的。具体空间表示如下:

2、内核高端内存

比如:当内核模块代码或络访问内存时,代码中的地址为逻辑地址,而且对应到真正的物理内存地址,需要地址和它一对一的映射,假设:逻辑地址0xc0000003对应的物理地址为0x3。内核逻辑地址空间访问为0xc0000000--0xFFFFFFFF,那么对应的物理内存范围为0x0--0x40000000。即只能访问1GB物理内存。假设我们的电脑8GB物理内存,那么内核就只能访问前面1GB物理内存,剩下7GB物理内存它无法访问,因为内核的地址空间已经全部映射到物理内存地址范围0x--0x40000000。

Linux将内核地址空间划分为三部分:
ZONE_DMA/ZONE_NORMAL/ZONE_HIGHMEM。高端内存HIGH_MEM地址空间范围为0xF8000000--0xFFFFFFFF(896MB-1024MB)。针对高端内存的最基本思想:借一段地址空间,建立临时地址映射,用完后释放,达到此段地址空间可以循环使用,访问所有物理内存。

3、内存映射

内存映射是在进程的虚拟地址空间中创建一个映射,可分为两种:

A、文件映射(文件支持的内存映射,把文件的一个区间映射到进程的虚拟地址空间,数据源是存储设备上文件);

B、匿名映射(没有文件支持的内存映射,把物理内存映射到进程的虚拟地址空间,没有数据源)。通常把文件映射的物理页称为文件页,把匿名映射的物理页称为匿名页。

4、根据修改是否对其他进程可见和是否传递到底层文件,内存映射分为共享映射和私有映射。

A、共享映射:修改数据时映射相同区域的其他进程可以看见,如果是文件支持的映射,修改会传递到底层文件。

B、私有映射:第一次修改数据时会从数据源复制一个副本,然后修改副本,其他进程看不见,不影响我们的数据源。

两个进程可以使用共享的文件映射实现共享内存。匿名映射通常为私有映射,共享的匿名映射只可能出现在父进程和子进程之间。在进程的虚拟地址空间中,代码段和数据段是私有的文件映射,未初始化数据段、堆栈是私有的匿名映射。

5、内存映射原理机制:

1、创建内存映射的时,在进程的用户虚拟地址空间中分配一个虚拟内存区域(vm_area_struct);

2、Linux内核采用延迟分配物理内存的策略,在进程第一次访问虚拟页的时候,产生缺页异常,如果是文件映射,那么分配物理页,把文件指定区间的数据读到物理页中,然后在页表中把虚拟页映射到物理页;如果你是匿名映射,那么分配物理页,然后在页表中把虚拟页映射到物理页。

二、应用层API系统调用

Linux内核当中内存管理子系统提供给我们用户层的系统调用API函数,具体如下:

头文件:#include 1、用来创建内存映射

void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);

2、用来删除内存映射

int munmap(void *addr, size_t length);

3、专用用来扩大或缩小已经存在的内存映射,可能同时移动

#define _GNU_SOURCE /* See feature_test_macros(7) */ #include void *mremap(void *old_address, size_t old_size, size_t new_size, int flags, ... /* void *new_address */);

4、用来设置堆的上界

#include

int brk(void *addr);

5、用来创建非线性的文件映射,即文件区域和虚拟地址空间之间的映射不是线性关系,现在已不用

#define _GNU_SOURCE /* See feature_test_macros(7) */ #include

int remap_file_pages(void *addr, size_t size, int prot, size_t pgoff, int flags);

6、用来设置虚拟内存区域的访问权限

#include

int mprotect(void *addr, size_t len, int prot);

在Linux空间中可以使用如下函数:

1、把内存的物理页映射到进程的虚拟地址空间,这个函数用处是:实现进程和内核共享内存。

int remap_pfn_range (struct vm_area_struct *vma,unsigned long addr,unsigned long pfn,unsigned long size,pgprot_t prot);

2、把外设寄存器的物理地址映射到进程的虚拟地址空间,进程可能直接访问外设寄存器。

int io_remap_page_range(struct vm_area_struct *vma, unsigned long virt_addr,unsigned long phys_addr, unsigned long size,pgprot_t prot);

应用层当中应用程序通过使用C标准库提供的函数malloc()申请内存。glibc库的内存分配器ptmalloc使用brk或mmap向内核以页为单位申请虚拟内存,然后把页划分成小内存块分配给应用程序。默认的阈值为128KB,如果应用程序申请的内存长度小于阈值,ptmalloc分配器使用brk向内核申请虚拟内存,否则ptmalloc分配器使用mmap内内核申请虚拟内存。应用程序可以直接使用mmap向内核申请虚拟内存。

三、Linux内核常用数据结构

1、进程描述符

2、内存描述符

3、虚拟内存区域

4、mmap系统调用

a.进程创建匿名的内存映射,把内存的物理页映射到进程的虚拟地址空间;

b.进程把文件映射到进程的虚拟地址空间,可以像访问内存一样访问文件,不需要调用系统调用read()/write()访问文件,从面避免用户模式和内核模式之间的切换,提高读写文件的速度。

c.两个进程针对同一个文件创建共享的内存映射,实现共享会败在。

函数原型:

#include void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);

参数如下:

addr:起始虚拟地址,如果addr为0,内核选择虚拟地址。如果addr为非0,内核把这个参数作为提示,在附近选择虚拟地址。

length:映射的长度,单位是字节。

prot:保护位,具体参数如下:

PROT_EXEC:页可执行 PROT_READ:页可读 PROT_WRITE:页可写 PROT_NONE:面不可访问

flags:标志,具体参数如下:

MAP_SHARED:共享映射

MAP_PRIVATE:私有映射

MAP_ANONYMOUS:匿名映射

MAP_FIXED:固定映射

MAP_HUGETLB:使用巨型页

MAP_LOCKED:把页锁在内存中

fd:文件描述符

offset:偏移,单位是字节,必须是页长度的整数倍。

返回值:

返回起始虚拟地址,否则返回负的错误号。


四、创建/删除内存映射

1、创建内存映射

C标准库封装函数mmap()用来创建内存映射,内核提花POSIX标准定义的系统调用mmap,内核系统调用sys_mmap(),具体操作流程如下:

函数sys_mmap_pgoff执行流程视图如下:

a.如果是创建文件映射,根据文件描述符在进程的打开文件表中找到file实例;

b.如果是创建匿名巨型页映射,在hugetlbfs文件系统中创建文件“anon_hugepage",并且创建此文件 的一个打开实例file;

c.调用vm_mmap_pgoff进行处理。

相关推荐

为什么劝你不要买Switch OLED?(现在买switch oled划算吗)

那么在聊我们自己的观点前,还是先来看看这款任天堂SwitchOLED款式究竟带来了哪些变化吧。SwitchOLED已经把它最大的特点之一写到了名字里——OLED。这款产品改动最大的地方,就是在维...

新游戏、怀旧机!没有Switch新机的任天堂还能俘虏玩家们的心吗?丨C位

6月16日凌晨,日本电子游戏巨头任天堂在E3游戏展会上举行了发布会。翘首以盼的SwitchPro并未亮相,截止发稿,任天堂股价跌2.44%。但玩家们最为期待的《塞尔达:荒野之息2》将于2022年推出...

腾讯引进Nintendo Switch (OLED版)开启预售 多重满足您的娱乐需求

1月4日,腾讯引进NintendoSwitch(OLED版)开启预售,并将于1月11日正式发售。NintendoSwitch(OLED版)是NintendoSwitch的全新款式,配置色彩艳丽的...

股东大会上任天堂考虑移植更多WiiU和GC游戏到Switch

任天堂股东大会上有任天堂的忠实小股东玩家提议想在Switch玩到WiiU以及GC的经典游戏,对于这个问题,官方给了正面的回应。官方表示目前皮克敏等部分游戏已经可以在switch上玩了,今后会认真考虑玩...

《野狗子》M站均分低至60分!IGN仅给5分、VGC感觉像是PS3游戏

外山圭一郎工作室首部作品《野狗子》全球媒体口碑已解禁,总体评价一般,目前M站均分已降低至60分,21条评价,好评5条,中评14条,差评2条。IGN为其打出5分评价。《野狗子》的特色在于一些有趣的附身交...

《EA SPORTS FC 25》加入任天堂游戏试玩会,Switch版可免费体验

近日,EASPORTS宣布其最新力作《EASPORTSFC25》的Switch版本已正式加入任天堂游戏试玩会。即日起至3月2日,所有NintendoSwitchOnline订阅用户均可限时...

Double Kill!马里奥乐园+Switch能解任天堂焦虑吗?丨C位

近日,“超级任天堂世界”主题乐园在大阪环球影城开园,“超级马里奥之父”宫本茂现身揭幕仪式。任天堂近来喜事连连,2020年财年前九个月实现营收838亿元,贡献最大的Switch销量远超索尼PS5与微...

迷你主机、Switch好搭子:16寸4K超亮QLED CFORCE便携屏值得入手吗

一、迷你主机、Switch好搭子...

怎样查看Switch的“主机序列号信息”

小时候看到游戏机就走不动,现在玩游戏越来越方便了,比如Switch.今天讲讲怎样查看Switch的“主机序列号信息”。第一步:点击【设置】...

Switch版《EA SPORTS FC 25》容量相比前作缩水

备受期待的Switch版足球游戏《EASPORTSFC25》即将发布,根据任天堂官方网站的游戏信息显示,与前作《EASPORTSFC24》相比,游戏容量有所下降。在任天堂官方网站可以查到,...

switch双系统升级注意点(switch双系统升级注意点是什么)

升级系统有风险,建议只有实在想玩的游戏玩不了的时候再升级。1、针对双系统进行,单系统不适用。2、国行系统同pj系统的升级是分开的,互不干涉。国行系统进入后直接升级即可。3、升级之前,建议先做好各类备份...

《鬼泣4:特别版》游戏评测:全家老小齐上阵

游戏名称:鬼泣4:特别版英文名称:DevilMayCry?4SpecialEdition游戏类型:动作游戏ACT制作公司:CAPCOMCo.,Ltd.发行公司:CAPCOMCo.,L...

最好不要在超过35°C的环境温度里玩你的掌机

随着进入“初伏”,天气越发酷热,今年全球高温尤为严重。Valve对此发布了一个安全警告,告诉玩家SteamDeck可以在哪些温度下安全运行。Valve指出,SteamDeck的最佳工作环...

任天堂回应股东玩家 考虑Switch回溯游玩WiiU以及GC游戏

今日有任天堂的忠实小股东玩家提议想在Switch玩到WiiU以及GC的经典游戏,官方回应称正在考虑中,敬请期待。·当然,Switch回溯游玩WiiU以及GC游戏的方式有任天堂的在线服务直接游玩官方优...

Switch 2神秘C键用途曝光!或能连接初代NS手柄

直到近日,游戏圈内的风云人物、知名爆料人extas1s站了出来,带来一则令人颇感意外的消息。extas1s爆料称,玩家有望借助这个神秘的C按钮,实现初代Switch与Switch2...