Linux驱动学习——内存管理

环境:Linux arch-dev 6.18.9-arch1-2 #1 SMP PREEMPT_DYNAMIC Mon, 09 Feb 2026 17:16:33 +0000 x86_64 GNU/Linux

获取系统的物理内存信息

Linux 内核对每个物理页面都采用struct page数据结构来描述,内核为每一个物理页面都分配了这样一个struct page数据结构,并且存储到一个全局的数组mem_map[]中。它们之间一一映射,数组的第i个元素指向页帧号为i的物理页面的struct page数据结构。 基于此,我们可以编写一个内核模块,通过遍历这个mem_map[]`数组来统计当前系统有多少个空闲页面、保留页面、swapcache页面、slab页面、脏页面、活跃页面、正在回写的页面等。

代码

mem_info.c

// mem_info.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/mm.h>

// 指定license版本
MODULE_LICENSE("GPL");
// 作者信息
MODULE_AUTHOR("Marvin");
// 模块描述
MODULE_DESCRIPTION("show memory info");
// 提供别名
MODULE_ALIAS("meminfo");

#define PRT(a, b)                                                              \
  pr_info("%-15s=%10d %10ld %8ld\n", a, b, (PAGE_SIZE * b) / 1024,             \
          (PAGE_SIZE * b) / 1024 / 1024)

//设置初始化入口函数
static int __init mem_info_init(void)
{
    struct folio *folio;
    int i;
    unsigned long pfn, valid = 0;
    int free = 0, locked = 0, reserved = 0, swapcache = 0, referenced = 0,
        slab = 0, private = 0, uptodate = 0, dirty = 0, active = 0,
        writeback = 0, mappedtodisk = 0;
    unsigned long num_physpages;
    num_physpages = get_num_physpages();

    for (i = 0; i< num_physpages; i++) {
      pfn = i + PREEMPT_OFFSET;
      // skip empty hole
      if (!pfn_valid(pfn)) {
        continue;
      }
      valid++;
      folio = pfn_folio(pfn);
      // page_count == 0 is a free page
      if (!folio_ref_count(folio)) {
        free ++;
        continue;
      }
      if (folio_zone(folio)) {
        locked++;
      }
      if (PageReserved(&folio->page)) {
        reserved++;
      }
      if (folio_test_swapbacked(folio)) {
        swapcache++;
      }
      if (folio_test_referenced(folio)) {
        referenced++;
      }
      if (PageSlab(&folio->page)) {
        slab++;
      }
      if (PagePrivate(&folio->page)) {
        private++;
      }
      if (PageUptodate(&folio->page)) {
        uptodate++;
      }
      if(PageDirty(&folio->page)) {
        dirty++;
      }
      if (folio_test_active(folio)) {
        active++;
      }
      if (PageWriteback(&folio->page)) {
        writeback++;
      }
      if (folio_test_mappedtodisk(folio)) {
        mappedtodisk++;
      }
    }

    pr_info("\nExamining %ld pages(num_phys_pages) = %ls MB\n", num_physpages,
            num_physpages * PAGE_SIZE / 1024 / 1024);
    pr_info("Pages with valid PFN's = %ld, = %ld MB\n", valid,
            valid * PAGE_SIZE / 1024 / 1024);
    pr_info("\n                      Pages       KB        MB\n\n");

    PRT("free", free);
    PRT("locked", locked);
    PRT("reserved", reserved);
    PRT("swapcache", swapcache);
    PRT("referenced", referenced);
    PRT("slab", slab);
    PRT("private", private);
    PRT("uptodate", uptodate);
    PRT("dirty", dirty);
    PRT("active", active);
    PRT("writeback", writeback);
    PRT("mappedtodisk", mappedtodisk);

    return 0;
}

//设置出口函数
static void __exit mem_info_exit(void)
{
    printk(KERN_DEBUG "goodbye!!!\n");
}

//将上述定义的init()和exit()函数定义为模块入口/出口函数
module_init(mem_info_init);
module_exit(mem_info_exit);

Makefile

ifneq ($(KERNELRELEASE),)
MODULE_NAME = showmeminfo
$(MODULE_NAME)-objs := mem_info.o
obj-m := $(MODULE_NAME).o
else
KERNEL_DIR = /lib/modules/`uname -r`/build
MODULEDIR := $(shell pwd)
 
.PHONY: modules
default: modules
 
modules:
	make -C $(KERNEL_DIR) M=$(MODULEDIR) modules
 
clean distclean:
	make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
	rm -f *.o *.mod.c .*.*.cmd *.ko
	rm -rf .tmp_versions
endif

测试

$ sudo insmod showmeminfo.ko

dmesg 输出

[31733.735244] showmeminfo: loading out-of-tree module taints kernel.
[31733.735249] showmeminfo: module verification failed: signature and/or required key missing - tainting kernel
[31733.745763] 
               Examining 1043558 pages(num_phys_pages) = (efault) MB
[31733.745767] Pages with valid PFN's = 524287, = 2047 MB
[31733.745767] 
                                     Pages       KB        MB

[31733.745768] free           =    119434     477736      466
[31733.745769] locked         =    404853    1619412     1581
[31733.745770] reserved       =     21587      86348       84
[31733.745771] swapcache      =    133955     535820      523
[31733.745772] referenced     =    209721     838884      819
[31733.745773] slab           =         0          0        0
[31733.745774] private        =     46758     187032      182
[31733.745774] uptodate       =    375524    1502096     1466
[31733.745775] dirty          =     35479     141916      138
[31733.745776] active         =         0          0        0
[31733.745776] writeback      =         0          0        0
[31733.745777] mappedtodisk   =    274058    1096232     1070

分配内存

在Linux内核中,可以通过alloc_page分配一个物理页面,然后输出该物理页面的物理地址,并输出该物理页面在内核空间的虚拟地址。
可以通过__get_free_pages来分配物理页面,也可以通过kmalloc直接分配物理内存。

代码

mem_alloc.c

// mem_alloc.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/vmalloc.h>

// 指定license版本
MODULE_LICENSE("GPL");
// 作者信息
MODULE_AUTHOR("Marvin");
// 模块描述
MODULE_DESCRIPTION("alloc memmory");
// 提供别名
MODULE_ALIAS("memalloc");

#define PRT(a, b)                                                              \
  pr_info("%-15s=%10d %10ld %8ld\n", a, b, (PAGE_SIZE * b) / 1024,             \
          (PAGE_SIZE * b) / 1024 / 1024)
#define MB (1024*1024)
static int mem = 64;
//设置初始化入口函数
static int __init mem_alloc_init(void)
{
    static char *kbuf, *vm_buff;
    static unsigned long order;
    int size;
    for (size = PAGE_SIZE, order = 0; order < NR_PAGE_ORDERS; order++, size *= 2) {
        pr_info(" order=%2ld, pages=%5ld, size=%8d ", order, size / PAGE_SIZE, size);
        kbuf = (char *)__get_free_pages(GFP_ATOMIC, order);
        if (!kbuf) {
          pr_err("__get_free_pages failed!");
          break;
        }
        pr_info("__get_free_pages OK");
        free_pages((unsigned long)kbuf, order);
    }

    for (size = PAGE_SIZE, order = 0; order < NR_PAGE_ORDERS; order++, size *= 2) {
      pr_info(" order=%2ld, pages=%5ld, size=%8d ", order, size / PAGE_SIZE, size);
        kbuf = kmalloc((size_t) size, GFP_ATOMIC);
        if (!kbuf) {
          pr_err("kmalloc failed!");
          break;
        }
        pr_info("kmalloc OK");
        kfree(kbuf);
    }

    for (size = 4 * MB; size <= mem * MB; size += 4 * MB) {
      pr_info(" pages=%6lu, size=%8lu ", size / PAGE_SIZE, size / MB);
      vm_buff = vmalloc(size);
      if (!vm_buff) {
        pr_err("... vmalloc failed\n");
        break;
      }
      pr_info("... vmalloc OK\n");
      vfree(vm_buff);
    }

    return 0;
}

//设置出口函数
static void __exit mem_alloc_exit(void)
{
    printk(KERN_DEBUG "goodbye!!!\n");
}

//将上述定义的init()和exit()函数定义为模块入口/出口函数
module_init(mem_alloc_init);
module_exit(mem_alloc_exit);

Makefile

ifneq ($(KERNELRELEASE),)
MODULE_NAME = memalloc
$(MODULE_NAME)-objs := mem_alloc.o
obj-m := $(MODULE_NAME).o
else
KERNEL_DIR = /lib/modules/`uname -r`/build
MODULEDIR := $(shell pwd)
 
.PHONY: modules
default: modules
 
modules:
	make -C $(KERNEL_DIR) M=$(MODULEDIR) modules
 
clean distclean:
	make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
	rm -f *.o *.mod.c .*.*.cmd *.ko
	rm -rf .tmp_versions
endif

测试

$ sudo insmod memalloc.ko

dmesg输出:

[ 5111.502527]  order= 0, pages=    1, size=    4096 
[ 5111.502531] __get_free_pages OK
[ 5111.502531]  order= 1, pages=    2, size=    8192 
[ 5111.502533] __get_free_pages OK
[ 5111.502534]  order= 2, pages=    4, size=   16384 
[ 5111.502537] __get_free_pages OK
[ 5111.502537]  order= 3, pages=    8, size=   32768 
[ 5111.502540] __get_free_pages OK
[ 5111.502540]  order= 4, pages=   16, size=   65536 
[ 5111.502544] __get_free_pages OK
[ 5111.502545]  order= 5, pages=   32, size=  131072 
[ 5111.502570] __get_free_pages OK
[ 5111.502571]  order= 6, pages=   64, size=  262144 
[ 5111.502583] __get_free_pages OK
[ 5111.502584]  order= 7, pages=  128, size=  524288 
[ 5111.502606] __get_free_pages OK
[ 5111.502607]  order= 8, pages=  256, size= 1048576 
[ 5111.502651] __get_free_pages OK
[ 5111.502652]  order= 9, pages=  512, size= 2097152 
[ 5111.502773] __get_free_pages OK
[ 5111.502782]  order=10, pages= 1024, size= 4194304 
[ 5111.502998] __get_free_pages OK
[ 5111.503002]  order= 0, pages=    1, size=    4096 
[ 5111.503004] kmalloc OK
[ 5111.503005]  order= 1, pages=    2, size=    8192 
[ 5111.503006] kmalloc OK
[ 5111.503006]  order= 2, pages=    4, size=   16384 
[ 5111.503008] kmalloc OK
[ 5111.503009]  order= 3, pages=    8, size=   32768 
[ 5111.503040] kmalloc OK
[ 5111.503041]  order= 4, pages=   16, size=   65536 
[ 5111.503048] kmalloc OK
[ 5111.503049]  order= 5, pages=   32, size=  131072 
[ 5111.503056] kmalloc OK
[ 5111.503057]  order= 6, pages=   64, size=  262144 
[ 5111.503078] kmalloc OK
[ 5111.503079]  order= 7, pages=  128, size=  524288 
[ 5111.503137] kmalloc OK
[ 5111.503138]  order= 8, pages=  256, size= 1048576 
[ 5111.503221] kmalloc OK
[ 5111.503225]  order= 9, pages=  512, size= 2097152 
[ 5111.503363] kmalloc OK
[ 5111.503365]  order=10, pages= 1024, size= 4194304 
[ 5111.503585] kmalloc OK
[ 5111.503588]  pages=  1024, size=       4 
[ 5111.503977] ... vmalloc OK
[ 5111.504094]  pages=  2048, size=       8 
[ 5111.504548] ... vmalloc OK
[ 5111.504946]  pages=  3072, size=      12 
[ 5111.505723] ... vmalloc OK
[ 5111.505995]  pages=  4096, size=      16 
[ 5111.506893] ... vmalloc OK
[ 5111.507246]  pages=  5120, size=      20 
[ 5111.508254] ... vmalloc OK
[ 5111.508652]  pages=  6144, size=      24 
[ 5111.509853] ... vmalloc OK
[ 5111.510383]  pages=  7168, size=      28 
[ 5111.511969] ... vmalloc OK
[ 5111.512642]  pages=  8192, size=      32 
[ 5111.514359] ... vmalloc OK
[ 5111.514982]  pages=  9216, size=      36 
[ 5111.517869] ... vmalloc OK
[ 5111.518718]  pages= 10240, size=      40 
[ 5111.521890] ... vmalloc OK
[ 5111.523108]  pages= 11264, size=      44 
[ 5111.528199] ... vmalloc OK
[ 5111.529169]  pages= 12288, size=      48 
[ 5111.533407] ... vmalloc OK
[ 5111.534582]  pages= 13312, size=      52 
[ 5111.539651] ... vmalloc OK
[ 5111.540847]  pages= 14336, size=      56 
[ 5111.544862] ... vmalloc OK
[ 5111.545983]  pages= 15360, size=      60 
[ 5111.551694] ... vmalloc OK
[ 5111.552957]  pages= 16384, size=      64 
[ 5111.558645] ... vmalloc OK
[ 5119.521126] goodbye!!!

slab 内存分配

mem_slab.c

// mem_slab.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/vmalloc.h>

// 指定license版本
MODULE_LICENSE("GPL");
// 作者信息
MODULE_AUTHOR("Marvin");
// 模块描述
MODULE_DESCRIPTION("memmory slab");
// 提供别名
MODULE_ALIAS("memslab");

#define PRT(a, b)                                                              \
  pr_info("%-15s=%10d %10ld %8ld\n", a, b, (PAGE_SIZE * b) / 1024,             \
          (PAGE_SIZE * b) / 1024 / 1024)

static char *kbuf;
static int size = 20;
static int align = 8;
static struct kmem_cache *my_cache;
//设置初始化入口函数
static int __init mem_slab_init(void)
{
    // 创建一个kmem_cache
    my_cache = kmem_cache_create("mycache", size, align, 0, NULL);
    if (!my_cache) {
      pr_err("kmem_cache_create failed!");
      return -ENOMEM;
    }
    pr_info("kmem_cache_create OK");

    // 分配一个缓存对象
    kbuf = kmem_cache_alloc(my_cache, GFP_ATOMIC);
    if (!kbuf) {
      pr_err("create a cache object failed!");
      (void)kmem_cache_destroy(my_cache);
      return -1;
    }
    pr_info("create a cache object OK");
    return 0;
}

//设置出口函数
static void __exit mem_slab_exit(void)
{
    kmem_cache_free(my_cache, kbuf);
    pr_info("destroyed memory cache object");
    (void)kmem_cache_destroy(my_cache);
    printk(KERN_DEBUG "goodbye!!!\n");
}

//将上述定义的init()和exit()函数定义为模块入口/出口函数
module_init(mem_slab_init);
module_exit(mem_slab_exit);

// sudo insmod memslab.ko

Makefile

ifneq ($(KERNELRELEASE),)
MODULE_NAME = memslab
$(MODULE_NAME)-objs := mem_slab.o
obj-m := $(MODULE_NAME).o
else
KERNEL_DIR = /lib/modules/`uname -r`/build
MODULEDIR := $(shell pwd)
 
.PHONY: modules
default: modules
 
modules:
	make -C $(KERNEL_DIR) M=$(MODULEDIR) modules
 
clean distclean:
	make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
	rm -f *.o *.mod.c .*.*.cmd *.ko
	rm -rf .tmp_versions
endif

测试

$ sudo insmod memslab.ko
$ sudo rmmod memslab.ko 

dmesg 信息

[ 5896.854844] kmem_cache_create OK
[ 5896.854851] create a cache object OK
[ 5904.684947] destroyed memory cache object
[ 5904.684950] goodbye!!!

VMA

编写一个内存模块,遍历一个用户进程中所有的VMA.

mem_vma.c

// mem_slab.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>

#include <linux/mm.h>
#include <linux/mm_types.h>

// 指定license版本
MODULE_LICENSE("GPL");
// 作者信息
MODULE_AUTHOR("Marvin");
// 模块描述
MODULE_DESCRIPTION("memmory vma");
// 提供别名
MODULE_ALIAS("memvma");

static int pid;
module_param(pid, int, S_IRUGO);

static void printit(struct task_struct *task) {
  int j = 0;
  unsigned long start, end, length;
  struct mm_struct *mm = task->mm;
  struct vm_area_struct *vma;
  VMA_ITERATOR(vmi, mm, 0); // 从地址0开始

  if (!mm)
    return;

  // 需要持有mm锁
  mmap_read_lock(mm);
  pr_info("vmas:          vma      start      end     length\n");
  // 使用VMA迭代器(Linux 6.x推荐方式)
  for_each_vma(vmi, vma) {
    // vma_iter_addr(vmi) 获取当前地址
    j++;
    start = vma->vm_start;
    end = vma->vm_end;
    length = end - start;
    pr_info("vma %d: %p 0x%08lx 0x%08lx 0x%08lx\n", j, vma, start, end, length);
    // printk("VMA at %px: 0x%lx - 0x%lx\n",
    //        vma, vma->vm_start, vma->vm_end);
  }

  mmap_read_unlock(mm);
}

// 设置初始化入口函数
static int __init mem_slab_init(void) {
  struct task_struct *task;
  if (pid == 0) {
    pr_info("pid is 0, use current process\n");
    task = current;
    pid = task->pid;
    pr_info("current process pid is %d\n", pid);
  } else {
    task = pid_task(find_vpid(pid), PIDTYPE_PID);
    if (task == NULL) {
      pr_info("cannot find task with pid %d\n", pid);
      return -ESRCH;
    }
    pr_info("find task with pid %d, command = %s\n", pid, task->comm);
  }
  printit(task);
  return 0;
}

// 设置出口函数
static void __exit mem_slab_exit(void) { pr_info("goodbye!!!\n"); }

// 将上述定义的init()和exit()函数定义为模块入口/出口函数
module_init(mem_slab_init);
module_exit(mem_slab_exit);

// sudo insmod memslab.ko

Makefile

ifneq ($(KERNELRELEASE),)
MODULE_NAME = memvma
$(MODULE_NAME)-objs := mem_vma.o
obj-m := $(MODULE_NAME).o
else
KERNEL_DIR = /lib/modules/`uname -r`/build
MODULEDIR := $(shell pwd)
 
.PHONY: modules
default: modules
 
modules:
	make -C $(KERNEL_DIR) M=$(MODULEDIR) modules
 
clean distclean:
	make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
	rm -f *.o *.mod.c .*.*.cmd *.ko
	rm -rf .tmp_versions
endif

测试

$ sudo insmod memvma.ko
$ sudo rmmod memvma.ko 

dmesg 信息

[ 1892.957910] pid is 0, use current process
[ 1892.957921] current process pid is 4538
[ 1892.957921] vmas:          vma      start      end     length
[ 1892.957922] vma 1: 00000000969d1748 0x56297e57e000 0x56297e581000 0x00003000
[ 1892.957924] vma 2: 000000003ac0dac5 0x56297e581000 0x56297e59c000 0x0001b000
[ 1892.957925] vma 3: 0000000098dc766f 0x56297e59c000 0x56297e5a4000 0x00008000
[ 1892.957926] vma 4: 000000001f6755c6 0x56297e5a4000 0x56297e5a6000 0x00002000
[ 1892.957926] vma 5: 000000006687b8c1 0x56297e5a6000 0x56297e5a7000 0x00001000
[ 1892.957927] vma 6: 0000000048871c79 0x562994cc3000 0x562994ce4000 0x00021000
[ 1892.957928] vma 7: 00000000cbbeb8ad 0x7fc88fbe2000 0x7fc88fc06000 0x00024000
[ 1892.957929] vma 8: 00000000329b2c33 0x7fc88fc06000 0x7fc88fd77000 0x00171000
[ 1892.957929] vma 9: 000000002c0e897d 0x7fc88fd77000 0x7fc88fdc5000 0x0004e000
[ 1892.957930] vma 10: 0000000033af3caf 0x7fc88fdc5000 0x7fc88fdc9000 0x00004000
[ 1892.957931] vma 11: 00000000df370602 0x7fc88fdc9000 0x7fc88fdcb000 0x00002000
[ 1892.957932] vma 12: 00000000d5b1e752 0x7fc88fdcb000 0x7fc88fdd3000 0x00008000
[ 1892.957933] vma 13: 000000006cb15d1f 0x7fc88fdd3000 0x7fc88fdd7000 0x00004000
[ 1892.957933] vma 14: 00000000f74787ba 0x7fc88fdd7000 0x7fc88fdfa000 0x00023000
[ 1892.957934] vma 15: 000000002c3c3958 0x7fc88fdfa000 0x7fc88fdfe000 0x00004000
[ 1892.957935] vma 16: 000000000ab00e5c 0x7fc88fdfe000 0x7fc88fdff000 0x00001000
[ 1892.957936] vma 17: 00000000d41c5c7f 0x7fc88fdff000 0x7fc88fe00000 0x00001000
[ 1892.957936] vma 18: 000000004eab2890 0x7fc88fe00000 0x7fc88fe52000 0x00052000
[ 1892.957937] vma 19: 000000003ece5d0f 0x7fc88fe52000 0x7fc8901de000 0x0038c000
[ 1892.957938] vma 20: 00000000ec38eb56 0x7fc8901de000 0x7fc8902f1000 0x00113000
[ 1892.957938] vma 21: 00000000ecec6c79 0x7fc8902f1000 0x7fc89036f000 0x0007e000
[ 1892.957939] vma 22: 00000000df9c77a9 0x7fc89036f000 0x7fc890372000 0x00003000
[ 1892.957940] vma 23: 0000000030ab3df1 0x7fc890372000 0x7fc890375000 0x00003000
[ 1892.957941] vma 24: 00000000c6ae42b7 0x7fc890377000 0x7fc89037c000 0x00005000
[ 1892.957941] vma 25: 000000003a32a804 0x7fc89037c000 0x7fc89037f000 0x00003000
[ 1892.957942] vma 26: 000000009cfcc92b 0x7fc89037f000 0x7fc89038f000 0x00010000
[ 1892.957943] vma 27: 000000003813c7a0 0x7fc89038f000 0x7fc890395000 0x00006000
[ 1892.957943] vma 28: 00000000228bdc99 0x7fc890395000 0x7fc890396000 0x00001000
[ 1892.957944] vma 29: 000000002bbf7407 0x7fc890396000 0x7fc890397000 0x00001000
[ 1892.957945] vma 30: 00000000b72e7ffe 0x7fc890397000 0x7fc89039b000 0x00004000
[ 1892.957946] vma 31: 00000000d084fab3 0x7fc89039b000 0x7fc8903bf000 0x00024000
[ 1892.957946] vma 32: 0000000060f1a54d 0x7fc8903bf000 0x7fc8903ca000 0x0000b000
[ 1892.957947] vma 33: 00000000827a2d87 0x7fc8903ca000 0x7fc8903cb000 0x00001000
[ 1892.957948] vma 34: 0000000098f924bf 0x7fc8903cb000 0x7fc8903cc000 0x00001000
[ 1892.957948] vma 35: 00000000a7e3d6e2 0x7fc8903cc000 0x7fc8903d8000 0x0000c000
[ 1892.957949] vma 36: 00000000fb3e0ce6 0x7fc8903d8000 0x7fc89049f000 0x000c7000
[ 1892.957950] vma 37: 00000000f174d217 0x7fc89049f000 0x7fc8904b0000 0x00011000
[ 1892.957951] vma 38: 00000000f6d3bcfb 0x7fc8904b0000 0x7fc8904b1000 0x00001000
[ 1892.957951] vma 39: 0000000062ec0d9d 0x7fc8904b1000 0x7fc8904b2000 0x00001000
[ 1892.957952] vma 40: 000000002529164a 0x7fc8904b2000 0x7fc8904b4000 0x00002000
[ 1892.957953] vma 41: 000000001a3d0012 0x7fc8904c4000 0x7fc8904c8000 0x00004000
[ 1892.957953] vma 42: 0000000043af3ebf 0x7fc8904c8000 0x7fc8904ca000 0x00002000
[ 1892.957954] vma 43: 00000000793b21f4 0x7fc8904ca000 0x7fc8904cc000 0x00002000
[ 1892.957955] vma 44: 000000007cd82d8c 0x7fc8904cc000 0x7fc8904cd000 0x00001000
[ 1892.957956] vma 45: 00000000e0951d2b 0x7fc8904cd000 0x7fc8904f7000 0x0002a000
[ 1892.957956] vma 46: 000000004b38866f 0x7fc8904f7000 0x7fc890502000 0x0000b000
[ 1892.957957] vma 47: 00000000fd5a9d96 0x7fc890502000 0x7fc890504000 0x00002000
[ 1892.957958] vma 48: 000000007236734e 0x7fc890504000 0x7fc890505000 0x00001000
[ 1892.957958] vma 49: 00000000d4317ef2 0x7fc890505000 0x7fc890506000 0x00001000
[ 1892.957959] vma 50: 000000000d369998 0x7ffedab77000 0x7ffedab98000 0x00021000
[ 1894.636183] goodbye!!!

注意

内存管理的内核接口从4.x到5.x再到6.x修改了很多,一些传统的API都已经被废弃了。

参考

posted @ 2026-02-09 23:59  main_c  阅读(1)  评论(0)    收藏  举报  来源