当前位置:首页>Linux>Linux早期内存memblock机制

Linux早期内存memblock机制

  • 2026-06-30 07:58:59
Linux早期内存memblock机制

一、介绍

Linux启动阶段在伙伴系统初始化之前,也有动态内存分配的需求,比如dts、sparse_vmemmap等,需要一种早期内存管理机制(early mem manger)。早期内存管理有两种内存管理策略:bootmem和memblock,bootmem是旧版本内核使用,4.x以后内核采用memblock,本文介绍memblock机制的实现。

二、内存分配策略

memblock内存分配采用first match算法,初始时整个DDR内存是一整个大块,随着内存分配被切成多个小块。内存分配方向可以是从高到低,也可以是从低到高,内存管理的区域是从linux代码段数据段结束位置到低端内存最高地址。

三、数据结构

内核版本: 4.19.114

在这里插入图片描述

3.1 全局context

struct memblock {bool bottom_up;  /* is bottom up direction? */phys_addr_t current_limit;struct memblock_type memory;struct memblock_type reserved;#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAPstruct memblock_type physmem;#endif};

bottom_up: 内存分配的方向:从高到低 or 从低到高。

current_limit:最大内存地址。

memblock_type: 内存区域的类型,有如下3种:

  • memory 可管理的总内存区域

  • reserve: 已分配的内存区域

  • physmem: 物理映射内存区域,固定映射的内存

3.2 memblock_type

struct memblock_type {    unsigned long cnt;    unsigned long max;    phys_addr_t total_size;    struct memblock_region *regions;    char *name;};
  • regions 内存块的描述,数组串起来。

  • cnt:当前内存块的个数

  • max: 最大内存块限制。

  • total_size: 内存区域的总大小。

3.3 memblock_region

描述内存块的地址范围。

struct memblock_region {phys_addr_t base;phys_addr_t size;enum memblock_flags flags;#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAPint nid;#endif};
  • base: 起始地址
  • size:大小
  • flags:分配的flag
  • nid: NUMA架构的nid信息。

memblock_flags的取值:

enum memblock_flags {    MEMBLOCK_NONE        = 0x0,    /* No special request */    MEMBLOCK_HOTPLUG    = 0x1,    /* hotpluggable region */    MEMBLOCK_MIRROR        = 0x2,    /* mirrored region */    MEMBLOCK_NOMAP        = 0x4,    /* don't add to kernel direct mapping */};

管理结构__initdata_memblock是全局静态数据,描述每个区域的最大长度等信息。

struct memblock memblock __initdata_memblock = {    .memory.regions        = memblock_memory_init_regions,    .memory.cnt        = 1,    /* empty dummy entry */    .memory.max        = INIT_MEMBLOCK_REGIONS,    .memory.name        = "memory",    .reserved.regions    = memblock_reserved_init_regions,    .reserved.cnt        = 1,    /* empty dummy entry */    .reserved.max        = INIT_MEMBLOCK_REGIONS,    .reserved.name        = "reserved",#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP    .physmem.regions    = memblock_physmem_init_regions,    .physmem.cnt        = 1,    /* empty dummy entry */    .physmem.max        = INIT_PHYSMEM_REGIONS,    .physmem.name        = "physmem",#endif    .bottom_up        = false,    .current_limit        = MEMBLOCK_ALLOC_ANYWHERE,};

regions的管理结构,也是提前预分配的静态数组,INIT_MEMBLOCK_REGIONS值为128,每个区域最大支持128个内存块(region)。

static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAPstatic struct memblock_region memblock_physmem_init_regions[INIT_PHYSMEM_REGIONS] __initdata_memblock;#endif

四、 API

  • memblock_add:将内存区域加入memblock可管理的内存区域,即memory的region队列。
int memblock_add(phys_addr_t base, phys_addr_t size);
  • memblock_remove:从可管理的内存区域中去掉一些内存。
int memblock_remove(phys_addr_t base, phys_addr_t size);
  • memblock_alloc:分配内存。
phys_addr_t memblock_alloc(phys_addr_t size, phys_addr_t align);
  • memblock_free:释放内存,释放时进行响铃内存块合并。
int memblock_free(phys_addr_t base, phys_addr_t size);
  • memblock_reserve:将内存区域加入reserved链表
int memblock_reserve(phys_addr_t base, phys_addr_t size);

4.1 初始化

memblock如何初始化可管理的内存区域?可以通过2种方式:

