linux内核分析笔记----内存管理

Linux内核源代码情景分析笔记 Linux内核源代码情景分析笔记好吧,首先我承认我要是读者的话,这篇文章我看着也头疼,因为写的太长太泛(其主要部分集中在内存管理,进程管理,文件系统)!原本是想按自己理解的精简精简的,按照操作系统中两个核心的抽象概念“进程”和“文件”开始介绍的,可以说操作系统引入这两个概念是系统的核心,其中进程的管理可以说是对内存和cpu的抽象管理,当然基础内存管理是必须的。而文件可以说是对设备的一层抽象(不仅仅是 阅读详情

      内存管理,不用多说,言简意赅。在内核里分配内存还真不是件容易的事情,根本上是因为内核不能想用户空间那样奢侈的使用内存。

      先来说说内存管理。内核把物理页作为内存管理的基本单位。尽管处理器的最小可寻址单位通常是字,但是,内存管理单元MMU通常以页为单位进行处理。因此,从虚拟内存的交代来看,页就是最小单位。内核用struct  page(linux/mm.h)结构表示系统中的每个物理页:

struct page {
         unsigned long flags;                                                      
         atomic_t count;                
         unsigned int mapcount;          
         unsigned long private;          
         struct address_space *mapping;  
         pgoff_t index;                  
         struct list_head lru;  
	 union{
	 	struct pte_chain;
		pte_addr_t;
	 }         
         void *virtual;                  
};

      flag用来存放页的状态,每一位代表一种状态,所以至少可以同时表示出32中不同的状态,这些状态定义在linux/page-flags.h中。count记录了该页被引用了多少次。mapping指向与该页相关的address_space对象。virtual是页的虚拟地址,它就是页在虚拟内存中的地址。要理解的一点是page结构与物理页相关,而并非与虚拟页相关。因此,该结构对页的描述是短暂的。内核仅仅用这个结构来描述当前时刻在相关的物理页中存放的东西。这种数据结构的目的在于描述物理内存本身,而不是描述包含在其中的数据。

      在linux中,内核也不是对所有的也都一视同仁,内核而是把页分为不同的区,使用区来对具有相似特性的页进行分组。Linux必须处理如下两种硬件存在缺陷而引起的内存寻址问题:

1.一些硬件只能用某些特定的内存地址来执行DMA
2.一些体系结构其内存的物理寻址范围比虚拟寻址范围大的多。这样,就有一些内存不能永久地映射在内核空间上。
为了解决这些制约条件,Linux使用了三种区:
1.ZONE_DMA:这个区包含的页用来执行DMA操作。
2.ZONE_NOMAL:这个区包含的都是能正常映射的页。
3.ZONE_HIGHEM:这个区包"高端内存",其中的页能不永久地映射到内核地址空间。

      区的实际使用与体系结构是相关的。linux 把系统的页划分区,形成不同的内存池,这样就可以根据用途进行分配了。需要说明的是,区的划分没有任何物理意义,只不过是内核为了管理页而采取的一种逻辑上的分组。尽管某些分配可能需要从特定的区中获得页,但这并不是说,某种用途的内存一定要从对应的区来获取,如果这种可供分配的资源不够用了,内核就会占用其他可用去的内存。下表给出每个区及其在X86上所占的列表:

     image

      每个区都用定义在linux/mmzone.h中的struct zone表示,如下:

struct zone {
         spinlock_t              lock;
         unsigned long           free_pages;
         unsigned long           pages_min, pages_low, pages_high;
         unsigned long           protection[MAX_NR_ZONES];
         spinlock_t              lru_lock;       
         struct list_head        active_list;
         struct list_head        inactive_list;
         unsigned long           nr_scan_active;
         unsigned long           nr_scan_inactive;
         unsigned long           nr_active;
         unsigned long           nr_inactive;
         int                     all_unreclaimable; 
         unsigned long           pages_scanned;    
         struct free_area        free_area[MAX_ORDER];
         wait_queue_head_t       * wait_table;
         unsigned long           wait_table_size;
         unsigned long           wait_table_bits;
         struct per_cpu_pageset  pageset[NR_CPUS];
         struct pglist_data      *zone_pgdat;
         struct page             *zone_mem_map;
         unsigned long           zone_start_pfn;

         char                    *name;
         unsigned long           spanned_pages;  
         unsigned long           present_pages;  
};

      其中的lock域是一个自旋锁,这个域只保护结构,而不是保护驻留在这个区中的所有页。没有特定的锁来保护单个页。free_pages域是这个区中空闲页的个数。内核尽可能的保护有pages_min个空闲页可用。name域是一个以NULL结束的字符串,表示这个区的名字。内核启动期间初始化这个值,其代码位于mm/page_alloc.h中,三个区的名字分别是"DMA","Normal","HighMem"。

内核提供了一种请求内层的底层机制,并提供了对它进行访问的几个接口。所有这些接口都是以页为单位进行操作的。下表给出所有底层的页分配方法:

     image

      当你不再需要页时可以用下列函数释放它们,只是提醒:仅能释放属于你的页,否则可能导致系统崩溃。内核是完全信任自己的,如果有非法操作,内核会开心的把自己挂起来,停止运行。列表如下:

      image

      上面提到都是以页为单位的分配方式,那么对于常用的以字节为单位的分配来说,内核通供的函数是kmalloc(),和mallloc很像吧,其实还真是这样,只不过多了一个flags参数。用它可以获得以字节为单位的一块内核内存。如果需要的是页----尤其是在你的需求总量接近2的幂次方的时候----那么,前面讨论的页分配接口可能是更好的选择。

      接下来,注意的话,可能会发现无论是页分配接口还是kmalloc都有一个分配器标志(如GFP_KERNEL这样的)。这些标志可分为三类:行为修饰符,区修饰符及类型.下面就来讨论个问题.

      1.行为修饰符(linux/gfp.h):表示内核应当如何分配所需的内存。在某些特定的情况下,只能使用某些特定的方法分配内存。可以同时使用这些标志,用|链接。列表如下:

       image

      2.区分配符:它只关心去应当从何处分配。通常,分配可以从任何区开始。不过,内核优先从ZONE_NORMAL开始,这样可以确保其他区在需要时有足够的空闲页可以使用。区修饰符如下:

       image

       不能给_get_free_pages()指定ZONE_HIGHMEM,因为这个函数返回都是逻辑地址,而不是page结构。这两个函数分配的内存当前可能有可能还没有映射到内核的虚拟地址空间,因此,也可能根本就没有逻辑地址。只有alloc_pages()才能分配高端内存。实际上,大多数ZONE_NORMAL就已经足够了。

      3.类型标志:指定所需的行为和区描述符以完成特殊类型的处理。正因为这点,内核代码趋向于使用正确的类型标志,而不是一味地指定它可能需要用到的多个描述符。下面两个表分别给出了类型标志的列表和每个类型标志与哪些修饰符相关联:

      image                image

      上表中,左边是类型标志,右边是每种类型标志后隐含的修饰符列表。在编写的大多数代码中,用到的要么是GFP_KERNEL,要么是GFP_ATOMIC。下表是通常情形和所用标志的列表,不管使用那种分配类型,你都必须进行检查,并对错误进行处理:

     image

      有了kmalloc,当然就有kfree()(linux/slab.h),释放由kmalloc()分配出来的内存块。如果想要释放的内存不是由kmalloc()分配的,或者想要释放的内存早就被释放了,在这种情况下调用这个函数会导致严重的后果。特别说明kfree(NULL)是安全的。

      vmalloc()和kmalloc是一样的作用,不同在于前者分配的内存虚拟地址是连续的,而物理地址则无需连续。这也是用户空间分配函数的工作方式,如malloc().kmalloc()可以保证在物理地址上都是连续的(当然,虚拟地址当然也是连续的)。vmalloc()函数只确保页在虚拟机地址空间内是连续的。它通过分配非联系的物理内存块,再“修正”页表,把内存映射到逻辑地址空间的连续区域中,就能做到这点。但很显然这样会降低处理性能,因为内核不得不做“拼接”的工作。所以这也是为什么不得已才使用vmalloc()的原因(比如获得大内存时)。大多数情况下,只有硬件设备需要得到物理地址连续的内存。硬件设备存在于内存管理单元以外,它根本不懂什么是虚拟地址。因此,硬件设备用到的任何内存区都必须是物理上连续的块,而不仅仅是虚地址连续的块。最后需要说明的是,vmalloc()可能睡眠,不能从中断上下文中进行调用,也不能从其他不允许阻塞的情况下进行调用。释放时必须使用vfree().

      分配和释放数据结构是所有内核中最普遍的操作之一。为了便于数据的频繁分配和回收,常常会用到一个空间链表。它就相当于对象高速缓存以便快速存储频繁使用的对象类型。在内核中,空闲链表面临的主要问题之一是不能全局控制。当可用内存变得紧张的时候,内核无法通知每个空闲链表,让其收缩缓存的大小以便释放一些内存来。实际上,内核根本不知道有这样的空闲离岸边。为了弥补这一缺陷,也为了是代码更加稳固,linux内核提供了slab层(也就是所谓的slab分类器),slab分类器扮演了通用数据结构缓存层的角色。slab分配器试图在如下几个原则中寻求一种平衡:

1.频繁使用的数据结构也会频繁分配和释放,因此应当缓存它们。
2.频繁分配和回收必然会导致内存碎片。为了避免这种情况,空闲链表的缓存会连续地存放。因为已释放的数据结构又会放回空闲链表,不会导致碎片。
3.回收的对象可以立即投入下一次分配,因此,对于频繁的分配和释放,空闲链表能够提高其性能。
4.如果让部分缓存专属于单个处理器,那么,分配和释放就可以在不加SMP锁的情况下进行。
5.对存放的对象进行着色,以防止多个对象映射到相同的高速缓存行。

      slab层把不同的对象划分为所谓的高速缓存组,其中每个高速缓存都存放不同类型的对象,每种对象类型对应一个高速缓存。kmalloc()接口建立在slab层上,使用了一组通用高速缓存。这些缓存又被分为slabs,slab由一个或多个物理上连续的页组成,一般情况下,slab也就仅仅由一页组成。每个高速缓存可以由多个slab组成。每个slab都包含一些对象成员,这里的对象指的是被缓存的数据结构,每个slab处于三种状态之一:满,部分满,空。当内核的某一部分需要一个新的对象时,先从部分满的slab中进行分配。如果没有部分满的slab,就从空的slab中进行分配。如果没有空的slab,就要创建一个slab了。下图给出高速缓存,slab及对象之间的关系:

      image

      上图中的每个cache由kmem_cache_s结构表示,这个结构包含三个链表slabs_full,slab_partial和slabs_empty,均存放在kmem_list3结构内,这些链表包含高速缓存中的所有slab,slab描述符struct slab:

struct slab {
        struct list_head  list;       /*满,部分满或空链表*/
        unsigned long     colouroff;  /*slab着色的偏移量*/
        void              *s_mem;     /*在slab中的第一个对象*/
        unsigned int      inuse;      /*已分配的对象数*/
        kmem_bufctl_t     free;       /*第一个空闲对象*/
};

      slab描述符要么在slab之外另行分配,要么就在slab自身最开始的地方。如果slab很小或者slab内核有足够的空间容纳slab描述符,那么描述符就存放在slab里面.slab分配器创建新的slab是通过__get_free_pages()低级内存分配器进行的:

static inline void * kmem_getpages(kmem_cache_t *cachep, unsigned long flags)
{
        void *addr;
        flags |= cachep->gfpflags;
        addr = (void*)__get_free_pages(flags, cachep->gfporder);
        return addr;
}

      上面的是一个描述原理的简化版。接着,调用kmem_freepages()释放内存,而对给定的高速缓存页,kmem_freepages()最终调用的是free_pages().当然,slab层的关键就是避免频繁分配和释放页。由此可知,slab页只有当给定的高速缓存中既没有部分满也没有空的slab时候才会调用页分配函数。而只有在下列情况下才会调用释放函数:当可用内存变得紧缺时,系统试图释放出更多内存以供使用,或者当高速缓存显式地被销毁时。slab层的管理是在每个高速缓存的基础上,通过提供个整个内核一个简单的接口来完成的。通过接口就可以创建和销毁新的高速缓存,并在高速缓存内分配和释放对象。高速缓存及slab的复杂管理完全通过slab层的内部机制来处理。当创建一个高速缓存后,slab层所起的作用就像一个专用的分配器,可以为具体的对象类型进行分配。一个新的高速缓存是通过一下接口进行创建的:

kmem_cache_t * kmem_cache_create(const char *name, size_t size,size_t align, unsigned long flags,
                                 void (*ctor)(void*, kmem_cache_t *, unsigned long),
                                 void (*dtor)(void*, kmem_cache_t *, unsigned long));
      有关这个函数的说明,我就省略了,需要的网上一大堆。这个函数成功时会返回一个执行所创建高速缓存的指针,否则,返回空。这个函数由于会睡眠,因此不能在中断上下文中使用。要销毁一个高速缓存,调用:int kmem_cache_destroy(kmem_cache_t *cachep),同样,也是不能在中断上下文中使用。调用该函数之前必须确保存在以下两个条件:
1.高速缓存中的所有slab都必须为空。
2.在调用kmem_cache_destory()期间不再访问这个高速缓存,调用者必须确保这种同步。

      创建了高速缓存以后,就可以通过下列函数从中获取对象:void * kmem_cache_alloc(kmem_cache_t *cachep, int flags)。该函数从高速缓存cachep中返回一个指向对象的指针。如果高速缓存的所有slab中都没有空闲的对象,那么slab层必须通过kmem_getpages()获取新的页,flags的值传递给__get_free_pages().最后,释放一个对象,并把它返回给原来的slab,可以使用下面的函数:

void kmem_cache_free(kmem_cache_t *cachep,void *objp)

      这样就能把cachep中的对象objp标记为空闲了,关于slab分配器的使用实例,参考资料上有,我就不说了。相比较以前的用户空间栈而言,内核栈是非常小的。每个进程都有自己的内核栈进程在内核执行期间的整个调用链必须放在自己的内核栈上。中断处理程序也使用被它们打断的进程的堆栈。这就意味着,在最恶劣的情况下,8kB的内核栈可能会由多个函数的嵌套调用链和几个中断处理程序来共享。显然,深度的嵌套会导致溢出。

      根据定义,在高端内存中的页不能永久地映射到内核地址空间上。因此,通过alloc_pages()函数以__GFP_HIGHMEM标志获得的页不可能有逻辑地址。一旦这些页被分配,就必须映射到内核的逻辑地址空间上。要映射一个给定的page结构到内核地址空间,可以使用void *kmap(struct page *page) 这个函数在高端内存或低端内存上都能用。如果page结构对应的是低端内存中的一页,函数只会单纯地返回该页的虚拟地址,如果页位于高端内存,则会建立一个永久映射,在返回地址。这个函数可以睡眠,所以kmap()只能用在进程上下文中。当不再需要内存映射的时候,就用下列函数进行解除映射:

void kunmem(struct page* page)

      当必须创建一个映射而当前的上下文又不能睡眠时,内核提供了临时睡眠(也就是原子睡眠)。只要有一组保留的永久映射,它们就可以临时持有新创建的一个映射。内核可以原子地把高端内存中的一个页映射到某个保留的映射中。因此,临时映射可以用在不能睡眠的地方。建立临时映射:void *kmap_atomic(struct page *page,enum km_type type).参数type是下列枚举类型之一,描述了临时映射的目的,如下:

     image

      这个函数不会阻塞,它也禁止内核抢占,通过函数void *kunmap_atomic(void *kvaddr,enum km_type type).这个函数还是不会映射。

      最后,我们总结一下,说说分配函数的选择吧,总结如下:

1.如果需要连续的物理页,就可以使用某个低级页分配器或kmalloc().
2.如果想从高端内存进行分配,使用alloc_pages().
3.如果不需要物理上连续的页,而仅仅是虚拟地址上连续的页,那么就是用vmalloc
4.如果要创建和销毁很多大的数据结构,那么考虑建立slab高速缓存。
      好了,有关内存管理的也说完了,其实也不算我说,有很多都是参考书上资料的。
【随书光盘】Linux 0.01内核分析与操作系统设计随书光盘 Linux 0.01内核分析与操作系统设计随书光盘,注意是光盘,光盘内包含linux0.01源码和带注释版源码。 立即下载

相关推荐

【通信协议-RTCM】MSM语句(1) - 多信号GNSS观测数据消息格式

注释:RTCM响应消息1020为GLONASS星历信息,暂不介绍,前公司暂未研发RTCM消息类型版本的DR/RTK模块,DR/RTK模块仅NMEA消息类型使用注释:公司使用的多信号语句类型为MSM4&MSM7,也应该是运用最广泛的语句类型,例如本人之前在公司开发的工具全是基于MSM7语句类型来进行的。

qxj2422640226的博客 2092

LINUX内存管理

内存管理,不用多说,言简意赅。在内核里分配内存还真不是件容易的事情,根本上是因为内核不能想用户空间那样奢侈的使用内存。       先来说说内存管理。内核把物理页作为内存管理的基本单位。尽管处理器的最小可寻址单位通常是字,但是,内存管理单元MMU通常以页为单位进行处理。因此,从虚拟内存的交代来看,页就是最小单位。内核用struct  page(linux/mm.h)结构表示系统中的每个物理页:

Phoenix_FuliMa 1328

windows的rancherDesktop修改镜像源

Rancher Desktop中的“Allowed Images”功能(通常在 Preferences -> Container Engine -> Allowed Images 中找到)是用来定义一个允许拉取和推送的镜像列表的规则,例如,只允许从您组织或特定的受信任的仓库中获取镜像。如果问题依旧,请提供您Rancher Desktop的版本和当前选择的容器运行时,以便进一步协助。总结一下,对于Windows上的Rancher Desktop,如果您使用默认的。,镜像源的配置通常通过一个名为。

zwjapple的专栏 2697

[Linux][内核学习笔记]--内存管理

文章目录1.内存管理概览2.物理内存管理2.1 物理内存初始化流程2.2 zone2.3 zonelist2.4 fallbacks2.5 伙伴系统2.6 pg_data_t3. 虚拟空间管理3.1 进程虚拟地址空间3.2 虚拟地址空间布局3.2.1 内核空间3.2.2 用户空间3.2 描述用户空间的数据结构4. 内存管理机制4.1 地址映射(页表映射)4.1.1 页面高速缓存4.1.2 64位机器的页表映射5. 物理页面的分配5.1 gfp_mask标志5.2 常见的gfp_mask使用时机5.3 物理内

静待另一片蓝天 2015

全球AI算力最强公司分析报告

全球AI算力最强公司分析报告显示,Google凭借自研TPU技术和庞大数据中心网络位居榜首,拥有约100万至150万块等效H100 GPU算力。微软、Meta和亚马逊紧随其后,分别拥有75万、55万和25万块等效H100 GPU。中国企业中,百度、阿里巴巴和腾讯表现突出,华为在国产AI芯片领域领先。技术指标上,NVIDIA H100相比A100性能显著提升,但功耗也大幅增加。未来AI算力需求将持续激增,预计2028年全球市场将超2000亿美元。新兴挑战者如xAI可能改变竞争格局。

MyySophia的博客 5715

已过tiktok校招客户端,面经分享

面试的话, 一天面完3面, 效率很高, 三天之后就发了offer 字节邮件里面也说了不能泄露面试题, 那我就把我秋招参与美团,字节,腾讯,阿里面试被问到的全部问题总结着写出来了, 这其实是我每一轮面试完之后我都会总结哪里答对了, 哪里没有答对, 总结了一大堆问题出来. 答案未必正确, 我只是给自己写了个简单的一句话概括, 可能不够完善, 建议看官自行回答一下这些问题 二本非科班, 暑假在字节实习过, 不过不是tiktok部门, 因此秋招就没啥时间准备面试了, 只投了几个大厂, 顺便也在字节跨部门转正,

a1472750149的博客 1308

linux内核-内存管理

*分配一块给某个数据结构使用的缓存描述符name:对象的名字 size:对象的实际大小 align:对齐要求,通常填0,创建是自动选择。flags:可选标志位 ctor: 构造函数 */ struct kmem_cache * kmem_cache_create(const char * name , size_t size , size_t align , unsigned long flags, void(* ctor)(void *));

csdn546229768的博客 1598

altium room 布局_ALtium 16相同重复模块PCB布局,复制布局走线

自己做了实际工程以后发现PCB器件名字后缀太长了,所以文章最后写了一下后缀的调整方法。第一种方法:1、建立子原理图如下,文件名CANM 2、之后新建一个顶层文件,文件名TOP,之后design—create sheet symbol form sheet or hdl。选择CANM,并放置到TOP中,如下 3、由于我们要多次调用CANM所以使用repeat命令修改如下: 4、之后根据自己的定义,连...

weixin_39609573的博客 5751

说出来你可能不信,内核这家伙在内存的使用上给自己开了个小灶!

点击上方蓝字"开发内功修炼",关注并设为星标飞哥的硬核文章将第一时间送达~~~现在你可能还觉得node、zone、伙伴系统、slab这些东东还有那么一点点陌生。别怕,接下...

zhangyanfei01的专栏 327

28、时间敏感网络中可靠性感知的综合路由与调度

本文针对时间敏感网络(TSN)中现有路由与调度机制主要关注时间触发(TT)流量而忽略其他类型流量效用的问题,提出了一种可靠性感知的综合路由与调度机制。通过将具有不同可靠性和延迟要求的各类流量的联合路由与调度问题形式化为基于优化模理论(OMT)的混合整数规划问题,设计了完整的路由约束与调度约束,并分析了不同类型流量的传输效用,设定了优化目标以提升整体网络性能。实验结果表明,该机制在满足TT流量严格时延与可靠性要求的同时,显著提高了AVB和BE等非关键流量的传输效用,实现了多类型流量的高效协同传输。

hhh00的博客 95

ROS从入门到精通2-7:Gazebo仿真之动态生成障碍物

动态生成障碍物在机器人导航、碰撞避障算法测试、多机协同等领域应用广泛,可以帮助开发人员快速测试,本文介绍该技术并提供基于ROS Gazebo的实现

FRIGIDWINTER的博客 4899

08内存管理

1、页和区 (1)页 页是虚拟内存的最小单位。内核把物理页作为内存管理的基本单位。处理器的最小可寻址单位通常为字(甚至字节)。但是内存管理单元(将虚拟地址转换为物理地址的硬件)通常以页为单位进行处理。从虚拟内存角度来看,页就是最小单位。内核使用struct page结构(物理页结构)表示系统中的每个物理页: struct page{ /* 存放页的状态(是否为脏页)等 */ unsigned long flags; /* 页被引用的次数统计,为-1时表示内核中没有引用这一页

Revendell的博客 754

工业4.0必备:C#上位机+数字孪生 生产线实时监控与智能预警系统(工业级实战)

数据割裂:PLC、传感器、工业相机的数据散落在不同系统,想看全局生产状态要切换N个软件,“数据孤岛”导致决策滞后;故障难预判:设备突发故障时,只能停机排查,平均故障响应时间超30分钟,一条生产线停工1小时损失超10万;可视化差:传统监控只有冰冷的数字和2D图表,设备运行状态、生产流程、物料流转无法直观感知,新人上手需3个月才能熟悉产线。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 660

[转]linux内核分析笔记----内存管理

转自:http://blog.youkuaiyun.com/Baiduluckyboy/article/details/9667933 内存管理,不用多说,言简意赅。在内核里分配内存还真不是件容易的事情,根本上是因为内核不能想用户空间那样奢侈的使用内存。 先来说说内存管理。内核把物理页作为内存管理的基本单位。尽管处理器的最小可寻址单位通常是字,但是,内存管理单元MMU通常以页为单位进...

aodiyu3146的博客 117

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

linux内核框架分析,读书笔记——Linux内核源代码情景分析——2.1  内存管理的基本框架...

i386CPU中的页式内存管理的基本思路是:通过页面目录和页面表分两个层次实现从线性地址到物理地址的映射。Linux内核的映射机制设计成三层,在页面目录和页面表中间增设了一层“中间目录”。在代码中,页面目录称为PGD,中间目录称为PMD,而页面表则称为PT。PT中的表项则称为PTE(PageTable Entry)。对于CPU发出的线性地址,虚拟的Linux内存管理单元分如下四步完成从线性地址到物...

weixin_34980267的博客 227

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Linux内存管理的基本框架(Linux内核源代码情景分析读书笔记连载)

1 Linux内核的映射机制设计成三层,在页面目录和页面表中间增设了一层“中间目录”。页面目录称为PGD,中间目录称为PMD,页面目录称为PT,PT中的表项称为PTE。PGD、PMD、PT三者均为数组。相应的,在逻辑上把线性地址从高位到低位划分成4个位段,各占若干位,分别用作在目录PGD中的下标、中间目录PMD中的下标、页面表PT中的下标以及物理页面内的偏移。 对于CPU发出的线性地址,虚拟的L

无论岁月怎样流逝,都改变不了人们对真、善、美的追求…… 806

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Linux内核学习

参考: https://www.cnblogs.com/xuxinkun/p/5541894.html https://www.cnblogs.com/zhengchunyuan/p/9639245.html https://github.com/plantegg/programmer_case 学习笔记 性能优化 Linux内核性能剖析的方法学和主要工具 极客时间Linux性能优化...

pengdonglin137的专栏 99

《深入分析Linux内核源代码》读书、私藏笔记大放送

秉承着"不懂操作系统原理的程序员不是合格的程序员"的至理名言,鄙人又是买陈莉君老师的“Linux教学视频”,又是研读其力作《深入分析Linux内核源代码》,先将总结笔记放送给大家,希望对大家研习Linux源码提供更多的帮助,分章总结,从硬件起源开始->CPU中断->进程调度->内存管理->进程通信->文件系统->Socket网络通信,以源码结合注释的方式,对《深...

weixin_30393907的博客 211

Linux内核学习计划

前一阵儿开始学习Linux内核,开始之后逐渐发现这是一个庞大的计划,需要极大恒心。因此开通这个博客,记录学习笔记,督促自己坚持下去。学习资料主要来源于两本书:《深入理解Linux内核》、《Linux内核源代码情景分析》,以第一本为主。还参考了一些其他资料,在具体遇到时再一一标注。

li_boxue的博客 878

Linux内核分析期中总结

Linux内核分析期中总结 每周读书笔记链接汇总 第三周 http://www.cnblogs.com/lxq20135309/p/5284952.html 第四周 http://www.cnblogs.com/lxq20135309/p/5296846.html 第五周 http://www.cnblogs.com/lxq20135309/p/5335502.html 第六周 http://ww...

weixin_30758821的博客 83

内存管理(Linux内核源码分析)

背景本篇博客试图通过linux内核源码分析linux的内存管理机制,并且对比内核提供的几个分配内存的接口函数。然后聊下slab层的用法以及接口函数。内核分配内存与用户态分配内存内核分配内存与用户态分配内存显然是不同的,内核不可以像用户态那样奢侈的使用内存,内核使用内存一定是谨小慎微的。并且,在用户态如果出现内存溢出因为有内存保护机制,可能只是一个报错或警告,而在内核态若出现内存溢出后果就会严重的多(

hty46565的博客 1万+

什么是Linux内核,如何搞懂Linux内核?(Linux内核学习笔记合集来了!)

操作系统(简称为OS)是一中软件平台,可创建一个环境,用户可以再该环境中再计算设备上运行不同的应用程序。它被移动设备,标签,台式机,web服务器,视频游戏机等不同的设备所利用。如果你有这些技能,你可以试试给暴雪发简历,给他们写服务器后台,以为全世界的魔兽都运行在你的服务器软件上。当然,一般的网络公司,哪怕是百度级别的,都应该毫不犹豫的录用你。每当将操作系统加载到内存中时,首先,将加载内核并将其保留在那里,直到操作系统关闭。内核负责处理低级任务,例如任务管理,内存管理,风险管理等。内核是操作系统的关键组件。

weixin_44909451的博客 5880

linux内核源码分析笔记

一、内核源码目录结构 1、Linux 内核源代码包括三个主要部分 1)内核核心代码:包括linux内核整体架构分析笔记描述的各子系统和子模块,以及其他支撑子系统,如:电源管理、linux初始化等。 2)非核心代码:例如库文件(因为 Linux 内核是一个自包含的内核,即内核不依赖其它的任何软件,自己就可以编译通过)、固件集合、 KVM(虚拟机技术)等。 3)编译脚本、配置文件、帮助文档、版权说明等辅助性文件。 2、内核源代码顶层目录结构: include/ :内核头文件,需要提供给外部模块(例..

locahuang的博客 6533

《Linux内核精通》笔记

了解Linux内核由哪些组成?须知Linux内核源码(下载的链接👆👆👆)组织结构?重点需要学习地知识点有哪些?Linux内核架构和工作原理Linux内核Makefile系统文件详解计算机Intel CPU体系结构分析QEMU调试Linux内核环境搭建Linux Kernel内核整体架构(图文详解)Linux内核看socket底层的本质(IO)Linux用户空间与内核空间通信(Netlink通信机制)最后依据我为大家提供的的学习资料,开启我们的Linux学习之旅。

qq_34738754的博客 894
上一篇: linux内核分析笔记----定时器和时间管理
下一篇: linux内核分析笔记----虚拟文件系统(上)
wustdatamining
博客等级 码龄15年 12粉丝 81原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值