內核分配大塊連續內存的方法【轉】

原文鏈接:https://blog.csdn.net/edwardlulinux/article/details/45896901

參數傳遞:

    uboot向內核傳遞參數的方式分爲兩類。

    (1)第一類是通過boot cmd 例如在uboot終端提示行使用pri命令現實出的boot arg等。

    (2)第二類是通過DeviceTree。在/arch/arm/boot/dts/文件中和定義了和開發板相關的板級描述信息。

注(1)Device Tree的分析在其它文章中分析

以soc devkit (友晶)爲參考在dts目錄下文件socfpga_cyclone5.dtsi或者socfpga.dts文件中有以下描述:

memory {

name = "memory";

device_type = "memory";

reg = <0x0 0x40000000>; /* 1 GB */

};

描述了開發辦的物理內存使用情況爲1G。設備類型爲deivce_type。

    在函數:setup_arch()中調用setup_machine_fdt()。這個函數參數是__atags_pointer。這個地址是由uboot傳遞。Uboot把控制權交給kernel之前會在R2寄存中存放device tree的線性地址。物理還是虛擬地址?虛擬地址。此地址和物理地址相差一個pgd。即段映射的高12位做基地址。Kernel還沒有真正使用mmu的三級映射方案,還是停留在段映射的空間內。

函數調用順序:

setup_arch()

i early_init_dt_scan_memory()

early_init_dt_add_memory_arch()

arm_add_memory()

中作相關處理。主要是把reg字段解析。最後把base和size等參數存放入相關結構體。這些結構體在下一章中解釋。

 

uboot cmd 傳遞參數:

static int __init early_mem(char *p) 

以上兩種參數傳遞都是通過R2寄存器中的__atags_pointer傳遞。在setup_arch函數中解析。這個函數還是用了cmdline作爲參數分析uboot傳遞的參數。

以上兩種方式方法主要初始化以下全局變量:(memory的使用SOC採用的是Device Tree)

內存描述:

/*

 * Memory map description

 */

struct membank {

phys_addr_t start;

phys_addr_t size;

unsigned int highmem;

};

struct meminfo {

int nr_banks;

struct membank bank[NR_BANKS];

};

由membank到meminfo的過渡

membank描述了硬件的相關信息,這些信息最後落實到linux的管理範圍之內。並且依據處理後的相關信息分配佈置內存空間。這個過程使用到了memblock_type和memblock的數據結構。

struct memblock_type {

unsigned long cnt; /* number of regions */

unsigned long max; /* size of the allocated array */

phys_addr_t total_size; /* size of all regions */

struct memblock_region *regions;

};



struct memblock {

phys_addr_t current_limit;

struct memblock_type memory;

struct memblock_type reserved;

};

Reserved 和memory代表的是保留和物理內存描述。可以結合一下打印信息進行分析。

MEMBLOCK configuration:

 memory size = 0x40000000 reserved size = 0x54f553



 memory.cnt  = 0x1

 memory[0x0]    [0x00000000000000-0x0000003fffffff], 0x40000000 bytes



 reserved.cnt  = 0x3

 reserved[0x0]  [0x00000000004000-0x00000000007fff], 0x4000 bytes

 reserved[0x1]  [0x000000000081c0-0x0000000054e763], 0x5465a4 bytes

 reserved[0x2]  [0x00000003ffb000-0x00000003ffffae], 0x4faf bytes

   所有保留的數據大小綜合爲0x54f553。Memory的區域沒有記錄。只是調用create_mapping把這些物理地址建立相應的頁表和葉目錄項。那麼那些記錄爲reserve的內存大小又是什麼呢?其實這就是內核本身以及device tree 還有一些其它的數據指令段。這些段都是已經存在於內存中。並且系統本身以及系統將會用到的數據和指令等,這些信息非常重要,一定要保留。既然保留,那麼一定是將來的其它管理方案接手並且採用自己的方案管理。但是不會對前一任管理方案所保留的內容進行破壞。

    內核內存管理方案在初始化和運行時是不同的。初始化偏重於“區分”,而運行時偏重於“效率”。初始化一定要把不同的區域區分明白,告訴後者如何有效管理。至於後者的管理是否和前者衝突,當然有這些reserve的區域來解決。(實際使用更復雜)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章