  • bootargs
  • dts

1、bootargs方式

通过linux的启动参数bootargs,传递内存大小,初始化memblock。

bootargs的格式

mem=size@start

bootargs的解析<arch\arm\kernel\setup.c>

early_mem-> arm_add_memory->memblock_add
static int __init early_mem(char *p){static int usermem __initdata = 0;    u64 size;    u64 start;char *endp;/*     * If the user specifies memory size, we     * blow away any automatically generated     * size.     */if (usermem == 0) {        usermem = 1;        memblock_remove(memblock_start_of_DRAM(),            memblock_end_of_DRAM() - memblock_start_of_DRAM());    }    start = PHYS_OFFSET;    size  = memparse(p, &endp);if (*endp == '@')        start = memparse(endp + 1NULL);    arm_add_memory(start, size);return 0;}early_param("mem", early_mem);

2、fdt方式

需要打开宏CONFIG_OF_EARLY_FLATTREE。

调用链:

early_init_dt_scan_memory->early_init_dt_add_memory_arch-> memblock_add

解析dts的memory节点,确认内存范围,。

  • reserved-memory

reserved的内存不加入到linux的内存管理空间,如下内存是reserved

1)内核代码段等各段段区域。

2)fdt区域。

3)firmware使用内存等。

dts中的“reserved-memory"节点的解析过程,代码在<driver\of>目录下

early_init_fdt_scan_reserved_mem->__fdt_scan_reserved_mem ->__reserved_mem_reserve_reg-> early_init_dt_reserve_memory_arch

此reserved-memory不会加入到memblock的reserved节点,而是直接就从memblock的可管理区域去掉了。

内核等代码段的reserved

setup_arch-> arm_memblock_init

void __init arm_memblock_init(const struct machine_desc *mdesc){/* Register the kernel text, kernel data and initrd with memblock. */    memblock_reserve(__pa(KERNEL_START), KERNEL_END - KERNEL_START);    arm_initrd_init();    arm_mm_memblock_reserve();/* reserve any platform specific memblock areas */if (mdesc->reserve)        mdesc->reserve();    early_init_fdt_reserve_self();    early_init_fdt_scan_reserved_mem();/* reserve memory for DMA contiguous allocations */    dma_contiguous_reserve(arm_dma_limit);    arm_memblock_steal_permitted = false;    memblock_dump_all();}

4.2 alloc

早期内存分配的API为early_alloc<arch\arm\mm\mmu.c>,其中会调用memblock_alloc进行内存分配。

early_alloc->early_alloc_aligned->memblock_alloc

调用链:

memblock_alloc->memblock_alloc_base->__memblock_alloc_base->memblock_alloc_base_nid->memblock_alloc_range_nid/*找到在memory中,但是不在reserved中的内存*/->memblock_find_in_range_node/*将内存区域加入到reserve链表*/->memblock_reserve
  • memblock_find_in_range_node: 用于查找可用内存。

遍历memblock的可用区域(即memory的region链表),具体区域是从kernel_end到current_limit (低端内存最高地址)。方向从高往低还是从低往高,由bottom_up决定。默认是从上往下分配的,bottom_up=false。

phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,phys_addr_t align, phys_addr_t start,phys_addr_t end, int nid,enum memblock_flags flags){phys_addr_t kernel_end, ret;/* pump up @end */if (end == MEMBLOCK_ALLOC_ACCESSIBLE)        end = memblock.current_limit;/* avoid allocating the first page */    start = max_t(phys_addr_t, start, PAGE_SIZE);    end = max(start, end);/*内核各段的结束地址*/    kernel_end = __pa_symbol(_end);/*     * try bottom-up allocation only when bottom-up mode     * is set and @end is above the kernel image.     */if (memblock_bottom_up() && end > kernel_end) {phys_addr_t bottom_up_start;/* make sure we will allocate above the kernel */        bottom_up_start = max(start, kernel_end);/* ok, try bottom-up allocation first */        ret = __memblock_find_range_bottom_up(bottom_up_start, end,                              size, align, nid, flags);if (ret)return ret;/*         * we always limit bottom-up allocation above the kernel,         * but top-down allocation doesn't have the limit, so         * retrying top-down allocation may succeed when bottom-up         * allocation failed.         *         * bottom-up allocation is expected to be fail very rarely,         * so we use WARN_ONCE() here to see the stack trace if         * fail happens.         */        WARN_ONCE(IS_ENABLED(CONFIG_MEMORY_HOTREMOVE),"memblock: bottom-up allocation failed, memory hotremove may be affected\n");    }return __memblock_find_range_top_down(start, end, size, align, nid,                          flags);}

