linux 内存管理(13) - memblock 案例分析

  • 案例分析

1>.驱动的源码如下:

#include 
#include 
#include 

int bs_debug = 0;

#ifdef CONFIG_DEBUG_MEMBLOCK_HELPER
int __init debug_memblock_helper(void)
{
	struct memblock_region *reg;
	phys_addr_t size;
	phys_addr_t addr;
	phys_addr_t limit;
	bool state;
	int nid;

	/*
	 * Emulate memory
	 *
	 *                      memblock.memory
	 * 0     | <----------------------------------------> |
	 * +-----+---------+-------+----------+-------+-------+----+
	 * |     |         |       |          |       |       |    |
	 * |     |         |       |          |       |       |    |
	 * |     |         |       |          |       |       |    |
	 * +-----+---------+-------+----------+-------+-------+----+
	 *                 | <---> |          | <---> |
	 *                 Reserved 0         Reserved 1
	 *
	 * Memroy Region:   [0x60000000, 0xa0000000]
	 * Reserved Region: [0x80000000, 0x8d000000]
	 * Reserved Region: [0x90000000, 0x92000000]
	 */
	memblock_reserve(0x80000000, 0xd000000);
	memblock_reserve(0x90000000, 0x2000000);
	pr_info("Memory Regions:\n");
	for_each_memblock(memory, reg)
		pr_info("Region: %#x - %#x\n", reg->base,
					reg->base + reg->size);
	pr_info("Reserved Regions:\n");
	for_each_memblock(reserved, reg)
		pr_info("Region: %#x - %#x\n", reg->base,
					reg->base + reg->size);

	/* Obtain memblock.memory total size */
	size = memblock_phys_mem_size();
	pr_info("Phyiscal Memory total size: %#x\n", size);

	/* Obtain memblock.reserved total size */
	size = memblock_reserved_size();
	pr_info("Reserved Memory total size: %#x\n", size);

	/* Obtain Start physical address of DRAM */
	addr = memblock_start_of_DRAM();
	pr_info("Start address of DRAM:      %#x\n", addr);

	/* Obtain End of physical address of DRAM */
	addr = memblock_end_of_DRAM();
	pr_info("End address of DRAM:        %#x\n", addr);

	/* Check address is memblock.reserved */
	addr = 0x81000000; /* Assume address in memblock.reserved */
	state = memblock_is_reserved(addr);
	if (state)
		pr_info("Address: %#x in reserved.\n", addr);

	/* Check address in memblock.memory */
	addr = 0x62000000; /* Assume address in memblock.memory */
	state = memblock_is_memory(addr);
	if (state)
		pr_info("Address: %#x in memory.\n", addr);

	/* Check region in memblock.memory */
	addr = 0x62000000;
	size = 0x100000; /* Assume [0x62000000, 0x62100000] in memory */
	state = memblock_is_region_memory(addr, size);
	if (state)
		pr_info("Region: [%#x - %#x] in memblock.memory.\n",
				addr, addr + size);

	/* Check region in memblock.reserved */
	addr = 0x80000000;
	size = 0x100000; /* Assume [0x80000000, 0x80100000] in reserved */
	state = memblock_is_region_reserved(addr, size);
	if (state)
		pr_info("Region: [%#x - %#x] in memblock.reserved.\n",
				addr, addr + size);

	/* Obtain current limit for memblock */
	limit = memblock_get_current_limit();
	pr_info("MEMBLOCK current_limit: %#x\n", limit);

	/* Set up current_limit for MEMBLOCK */
	memblock_set_current_limit(limit);

	/* Check memblock regions is hotpluggable */
	state = memblock_is_hotpluggable(&memblock.memory.regions[0]);
	if (state)
		pr_info("MEMBLOCK memory.regions[0] is hotpluggable.\n");
	else
		pr_info("MEMBLOCK memory.regions[0] is not hotpluggable.\n");

	/* Check memblock regions is mirror */
	state = memblock_is_mirror(&memblock.memory.regions[0]);
	if (state)
		pr_info("MEMBLOCK memory.regions[0] is mirror.\n");
	else
		pr_info("MEMBLOCK memory.regions[0] is not mirror.\n");

	/* Check memblock regions is nomap */
	state = memblock_is_nomap(&memblock.memory.regions[0]);
	if (state)
		pr_info("MEMBLOCK memory.regions[0] is nomap.\n");
	else
		pr_info("MEMBLOCK memory.regions[0] is not nomap.\n");

	/* Check region nid information */
	nid = memblock_get_region_node(&memblock.memory.regions[0]);
	pr_info("MEMBLOCK memory.regions[0] nid: %#x\n", nid);
	/* Set up region nid */
	memblock_set_region_node(&memblock.memory.regions[0], nid);

	/* Obtian MEMBLOCK allocator direction */
	state = memblock_bottom_up();
	pr_info("MEMBLOCK direction: %s", state ? "bottom-up" : "top-down");
	/* Set up MEMBLOCK allocate direction */
	memblock_set_bottom_up(state);

	return 0;
}
#endif

  驱动直接编译进内核,将驱动放到 drivers/BiscuitOS/ 目录下,命名为 memblock.c。

