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/