current_limit默认为MEMBLOCK_ALLOC_ANYWHERE,即0xFFFFFFFF,在adjust_lowmem_bounds中设置最大限制,即低端内存。

void __init adjust_lowmem_bounds(void){phys_addr_t memblock_limit = 0;    u64 vmalloc_limit;struct memblock_region *reg;phys_addr_t lowmem_limit = 0;/*     * Let's use our own (unoptimized) equivalent of __pa() that is     * not affected by wrap-arounds when sizeof(phys_addr_t) == 4.     * The result is used as the upper bound on physical memory address     * and may itself be outside the valid range for which phys_addr_t     * and therefore __pa() is defined.     */    vmalloc_limit = (u64)(uintptr_t)vmalloc_min - PAGE_OFFSET + PHYS_OFFSET;/*     * The first usable region must be PMD aligned. Mark its start     * as MEMBLOCK_NOMAP if it isn't     */    for_each_memblock(memory, reg) {if (!memblock_is_nomap(reg)) {if (!IS_ALIGNED(reg->base, PMD_SIZE)) {phys_addr_t len;                len = round_up(reg->base, PMD_SIZE) - reg->base;                memblock_mark_nomap(reg->base, len);            }break;        }    }    for_each_memblock(memory, reg) {phys_addr_t block_start = reg->base;phys_addr_t block_end = reg->base + reg->size;if (memblock_is_nomap(reg))continue;if (reg->base < vmalloc_limit) {if (block_end > lowmem_limit)/*                 * Compare as u64 to ensure vmalloc_limit does                 * not get truncated. block_end should always                 * fit in phys_addr_t so there should be no                 * issue with assignment.                 */                lowmem_limit = min_t(u64,                             vmalloc_limit,                             block_end);/*             * Find the first non-pmd-aligned page, and point             * memblock_limit at it. This relies on rounding the             * limit down to be pmd-aligned, which happens at the             * end of this function.             *             * With this algorithm, the start or end of almost any             * bank can be non-pmd-aligned. The only exception is             * that the start of the bank 0 must be section-             * aligned, since otherwise memory would need to be             * allocated when mapping the start of bank 0, which             * occurs before any free memory is mapped.             */if (!memblock_limit) {if (!IS_ALIGNED(block_start, PMD_SIZE))                    memblock_limit = block_start;else if (!IS_ALIGNED(block_end, PMD_SIZE))                    memblock_limit = lowmem_limit;            }        }    }    arm_lowmem_limit = lowmem_limit;    high_memory = __va(arm_lowmem_limit - 1) + 1;if (!memblock_limit)        memblock_limit = arm_lowmem_limit;/*     * Round the memblock limit down to a pmd size.  This     * helps to ensure that we will allocate memory from the     * last full pmd, which should be mapped.     */    memblock_limit = round_down(memblock_limit, PMD_SIZE);if (!IS_ENABLED(CONFIG_HIGHMEM) || cache_is_vipt_aliasing()) {if (memblock_end_of_DRAM() > arm_lowmem_limit) {phys_addr_t end = memblock_end_of_DRAM();            pr_notice("Ignoring RAM at %pa-%pa\n",                  &memblock_limit, &end);            pr_notice("Consider using a HIGHMEM enabled kernel.\n");            memblock_remove(memblock_limit, end - memblock_limit);        }    }    memblock_set_current_limit(memblock_limit);}

以从小到大方向为例,看一下可用内存查找过程:

static phys_addr_t __init_memblock__memblock_find_range_bottom_up(phys_addr_t start, phys_addr_t end,phys_addr_t size, phys_addr_t align, int nid,enum memblock_flags flags){phys_addr_t this_start, this_end, cand;    u64 i;    for_each_free_mem_range(i, nid, flags, &this_start, &this_end, NULL) {        this_start = clamp(this_start, start, end);        this_end = clamp(this_end, start, end);        cand = round_up(this_start, align);if (cand < this_end && this_end - cand >= size)return cand;    }return 0;}

for_each_free_mem_range 是查找在memory中,但是没有在reserved中的内存,然后判断内存大小是否够用。

#define for_each_free_mem_range(i, nid, flags, p_start, p_end, p_nid)    \    for_each_mem_range(i, &memblock.memory, &memblock.reserved,    \               nid, flags, p_start, p_end, p_nid)

for_each_mem_range是遍历在type_a中,但是不在type_b中的内存。