2>.添加drivers/BiscuitOS/Kconfig:

menu "Biscuitos support"

config BISCUITOS
    bool "BiscuitOS driver"

if BISCUITOS

config BISCUITOS_DRV 
    bool "BiscuitOS driver"

config DEBUG_MEMBLOCK_HELPER
    bool "memblock helper"

config MEMBLOCK_ALLOCATOR
    bool "MEMBLOCK allocator"

if MEMBLOCK_ALLOCATOR
                                                                                                             
config DEBUG_MEMBLOCK_PHYS_ALLOC_TRY_NID
    bool "memblock_phys_alloc_try_nid()"

endif # MEMBLOCK_ALLOCATOR

endif # BISCUITOS_DRV

endmenu

3>.添加drivers/BiscuitOS/Makefile:

obj-$(CONFIG_MEMBLOCK_ALLOCATOR) += memblock.o  

4>.添加iTop-4412_scp_defconfig:

diff --git a/arch/arm/configs/iTop-4412_scp_defconfig b/arch/arm/configs/iTop-4412_scp_defconfig
index 828edc8f..58022467 100644
--- a/arch/arm/configs/iTop-4412_scp_defconfig
+++ b/arch/arm/configs/iTop-4412_scp_defconfig
 # CONFIG_STRING_SELFTEST is not set
 # CONFIG_VIRTUALIZATION is not set
+CONFIG_BISCUITOS=y
+CONFIG_BISCUITOS_DRV=y
+CONFIG_MEMBLOCK_ALLOCATOR=y
+CONFIG_DEBUG_MEMBLOCK_HELPER=y

5>.增加调试点

  驱动运行还需要在内核的指定位置添加调试点,由于该驱动需要在内核启动阶段就使用,参考下面 patch 将源码指定位置添加调试代码:

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 375b13f7e..fec6919a9 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1073,6 +1073,10 @@ void __init hyp_mode_check(void)
 void __init setup_arch(char **cmdline_p)
 {
 	const struct machine_desc *mdesc;
+#ifdef CONFIG_DEBUG_MEMBLOCK_HELPER
+	extern int bs_debug;
+	extern int debug_memblock_helper(void);
+#endif

 	setup_processor();
 	mdesc = setup_machine_fdt(__atags_pointer);
@@ -1104,6 +1108,10 @@ void __init setup_arch(char **cmdline_p)
 	strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
 	*cmdline_p = cmd_line;

ck_add
+#ifdef CONFIG_DEBUG_MEMBLOCK_HELPER
+	debug_memblock_helper();
+#endif
+
 	early_fixmap_init();
 	early_ioremap_init();

Note:
详细分析:- https://biscuitos.github.io/blog/MMU-ARM32-MEMBLOCK-memblock_information/

你可能感兴趣的:(linux,运维,服务器)