PSTORE ramoops 在Linux x86_64 与 arm64上使用

PSTORE ramoops 在Linux x86_64 与 arm64上使用

一、官方文档
kernel中关于ramoops的文档:
Documentation/admin-guide/ramoops.rst

二、操作过程

  1. kernel 配置选项:
CONFIG_PSTORE=y
CONFIG_PSTORE_CONSOLE=y
CONFIG_PSTORE_RAM=y
CONFIG_PSTORE_COMPRESS=y
CONFIG_PSTORE_COMPRESS_DEFAULT="zstd"
CONFIG_PSTORE_ZSTD_COMPRESS=y
CONFIG_PSTORE_ZSTD_COMPRESS_DEFAULT=y

  1. 参数说明
    主要的几个参数
    在这里插入图片描述
    2.1 参数的配置方式
    从kernel中的ramoops的文档中可知,共有三种方式设置这些参数,
    ① 模块参数
    ② 设备树中配置参数
    ③ platform_data

2.1.1 模块参数 的方式
例如:
内存起始地址为0x20200000,内存大小为1M,dump(dmesg)的大小为64K,console的大小为64K:

insmod reed_solomon.ko  
insmod ramoops.ko mem_size=0x100000 mem_address=0x20200000 record_size=0x10000  console_size=0x10000

2.1.2 设备树中配置参数的方式
该方式只能用于arm的方式,因为x86是没有设备树的。
Documentation/devicetree/bindings/reserved-memory/ramoops.txt

reserved-memory {
   #address-cells = <2>;
   #size-cells = <2>;
   ranges;

   ramoops@8f000000 {
       compatible = "ramoops";
       reg = <0 0x20200000 0 0x100000>;
       record-size = <0x10000>;
       console-size = <0x10000>;
   };
};

2.1.3 参数配置使用 platform_data 的方式
patch 如下


	diff --git a/fs/pstore/ramoops_dev.c b/fs/pstore/ramoops_dev.c
	new file mode 100644
	index 000000000..3adf85bfa
	--- /dev/null
	+++ b/fs/pstore/ramoops_dev.c
	@@ -0,0 +1,48 @@
	+#include <linux/init.h>
	+#include <linux/module.h>
	+#include <linux/platform_device.h>
	+#include <linux/pstore_ram.h>
	+#include <linux/memblock.h>
	+#include <linux/types.h>
	+#include <linux/sizes.h>
	+
	+
	+static struct ramoops_platform_data ramoops_data = {
	+      .mem_size               = 0x100000,
	+      .mem_address            = 0x20200000,
	+      .mem_type               = 0,
	+      .record_size            = 0x10000,
	+      .console_size           = 0x10000,
	+      .max_reason             = 2,
	+};
	+
	+static struct platform_device ramoops_dev = {
	+      .name = "ramoops",
	+      .dev = {
	+          .platform_data = &ramoops_data,
	+      },
	+};
	+
	+static int __init ramoops_device_init(void)
	+{
	+    int ret = 0;
	+
	+    pr_info("%s into %d\n", __func__, __LINE__);
	+    ret = platform_device_register(&ramoops_dev);
	+    if (ret) {
	+        pr_err("%s %d into: unable to register platform device\n", __func__, __LINE__);
	+    }
	+
	+    return ret;
	+}
	+
	+static void __exit ramoops_device_exit(void)
	+{
	+    platform_device_unregister(&ramoops_dev);
	+}
	+
	+postcore_initcall(ramoops_device_init);
	+module_exit(ramoops_device_exit);
	+
	+MODULE_LICENSE("GPL");
	+MODULE_DESCRIPTION("RAM Oops/Panic logger/device");


三、 在x86_64上的使用
对于x86只能使用模块参数或者platform_data的方式,由于编译进kernel,所以选择platform_data的方式;

  1. 指定预留内存
    1.1物理内存地址的选择
    首先可以通过 /proc/iomem 中的 System RAM 了解到物理内存的映射,如下(2G的内存):
