歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux Kernel是如何做到釋放僅在啟動時使用的內存的?

Linux Kernel是如何做到釋放僅在啟動時使用的內存的?

日期:2017/2/28 13:48:15   编辑:Linux教程

你在哪裡

走遍千山萬水,終於找到了你。

void free_initmem(void)
{
    free_init_pages("unused kernel",
            (unsigned long)(&__init_begin),
            (unsigned long)(&__init_end));
}

啥也不說了,看這個函數名大家就知道是釋放啟動過程中使用的內存空間的。

只是因為在代碼中多看了你一眼

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;

在看內存管理的代碼中,說memblock使用的內存在啟動後會又內核回收,繼續作為內核可以使用的內存。引發了我一點點的好奇心。 話說內核也是像我們貧下中農一樣,挺省吃儉用的嘛。

從代碼上看,和普通變量定義時的差異就是這個後綴修飾,__initdata_memblock。

#ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
#define __init_memblock __meminit
#define __initdata_memblock __meminitdata
#else
#define __init_memblock
#define __initdata_memblock
#endif

看來這個還得在內核配置上有所配置才能做到省吃儉用。感覺和人生一樣,有的娃出生的時候含著金鑰匙,完全不在乎那麼點內存;而有的就要默默執行hard模式咯。

作為窮苦的孩子,咱還是學習學習hard模式是怎麼個玩兒的哈

#define __meminitdata    __section(.meminit.data)

ok,原來就是把這個數據結構定義在了一個叫 .meminit.data的區域。
區域(section)這個高級貨大家請自行搜索 elf section哈,因為我也不大記得了。還是不要誤導了大家。

幸福像花兒一樣

此處略過若干字,在include/asm-generic/vmlinux.lds.h文件中,有如下定義

#if defined(CONFIG_MEMORY_HOTPLUG)
#define MEM_KEEP(sec)    *(.mem##sec)
#define MEM_DISCARD(sec)
#else
#define MEM_KEEP(sec)
#define MEM_DISCARD(sec) *(.mem##sec)
#endif

/* init and exit section handling */
#define INIT_DATA                           \
    *(.init.data)                           \
    MEM_DISCARD(init.data)                      \
    KERNEL_CTORS()                          \
    ...

#define INIT_DATA_SECTION(initsetup_align)              \
    .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {       \
        INIT_DATA                       \
        INIT_SETUP(initsetup_align)             \
        INIT_CALLS                      \
        CON_INITCALL                        \
        SECURITY_INITCALL                   \
        INIT_RAM_FS                     \
    }

我猜你已經看出點什麼來了,如果沒用猜出來那再看上述代碼一百遍。。。
哦,忘了說了,這裡有個東西叫 “gcc鏈接腳本”,大家請先自行搜之 -_-!

踏破鐵鞋無覓處

高興得太早了,剛才一路順溜得找到了INIT_DATA_SECTION(),然後,就不知道然後了。。。

關鍵時候注釋起到了不可忽視的作用。所以說,寫代碼注釋很重要。

 * SECTIONS
 * {
 *  . = START;
 *  __init_begin = .;
 *  HEAD_TEXT_SECTION
 *  INIT_TEXT_SECTION(PAGE_SIZE)
 *  INIT_DATA_SECTION(...)
 *  PERCPU_SECTION(CACHELINE_SIZE)
 *  __init_end = .;
 *
 * ...
 * }

原來啟動階段可以釋放的內存不僅僅是內存初始化相關的部分,還包括了其他好多東西。嗯,又那麼深入了一點點~

好了,你看這裡和最開始的free_initmem()有沒有點眼熟呢?
我相信你會發現的:)

好了,今天就到這裡,希望對你有幫助~

Copyright © Linux教程網 All Rights Reserved