/** * for_each_mem_range - iterate through memblock areas from type_a and not * included in type_b. Or just type_a if type_b is NULL. * @i: u64 used as loop variable * @type_a: ptr to memblock_type to iterate * @type_b: ptr to memblock_type which excludes from the iteration * @nid: node selector, %NUMA_NO_NODE for all nodes * @flags: pick from blocks based on memory attributes * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL * @p_nid: ptr to int for nid of the range, can be %NULL */#define for_each_mem_range(i, type_a, type_b, nid, flags,        \               p_start, p_end, p_nid)            \    for (i = 0, __next_mem_range(&i, nid, flags, type_a, type_b,    \                     p_start, p_end, p_nid);        \         i != (u64)ULLONG_MAX;                    \         __next_mem_range(&i, nid, flags, type_a, type_b,        \                  p_start, p_end, p_nid))

2)找到可用内存后,加入reserved队列。

int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size){phys_addr_t end = base + size - 1;    memblock_dbg("memblock_reserve: [%pa-%pa] %pF\n",             &base, &end, (void *)_RET_IP_);return memblock_add_range(&memblock.reserved, base, size, MAX_NUMNODES, 0);}

4.3 free

从reserved链表中移除:

int __init_memblock memblock_free(phys_addr_t base, phys_addr_t size){phys_addr_t end = base + size - 1;    memblock_dbg("   memblock_free: [%pa-%pa] %pF\n",             &base, &end, (void *)_RET_IP_);    kmemleak_free_part_phys(base, size);return memblock_remove_range(&memblock.reserved, base, size);}

memblock_remove_range:

1)memblock_isolate_range:将要释放的区域隔离出来,即若释放区域不是刚好的region对齐,而是一头一尾处在某个region中间,则新建两个region节点,把这两个头尾两个节点切割成两半,使得要释放的区域刚好占n个region。

2)memblock_remove_region:从region数组中删除对应的节点,后续的region节点前移。

static int __init_memblock memblock_remove_range(struct memblock_type *type,phys_addr_t base, phys_addr_t size){int start_rgn, end_rgn;int i, ret;    ret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn);if (ret)return ret;for (i = end_rgn - 1; i >= start_rgn; i--)        memblock_remove_region(type, i);return 0;}

4.4 exit

在初始化好伙伴系统后,memblock内存管理器要退出,将空闲内存加速伙伴系统管理(页框分配器<page_alloc.c>),并将内存管理权交给伙伴系统。

mem_init

  • free_unused_memmap

    释放memblock的memory中的空洞内存。

  • free_all_bootmem

    释放memblock未使用的内存。

void __init mem_init(void){...    free_unused_memmap();    free_all_bootmem();}

另外,mem_init中会打印启动内存信息,如:

在这里插入图片描述
  • free_unused_memmap

遍历memblock的memory节点,释放pre_end和start之间的内存,即空洞内存。