cat /proc/iomem | grep "System RAM"
00001000-0009ebff : System RAM                            631K
00100000-1fffffff : System RAM                            511M
20200000-40003fff : System RAM                            510M
40005000-6a7c0fff : System RAM                            679M
6a804000-6adecfff : System RAM                            5M
6afaa000-7985cfff : System RAM                            232M
79fff000-79ffffff : System RAM                            4K
100000000-1005fffff : System RAM                          5M

总大小为1943M,与 kernel 启动 log 中的总内存大小1945M相差不多;

[ 0.050303] Memory: 1854248K/1992680K available (14340K kernel code, 1770K rwdata, 5820K rodata, 1412K init, 3060K bss, 138176K reserved, 0K cma-reserved)

cat /proc/iomem 
00000000-00000fff : Reserved
00001000-0009ebff : System RAM								631K
......
00100000-1fffffff : System RAM								511M
  01000000-01e010a4 : Kernel code
  02000000-025aefff : Kernel rodata
  02600000-027ba47f : Kernel data
  02d02000-02dfffff : Kernel bss
20000000-201fffff : Reserved
  20000000-201fffff : pnp 00:0a
20200000-40003fff : System RAM								510M
......

由以上可知
00100000-1fffffff : System RAM 511M 段的内存中,kernel 使用了01000000-02dfffff 30M的内存;所以选择
20200000-40003fff : System RAM 510M 这段地址的内存;(只要找一块空闲的地址即可,内存大小使用1M足以)

1.2 设置保留地址
接着需要将选择的物理地址段设置为保留地址,在 arch/x86/kernel/setup.c 中的 setup_arch() 函数中稍微前一些的位置中调用 memblock_reserve() 来声明保留内存;(新建了个函数reserve_ramoops()函数,在reserve_crashkernel()函数之前调用)
patch如下:


	diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
	index 065152d92..80892fd8d 100644
	--- a/arch/x86/kernel/setup.c
	+++ b/arch/x86/kernel/setup.c
	@@ -409,6 +409,15 @@ static void __init memblock_x86_reserve_range_setup_data(void)
 		}
 	}
 	
	+static void __init reserve_ramoops(void)
	+{
	+#ifdef CONFIG_RAMOOPS_SPEC_MEM_TEST
	+    pr_info("%s into %d before memblock_reserve ramoops\n", __func__, __LINE__);
	+    memblock_reserve(0x20200000, SZ_1M);
	+    pr_info("%s into %d after memblock_reserve ramoops\n", __func__, __LINE__);
	+#endif
	+}
	+
 	/*
  	* --------- Crashkernel reservation ------------------------------
  	*/
	@@ -1166,6 +1175,9 @@ void __init setup_arch(char **cmdline_p)
 		if (boot_cpu_has(X86_FEATURE_GBPAGES))
 			hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT);
	 
	+#ifdef CONFIG_PSTORE_RAM
	+	 reserve_ramoops();
	+#endif
	 	/*
 	 	* Reserve memory for crash kernel after SRAT is parsed so that it
 	 	* won't consume hotpluggable memory.



  1. 测试
    2.1 测试前准备
    2.1.1 挂载pstore文件系统
mount -t pstore pstore /sys/fs/pstore

2.1.2 确保驱动有被加载

dmesg | grep "ramoops"

2.1.3 开启panic_on_oops

echo 1 > /proc/sys/kernel/panic_on_oops

2.2 触发panic

echo c > /proc/sysrq-trigger

若这样没有触发panic,则可以使用以下patch:

diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 7ca209d4e..a0f7d4319 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -599,6 +599,8 @@ void __handle_sysrq(int key, bool check_mask)
 		 */
 		if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
 			pr_info("%s\n", op_p->action_msg);
