對於一個這樣的參數
memsize=128M mem=151M mem=118M@768M
內核是怎麼處理的呢?
- Arch/mips/kernel/setup.c:
- early_param("mem", early_parse_mem);
這裡說明mem參數由early_parse_mem函數處理。該函數調用memparse處理每一個mem=size@addr格式的參數,表示從addr地址(物理地址)開始的size大小的內存區域。如果沒有”@addr”則默認起始地址為零。
TODO:研究宏early_param的具體實現
對於每一個mem參數,都會調用add_memory_region(start, size, BOOT_MEM_RAM); 把指定的內存區域信息寫到boot_mem_map數組中。該數組定義為:
- arch/mips/include/asm/bootinfo.h:
- /*
- * A memory map that's built upon what was determined
- * or specified on the command line.
- */
- struct boot_mem_map {
- int nr_map;
- struct boot_mem_map_entry {
- phys_t addr; /* start of memory segment */
- phys_t size; /* size of memory segment */
- long type; /* type of memory segment */
- } map[BOOT_MEM_MAP_MAX];
- };
整數nr_map表示有效boot_mem_map_entry的個數。緊跟著就是boot_mem_map_entry的數組。按照上述啟動參數填充的值應該是:
- Nr_map =2;
- Map[0].addr=0
- Map[0].size=151M, map[0].type=RAM
- Map[1].addr=768M
- Map[1].size=118M, map[1].type=RAM
在處理命令行參數之前,還會自動檢測物理內存大小,這是在arch_mem_init()函數中調用plat_mem_setup()函數實現的。Plat_mem_setup()函數是跟板子相關的,不同的板子需要實現自己的這個函數。但是如果用戶在命令行中指定了mem參數,則自動檢測的結果會被覆蓋掉,正如early_parse_mem函數中的注釋所說:
- /*
- * If a user specifies memory size, we
- * blow away any automatically generated
- * size.
- */
關於自動檢測RAM,發現Plat_mem_setup()函數並沒有真正的去檢測DRAM,而是由用戶用#define直接指定了一個值,或者從uboot環境變量中讀取。而這個配置值並不等於真正的RAM大小。不知道能不能真正通過讀硬件的方式自動獲取RAM大小。而U-boot中RAM大小似乎也是用戶配置的。
Memsize=128M的處理:
在內核代碼中沒有找到處理memsize參數的地方。