static void __init free_unused_memmap(void){unsigned long start, prev_end = 0;struct memblock_region *reg;/*     * This relies on each bank being in address order.     * The banks are sorted previously in bootmem_init().     */    for_each_memblock(memory, reg) {        start = memblock_region_memory_base_pfn(reg);#ifdef CONFIG_SPARSEMEM/*         * Take care not to free memmap entries that don't exist         * due to SPARSEMEM sections which aren't present.         */        start = min(start,                 ALIGN(prev_end, PAGES_PER_SECTION));#else/*         * Align down here since the VM subsystem insists that the         * memmap entries are valid from the bank start aligned to         * MAX_ORDER_NR_PAGES.         */        start = round_down(start, MAX_ORDER_NR_PAGES);#endif/*         * If we had a previous bank, and there is a space         * between the current bank and the previous, free it.         */if (prev_end && prev_end < start)            free_memmap(prev_end, start);/*         * Align up here since the VM subsystem insists that the         * memmap entries are valid from the bank end aligned to         * MAX_ORDER_NR_PAGES.         */        prev_end = ALIGN(memblock_region_memory_end_pfn(reg),                 MAX_ORDER_NR_PAGES);    }#ifdef CONFIG_SPARSEMEMif (!IS_ALIGNED(prev_end, PAGES_PER_SECTION))        free_memmap(prev_end,                ALIGN(prev_end, PAGES_PER_SECTION));#endif}
  • free_all_bootmem

free_all_bootmem 时遍历memory中没有reserved的,将其加入totlram_pages,归伙伴系统管理。

<nobootmem.c>

/** * free_all_bootmem - release free pages to the buddy allocator * * Return: the number of pages actually released. */unsigned long __init free_all_bootmem(void){unsigned long pages;    reset_all_zones_managed_pages();    pages = free_low_memory_core_early();    totalram_pages += pages;return pages;}

调用链:

free_all_bootmem->free_low_memory_core_early->__free_memory_core->__free_pages_memory->__free_pages_bootmem->__free_pages_boot_core->__free_pagespage_zone(page)->managed_pages += nr_pages;

free_low_memory_core_early:

static unsigned long __init free_low_memory_core_early(void){unsigned long count = 0;phys_addr_t start, end;    u64 i;    memblock_clear_hotplug(0-1);    for_each_reserved_mem_region(i, &start, &end)        reserve_bootmem_region(start, end);/*     * We need to use NUMA_NO_NODE instead of NODE_DATA(0)->node_id     *  because in some case like Node0 doesn't have RAM installed     *  low ram will be on Node1     */    for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end,NULL)        count += __free_memory_core(start, end);return count;}

启动阶段打印的reverved内存。

mem_init_print_info

reserved内存:(physpages - totalram_pages - totalcma_pages) << (PAGE_SHIFT - 10)。

void __init mem_init_print_info(const char *str){unsigned long physpages, codesize, datasize, rosize, bss_size;unsigned long init_code_size, init_data_size;    physpages = get_num_physpages();    codesize = _etext - _stext;    datasize = _edata - _sdata;    rosize = __end_rodata - __start_rodata;    bss_size = __bss_stop - __bss_start;    init_data_size = __init_end - __init_begin;    init_code_size = _einittext - _sinittext;/*     * Detect special cases and adjust section sizes accordingly:     * 1) .init.* may be embedded into .data sections     * 2) .init.text.* may be out of [__init_begin, __init_end],     *    please refer to arch/tile/kernel/vmlinux.lds.S.     * 3) .rodata.* may be embedded into .text or .data sections.     */#define adj_init_size(start, end, size, pos, adj) \    do { \if (start <= pos && pos < end && size > adj) \            size -= adj; \    } while (0)    adj_init_size(__init_begin, __init_end, init_data_size,             _sinittext, init_code_size);    adj_init_size(_stext, _etext, codesize, _sinittext, init_code_size);    adj_init_size(_sdata, _edata, datasize, __init_begin, init_data_size);    adj_init_size(_stext, _etext, codesize, __start_rodata, rosize);    adj_init_size(_sdata, _edata, datasize, __start_rodata, rosize);#undef    adj_init_size    pr_info("Memory: %luK/%luK available (%luK kernel code, %luK rwdata, %luK rodata, %luK init, %luK bss, %luK reserved, %luK cma-reserved"#ifdef    CONFIG_HIGHMEM", %luK highmem"#endif"%s%s)\n",        nr_free_pages() << (PAGE_SHIFT - 10),        physpages << (PAGE_SHIFT - 10),        codesize >> 10, datasize >> 10, rosize >> 10,        (init_data_size + init_code_size) >> 10, bss_size >> 10,        (physpages - totalram_pages - totalcma_pages) << (PAGE_SHIFT - 10),        totalcma_pages << (PAGE_SHIFT - 10),#ifdef    CONFIG_HIGHMEM        totalhigh_pages << (PAGE_SHIFT - 10),#endif        str ? ", " : "", str ? str : "");}

五、DEBUG方式

  • log

    启动阶段通过bootargs打开memblock的log 。

    memblock=debug
  • debugfs

可以通过debugfs查看memblock的memory和reserved信息。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-04 05:17:31 HTTP/2.0 GET : https://f.mffb.com.cn/a/490977.html
  2. 运行时间 : 0.132100s [ 吞吐率:7.57req/s ] 内存消耗:4,800.05kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=2d6ee0c2a12f65f55498d650c5381d31
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000400s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000741s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000363s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000320s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000480s ]
  6. SELECT * FROM `set` [ RunTime:0.000209s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000616s ]
  8. SELECT * FROM `article` WHERE `id` = 490977 LIMIT 1 [ RunTime:0.001990s ]
  9. UPDATE `article` SET `lasttime` = 1783113451 WHERE `id` = 490977 [ RunTime:0.012033s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000272s ]
  11. SELECT * FROM `article` WHERE `id` < 490977 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000483s ]
  12. SELECT * FROM `article` WHERE `id` > 490977 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000632s ]
  13. SELECT * FROM `article` WHERE `id` < 490977 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.011580s ]
  14. SELECT * FROM `article` WHERE `id` < 490977 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.022882s ]
  15. SELECT * FROM `article` WHERE `id` < 490977 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.006088s ]
0.133685s