+           op_p = NULL;
+			pr_info("after %s\n", op_p->action_msg);
 			console_loglevel = orig_log_level;
 			op_p->handler(key);
 		} else {

2.3 查看dump
重启后,先挂载pstore文件系统,再加确保驱动有被加载,然后即可在 /sys/fs/pstore/下看见dump log

ls /sys/fs/pstore/
console-ramoops-0 dmesg-ramoops-1
  1. 指定预留内存 – 使用自动分配物理内存
    3.1 原理
    因为指定预留内存的方式,需要预先知道本地物理内存的映射,所以有了不需要预先知道本地物理内存的映射,而自动分配物理内存作为保留内存的需求;

参考了 arch/x86/kernel/setup.c 中 reserve_crashkernel() 函数的实现,其保留内存的方式,其便是通过调用memblock_phys_alloc_range() 函数来实现的;

memblock_phys_alloc_range() 在start 和end 之间分配size 字节,需要4个参数,如下:
在这里插入图片描述
成功时分配的内存块的物理地址,失败时返回0


	static void __init reserve_ramoops(void)                                                                                                                                                     
	{                                           
	#ifdef CONFIG_RAMOOPS_MEM_AUTO_ALLOC    
	    extern phys_addr_t ram_mem_addr;    
	    unsigned long long crash_size, crash_base, total_mem;
	                                            
	    crash_size = SZ_1M;                     
	    total_mem = memblock_phys_mem_size();
	                                            
	    crash_base = memblock_phys_alloc_range(crash_size,
	            SZ_1M, 0,                       
	            SZ_64T);                        
	    if (!crash_base) {                      
	        pr_info("ramoops reservation failed - No suitable area found.\n");
	        return;                             
	    }                                       
	                                            
	                                            
	    pr_info("Reserving %ldMB of memory at %ldMB for ramoops (System RAM: %ldMB)\n",
	            (unsigned long)(crash_size >> 20), 
	            (unsigned long)(crash_base >> 20), 
	            (unsigned long)(total_mem >> 20));
	                                            
	    ram_mem_addr = crash_base;              
	#else                                       
	                                            
	#ifdef CONFIG_RAMOOPS_SPEC_MEM_TEST         
	    pr_info("%s into %d before memblock_reserve ramoops\n", __func__, __LINE__);
	    memblock_reserve(0x20200000, SZ_1M);
	    pr_info("%s into %d after memblock_reserve ramoops\n", __func__, __LINE__);
	#endif                                      
	                                            
	#endif                                      
	}


完整patch如下:


	diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
	index 065152d92..71f01a8cd 100644
	--- a/arch/x86/kernel/setup.c
	+++ b/arch/x86/kernel/setup.c
	@@ -49,6 +49,9 @@
	 #include <asm/vsyscall.h>
	 #include <linux/vmalloc.h>
	 
	+#ifdef CONFIG_RAMOOPS_MEM_AUTO_ALLOC
	+#include <linux/ramoops_dev.h>
	+#endif
	 /*
	  * max_low_pfn_mapped: highest directly mapped pfn < 4 GB
	  * max_pfn_mapped:     highest directly mapped pfn > 4 GB
	@@ -409,6 +412,41 @@ static void __init memblock_x86_reserve_range_setup_data(void)
	 	}
	 }
	 
	+static void __init reserve_ramoops(void)
	+{
	+#ifdef CONFIG_RAMOOPS_MEM_AUTO_ALLOC
	+    extern phys_addr_t ram_mem_addr;
	+	unsigned long long crash_size, crash_base, total_mem;
	+
	+    crash_size = SZ_1M;
	+	total_mem = memblock_phys_mem_size();
	+
	+    crash_base = memblock_phys_alloc_range(crash_size,
	+            SZ_1M, 0,
	+            SZ_64T);
	+    if (!crash_base) {
	+        pr_info("ramoops reservation failed - No suitable area found.\n");
	+        return;
	+    }
	+
	+
	+    pr_info("Reserving %ldMB of memory at %ldMB for ramoops (System RAM: %ldMB)\n",
	+            (unsigned long)(crash_size >> 20),
	+            (unsigned long)(crash_base >> 20),
	+            (unsigned long)(total_mem >> 20));
	+
	+    ram_mem_addr = crash_base;
	+#else
	+
	+#ifdef CONFIG_RAMOOPS_SPEC_MEM_TEST
	+    pr_info("%s into %d before memblock_reserve ramoops\n", __func__, __LINE__);
	+    memblock_reserve(0x20200000, SZ_1M);
	+    pr_info("%s into %d after memblock_reserve ramoops\n", __func__, __LINE__);
	+#endif
	+
	+#endif
	+}
	+
	 /*
	  * --------- Crashkernel reservation ------------------------------
	  */
	@@ -1166,6 +1204,9 @@ void __init setup_arch(char **cmdline_p)
	 	if (boot_cpu_has(X86_FEATURE_GBPAGES))
	 		hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT);
	 
	+#ifdef CONFIG_PSTORE_RAM
	+	reserve_ramoops();
	+#endif
	 	/*
	 	 * Reserve memory for crash kernel after SRAT is parsed so that it
	 	 * won't consume hotpluggable memory.
	diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
	index 8efe60487..25a33d079 100644
	--- a/fs/pstore/Kconfig
	+++ b/fs/pstore/Kconfig
	@@ -263,3 +263,11 @@ config PSTORE_BLK_FTRACE_SIZE
	 
	 	  NOTE that, both Kconfig and module parameters can configure
	 	  pstore/blk, but module parameters have priority over Kconfig.
	+
	+config RAMOOPS_MEM_AUTO_ALLOC
	+	bool "ramoops mem address use auto alloc in x86"
	+	depends on PSTORE_RAM
	+	default n
	+	help
	+     This will use the automatically allocated memory in setup.c 
	+     as the memory address for ramoops. in x86.
	diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
	index c270467ae..9193e7bf4 100644
	--- a/fs/pstore/Makefile
	+++ b/fs/pstore/Makefile
	@@ -4,6 +4,7 @@
	 #
	 
	 obj-$(CONFIG_PSTORE) += pstore.o
	+obj-$(CONFIG_RAMOOPS_MEM_AUTO_ALLOC) += ramoops_dev.o
	 
	 pstore-objs += inode.o platform.o
	 pstore-$(CONFIG_PSTORE_FTRACE)	+= ftrace.o
	diff --git a/fs/pstore/ramoops_dev.c b/fs/pstore/ramoops_dev.c
	new file mode 100644
	index 000000000..da272743c
	--- /dev/null
	+++ b/fs/pstore/ramoops_dev.c
	@@ -0,0 +1,61 @@
	+#include <linux/init.h>
	+#include <linux/module.h>
	+#include <linux/platform_device.h>
	+#include <linux/pstore_ram.h>
	+#include <linux/memblock.h>
	+#include <linux/types.h>
	+#include <linux/sizes.h>
	+#include <linux/ramoops_dev.h>
	+
	+
	+phys_addr_t ram_mem_addr = 0;
	+
	+static struct ramoops_platform_data ramoops_data = {
	+      .mem_size               = 0x100000,
	+      .mem_address            = 0x20200000,
	+      .mem_type               = 0,
	+      .record_size            = 0x10000,
	+      .console_size           = 0x10000,
	+      .max_reason             = 2,
	+};
	+
	+static struct platform_device ramoops_dev = {
	+      .name = "ramoops",
	+      .dev = {
	+              .platform_data = &ramoops_data,
	+      },
	+};
	+
	+static int __init ramoops_device_init(void)
	+{
	+    int ret = 0;
	+    pr_info("%s into %d\n", __func__, __LINE__);
	+
	+    if (0 != ram_mem_addr) {
	+        pr_info("%s %d into: ram_mem_addr = %llx, mem_address = %llx\n", 
	+                __func__, __LINE__, ram_mem_addr, ramoops_data.mem_address);
	+        ramoops_data.mem_address = ram_mem_addr;
	+        ramoops_data.mem_size = SZ_1M;
	+    } else {
	+        pr_err("%s %d into: ram_mem_addr is 0!\n", __func__, __LINE__);
	+        return -1;
	+    }
	+
	+    ret = platform_device_register(&ramoops_dev);
	+    if (ret) {
	+        pr_err("%s %d into: unable to register platform device\n", __func__, __LINE__);
	+    }
	+
	+    return ret;
	+}
	+
	+static void __exit ramoops_device_exit(void)
	+{
	+    platform_device_unregister(&ramoops_dev);
	+}
	+
	+postcore_initcall(ramoops_device_init);
	+module_exit(ramoops_device_exit);
	+
	+MODULE_LICENSE("GPL");
	+MODULE_DESCRIPTION("RAM Oops/Panic logger/device");
	diff --git a/include/linux/ramoops_dev.h b/include/linux/ramoops_dev.h
	new file mode 100644
	index 000000000..eb4278898
	--- /dev/null
	+++ b/include/linux/ramoops_dev.h
	@@ -0,0 +1,7 @@
	+#ifndef _LINUX_RAMOOPS_DEV_H
	+#define _LINUX_RAMOOPS_DEV_H
	+
	+
	+extern phys_addr_t ram_mem_addr;
	+
	+#endif




3.3 测试
从启动log中获取分配到的保留内存地址,作为参数在使用加载模块的方式即可。

[ 0.019398] Reserving 1MB of memory at 4100MB for ramoops (System RAM: 1945MB)
[ 0.019400] reserve_ramoops 431 into: memblock_phys_alloc_range ramoops_base = 0x100400000

挂载文件系统

mount -t pstore pstore /sys/fs/pstore

触发panic

echo c /proc/sysrq-trigger

重启后检测log

ls /sys/fs/pstore/
console-ramoops-0 dmesg-ramoops-0 dmesg-ramoops-1

四、 在arm64上的使用
在arm上,三种参数的配置方式都支持,只有设置指定预留内存的方式与x86有差异;

1 指定预留内存 – 直接指定物理内存
1.1物理内存地址的选择

cat /proc/iomem 
00200000-083fffff : System RAM
  00200000-0148ffff : Kernel code
  01490000-0166ffff : reserved
  01670000-019dffff : Kernel data
  08300000-08329fff : reserved
09400000-efffffff : System RAM
  ec000000-efffffff : reserved
......
1f0000000-1ffffffff : System RAM
......

由以上可知,可以继续使用0x20200000,大小1M 这段地址的内存。

1.2 设置保留地址
arm64与x86_64 不太一样,arm64需要在 arch/arm64/mm/init.c 中的 bootmem_init() 函数中中调用 memblock_reserve() 来声明保留内存;
patch如下:


	diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
	index 82cdb35ed..bddc93b10 100644
	--- a/arch/arm64/mm/init.c
	+++ b/arch/arm64/mm/init.c
	@@ -95,6 +95,16 @@ phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1;
	  */
	 static bool disable_dma32 __ro_after_init;
	 
	+static void __init reserve_ramoops(void)
	+{
	+#ifdef CONFIG_RAMOOPS_SPEC_MEM_TEST
	+
	+    pr_info("%s into %d before memblock_reserve ramoops\n", __func__, __LINE__);
	+    memblock_reserve(0x20200000, SZ_1M);
	+    pr_info("%s into %d after memblock_reserve ramoops\n", __func__, __LINE__);
	+#endif
	+}
	+
	 #ifdef CONFIG_KEXEC_CORE
	 /*
	  * reserve_crashkernel() - reserves memory for crash kernel
	@@ -454,6 +464,12 @@ void __init arm64_memblock_init(void)
	 
	 	reserve_elfcorehdr();
	 
	+
	+#ifdef CONFIG_PSTORE_RAM
	+    if (!IS_ENABLED(CONFIG_ZONE_DMA) && !IS_ENABLED(CONFIG_ZONE_DMA32))
	+        reserve_ramoops();
	+#endif
	+
	 	if (!IS_ENABLED(CONFIG_ZONE_DMA) && !IS_ENABLED(CONFIG_ZONE_DMA32))
	 		reserve_crashkernel();
	 
	@@ -500,6 +516,12 @@ void __init bootmem_init(void)
	 	dma_contiguous_reserve(arm64_dma_phys_limit);
	 	rk_dma_heap_cma_setup();
	 
	+
	+#ifdef CONFIG_PSTORE_RAM
	+    if (IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32))
	+        reserve_ramoops();
	+#endif
	+
	 	/*
	 	 * request_standard_resources() depends on crashkernel's memory being
	 	 * reserved, so do it here.


  1. 指定预留内存 – 使用自动分配物理内存
    在arm64下不再是使用memblock_phys_alloc_range()函数,而是使用memblock_find_in_range()函数来分配内存;
    参考了 arch/arm64/mm/init.c 中 reserve_crashkernel() 函数的实现,其保留内存的方式,便是通过调用memblock_find_in_range() 函数来实现的;

memblock_phys_alloc_range() 在start 和end 之间分配size 字节,需要4个参数,如下:
在这里插入图片描述

成功时返回找到的内存的物理地址,失败时返回0


	diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
	index 82cdb35ed..a9679a89f 100644
	--- a/arch/arm64/mm/init.c
	+++ b/arch/arm64/mm/init.c
	@@ -45,6 +45,10 @@
	 #include <asm/tlb.h>
	 #include <asm/alternative.h>
	 
	+#ifdef CONFIG_RAMOOPS_MEM_AUTO_ALLOC
	+#include <linux/ramoops_dev.h>
	+#endif
	+
	 /*
	  * We need to be able to catch inadvertent references to memstart_addr
	  * that occur (potentially in generic code) before arm64_memblock_init()
	@@ -95,6 +99,48 @@ phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1;
	  */
	 static bool disable_dma32 __ro_after_init;
	 
	+static void __init reserve_ramoops(void)
	+{
	+#ifdef CONFIG_RAMOOPS_MEM_AUTO_ALLOC
	+    extern phys_addr_t ram_mem_addr;
	+    unsigned long long crash_size, crash_base, total_mem;
	+    int ret = 0;
	+
	+    crash_size = SZ_1M;
	+    total_mem = memblock_phys_mem_size();
	+
	+    crash_base = memblock_find_in_range(0, arm64_dma_phys_limit, crash_size, SZ_1M);
	+    if (!crash_base) {
	+        pr_info("ramoops reservation failed - No suitable area found.\n");
	+        return ;
	+    }
	+
	+    pr_info("Reserving %ldMB of memory at %ldMB for ramoops (System RAM: %ldMB)\n",
	+            (unsigned long)(crash_size >> 20),
	+            (unsigned long)(crash_base >> 20),
	+            (unsigned long)(total_mem >> 20));
	+
	+    pr_info("%s into %d before memblock_reserve ramoops\n", __func__, __LINE__);
	+    ret = memblock_reserve(crash_base, crash_size);
	+    if (ret < 0) {
	+        pr_warn("ramoops reservation failed - memory is in use (0x%lx)\n",
	+                (unsigned long)crash_base);
	+        return ;
	+    }
	+
	+    ram_mem_addr = crash_base;
	+    pr_info("%s into %d after memblock_reserve ramoops\n", __func__, __LINE__);
	+#else
	+
	+#ifdef CONFIG_RAMOOPS_SPEC_MEM_TEST
	+    pr_info("%s into %d before memblock_reserve ramoops\n", __func__, __LINE__);
	+    memblock_reserve(0x20200000, SZ_1M);
	+    pr_info("%s into %d after memblock_reserve ramoops\n", __func__, __LINE__);
	+#endif
	+
	+#endif
	+}
	+
	 #ifdef CONFIG_KEXEC_CORE
	 /*
	  * reserve_crashkernel() - reserves memory for crash kernel
	@@ -454,6 +500,12 @@ void __init arm64_memblock_init(void)
	 
	 	reserve_elfcorehdr();
	 
	+
	+#ifdef CONFIG_PSTORE_RAM
	+    if (!IS_ENABLED(CONFIG_ZONE_DMA) && !IS_ENABLED(CONFIG_ZONE_DMA32))
	+        reserve_ramoops();
	+#endif
	+
	 	if (!IS_ENABLED(CONFIG_ZONE_DMA) && !IS_ENABLED(CONFIG_ZONE_DMA32))
	 		reserve_crashkernel();
	 
	@@ -500,6 +552,12 @@ void __init bootmem_init(void)
	 	dma_contiguous_reserve(arm64_dma_phys_limit);
	 	rk_dma_heap_cma_setup();
	 
	+
	+#ifdef CONFIG_PSTORE_RAM
	+    if (IS_ENABLED(CONFIG_ZONE_DMA) || IS_ENABLED(CONFIG_ZONE_DMA32))
	+        reserve_ramoops();
	+#endif
	+
	 	/*
	 	 * request_standard_resources() depends on crashkernel's memory being
	 	 * reserved, so do it here.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值