€•‡uŒsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ'/translations/zh_CN/admin-guide/ramoops”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/zh_TW/admin-guide/ramoops”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/it_IT/admin-guide/ramoops”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/ja_JP/admin-guide/ramoops”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/ko_KR/admin-guide/ramoops”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/pt_BR/admin-guide/ramoops”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/sp_SP/admin-guide/ramoops”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒRamoops oops/panic logger”h]”hŒRamoops oops/panic logger”…””}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³ŒA/var/lib/git/docbuild/linux/Documentation/admin-guide/ramoops.rst”h´KubhŒ paragraph”“”)”}”(hŒ%Sergiu Iordache ”h]”(hŒSergiu Iordache <”…””}”(hhÍh²hh³Nh´NubhŒ reference”“”)”}”(hŒsergiu@chromium.org”h]”hŒsergiu@chromium.org”…””}”(hh×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:sergiu@chromium.org”uh1hÕhhÍubhŒ>”…””}”(hhÍh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubhÌ)”}”(hŒUpdated: 10 Feb 2021”h]”hŒUpdated: 10 Feb 2021”…””}”(hhñh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubh¶)”}”(hhh]”(h»)”}”(hŒ Introduction”h]”hŒ Introduction”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhhÿh²hh³hÊh´K ubhÌ)”}”(hŒûRamoops is an oops/panic logger that writes its logs to RAM before the system crashes. It works by logging oopses and panics in a circular buffer. Ramoops needs a system with persistent RAM so that the content of that area can survive after a restart.”h]”hŒûRamoops is an oops/panic logger that writes its logs to RAM before the system crashes. It works by logging oopses and panics in a circular buffer. Ramoops needs a system with persistent RAM so that the content of that area can survive after a restart.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K hhÿh²hubeh}”(h]”Œ introduction”ah ]”h"]”Œ introduction”ah$]”h&]”uh1hµhh·h²hh³hÊh´K ubh¶)”}”(hhh]”(h»)”}”(hŒRamoops concepts”h]”hŒRamoops concepts”…””}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj&h²hh³hÊh´KubhÌ)”}”(hŒ†Ramoops uses a predefined memory area to store the dump. The start and size and type of the memory area are set using three variables:”h]”hŒ†Ramoops uses a predefined memory area to store the dump. The start and size and type of the memory area are set using three variables:”…””}”(hj7h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj&h²hubhŒ block_quote”“”)”}”(hX%* ``mem_address`` for the start * ``mem_size`` for the size. The memory size will be rounded down to a power of two. * ``mem_type`` to specify if the memory type (default is pgprot_writecombine). * ``mem_name`` to specify a memory region defined by ``reserve_mem`` command line parameter. ”h]”hŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒ``mem_address`` for the start”h]”hÌ)”}”(hjTh]”(hŒliteral”“”)”}”(hŒ``mem_address``”h]”hŒ mem_address”…””}”(hj[h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhjVubhŒ for the start”…””}”(hjVh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhjRubah}”(h]”h ]”h"]”h$]”h&]”uh1jPhjMubjQ)”}”(hŒR``mem_size`` for the size. The memory size will be rounded down to a power of two.”h]”hÌ)”}”(hŒR``mem_size`` for the size. The memory size will be rounded down to a power of two.”h]”(jZ)”}”(hŒ ``mem_size``”h]”hŒmem_size”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj}ubhŒF for the size. The memory size will be rounded down to a power of two.”…””}”(hj}h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khjyubah}”(h]”h ]”h"]”h$]”h&]”uh1jPhjMubjQ)”}”(hŒL``mem_type`` to specify if the memory type (default is pgprot_writecombine).”h]”hÌ)”}”(hj¡h]”(jZ)”}”(hŒ ``mem_type``”h]”hŒmem_type”…””}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj£ubhŒ@ to specify if the memory type (default is pgprot_writecombine).”…””}”(hj£h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhjŸubah}”(h]”h ]”h"]”h$]”h&]”uh1jPhjMubjQ)”}”(hŒ[``mem_name`` to specify a memory region defined by ``reserve_mem`` command line parameter. ”h]”hÌ)”}”(hŒZ``mem_name`` to specify a memory region defined by ``reserve_mem`` command line parameter.”h]”(jZ)”}”(hŒ ``mem_name``”h]”hŒmem_name”…””}”(hjÌh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhjÈubhŒ' to specify a memory region defined by ”…””}”(hjÈh²hh³Nh´NubjZ)”}”(hŒ``reserve_mem``”h]”hŒ reserve_mem”…””}”(hjÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhjÈubhŒ command line parameter.”…””}”(hjÈh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhjÄubah}”(h]”h ]”h"]”h$]”h&]”uh1jPhjMubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1jKh³hÊh´KhjGubah}”(h]”h ]”h"]”h$]”h&]”uh1jEh³hÊh´Khj&h²hubhÌ)”}”(hXdTypically the default value of ``mem_type=0`` should be used as that sets the pstore mapping to pgprot_writecombine. Setting ``mem_type=1`` attempts to use ``pgprot_noncached``, which only works on some platforms. This is because pstore depends on atomic operations. At least on ARM, pgprot_noncached causes the memory to be mapped strongly ordered, and atomic operations on strongly ordered memory are implementation defined, and won't work on many ARMs such as omaps. Setting ``mem_type=2`` attempts to treat the memory region as normal memory, which enables full cache on it. This can improve the performance.”h]”(hŒTypically the default value of ”…””}”(hj h²hh³Nh´NubjZ)”}”(hŒ``mem_type=0``”h]”hŒ mem_type=0”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj ubhŒP should be used as that sets the pstore mapping to pgprot_writecombine. Setting ”…””}”(hj h²hh³Nh´NubjZ)”}”(hŒ``mem_type=1``”h]”hŒ mem_type=1”…””}”(hj$h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj ubhŒ attempts to use ”…””}”(hj h²hh³Nh´NubjZ)”}”(hŒ``pgprot_noncached``”h]”hŒpgprot_noncached”…””}”(hj6h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj ubhX0, which only works on some platforms. This is because pstore depends on atomic operations. At least on ARM, pgprot_noncached causes the memory to be mapped strongly ordered, and atomic operations on strongly ordered memory are implementation defined, and won’t work on many ARMs such as omaps. Setting ”…””}”(hj h²hh³Nh´NubjZ)”}”(hŒ``mem_type=2``”h]”hŒ mem_type=2”…””}”(hjHh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj ubhŒx attempts to treat the memory region as normal memory, which enables full cache on it. This can improve the performance.”…””}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj&h²hubhÌ)”}”(hŒThe memory area is divided into ``record_size`` chunks (also rounded down to power of two) and each kmesg dump writes a ``record_size`` chunk of information.”h]”(hŒ The memory area is divided into ”…””}”(hj`h²hh³Nh´NubjZ)”}”(hŒ``record_size``”h]”hŒ record_size”…””}”(hjhh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj`ubhŒI chunks (also rounded down to power of two) and each kmesg dump writes a ”…””}”(hj`h²hh³Nh´NubjZ)”}”(hŒ``record_size``”h]”hŒ record_size”…””}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj`ubhŒ chunk of information.”…””}”(hj`h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K&hj&h²hubhÌ)”}”(hX Limiting which kinds of kmsg dumps are stored can be controlled via the ``max_reason`` value, as defined in include/linux/kmsg_dump.h's ``enum kmsg_dump_reason``. For example, to store both Oopses and Panics, ``max_reason`` should be set to 2 (KMSG_DUMP_OOPS), to store only Panics ``max_reason`` should be set to 1 (KMSG_DUMP_PANIC). Setting this to 0 (KMSG_DUMP_UNDEF), means the reason filtering will be controlled by the ``printk.always_kmsg_dump`` boot param: if unset, it'll be KMSG_DUMP_OOPS, otherwise KMSG_DUMP_MAX.”h]”(hŒHLimiting which kinds of kmsg dumps are stored can be controlled via the ”…””}”(hj’h²hh³Nh´NubjZ)”}”(hŒ``max_reason``”h]”hŒ max_reason”…””}”(hjšh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj’ubhŒ4 value, as defined in include/linux/kmsg_dump.h’s ”…””}”(hj’h²hh³Nh´NubjZ)”}”(hŒ``enum kmsg_dump_reason``”h]”hŒenum kmsg_dump_reason”…””}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj’ubhŒ0. For example, to store both Oopses and Panics, ”…””}”(hj’h²hh³Nh´NubjZ)”}”(hŒ``max_reason``”h]”hŒ max_reason”…””}”(hj¾h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj’ubhŒ; should be set to 2 (KMSG_DUMP_OOPS), to store only Panics ”…””}”(hj’h²hh³Nh´NubjZ)”}”(hŒ``max_reason``”h]”hŒ max_reason”…””}”(hjÐh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj’ubhŒ should be set to 1 (KMSG_DUMP_PANIC). Setting this to 0 (KMSG_DUMP_UNDEF), means the reason filtering will be controlled by the ”…””}”(hj’h²hh³Nh´NubjZ)”}”(hŒ``printk.always_kmsg_dump``”h]”hŒprintk.always_kmsg_dump”…””}”(hjâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj’ubhŒJ boot param: if unset, it’ll be KMSG_DUMP_OOPS, otherwise KMSG_DUMP_MAX.”…””}”(hj’h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K*hj&h²hubhÌ)”}”(hŒ”The module uses a counter to record multiple dumps but the counter gets reset on restart (i.e. new dumps after the restart will overwrite old ones).”h]”hŒ”The module uses a counter to record multiple dumps but the counter gets reset on restart (i.e. new dumps after the restart will overwrite old ones).”…””}”(hjúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K3hj&h²hubhÌ)”}”(hXRamoops also supports software ECC protection of persistent memory regions. This might be useful when a hardware reset was used to bring the machine back to life (i.e. a watchdog triggered). In such cases, RAM may be somewhat corrupt, but usually it is restorable.”h]”hXRamoops also supports software ECC protection of persistent memory regions. This might be useful when a hardware reset was used to bring the machine back to life (i.e. a watchdog triggered). In such cases, RAM may be somewhat corrupt, but usually it is restorable.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K6hj&h²hubeh}”(h]”Œramoops-concepts”ah ]”h"]”Œramoops concepts”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)”}”(hhh]”(h»)”}”(hŒSetting the parameters”h]”hŒSetting the parameters”…””}”(hj!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjh²hh³hÊh´Khjh²hubjF)”}”(hXˆ A. Use the module parameters (which have the names of the variables described as before). For quick debugging, you can also reserve parts of memory during boot and then use the reserved memory for ramoops. For example, assuming a machine with > 128 MB of memory, the following kernel command line will tell the kernel to use only the first 128 MB of memory, and place ECC-protected ramoops region at 128 MB boundary:: mem=128M ramoops.mem_address=0x8000000 ramoops.ecc=1 B. Use Device Tree bindings, as described in ``Documentation/devicetree/bindings/reserved-memory/ramoops.yaml``. For example:: reserved-memory { #address-cells = <2>; #size-cells = <2>; ranges; ramoops@8f000000 { compatible = "ramoops"; reg = <0 0x8f000000 0 0x100000>; record-size = <0x4000>; console-size = <0x4000>; }; }; C. Use a platform device and set the platform data. The parameters can then be set through that platform data. An example of doing that is: .. code-block:: c #include [...] static struct ramoops_platform_data ramoops_data = { .mem_size = <...>, .mem_address = <...>, .mem_type = <...>, .record_size = <...>, .max_reason = <...>, .ecc = <...>, }; static struct platform_device ramoops_dev = { .name = "ramoops", .dev = { .platform_data = &ramoops_data, }, }; [... inside a function ...] int ret; ret = platform_device_register(&ramoops_dev); if (ret) { printk(KERN_ERR "unable to register platform device\n"); return ret; } D. Using a region of memory reserved via ``reserve_mem`` command line parameter. The address and size will be defined by the ``reserve_mem`` parameter. Note, that ``reserve_mem`` may not always allocate memory in the same location, and cannot be relied upon. Testing will need to be done, and it may not work on every machine, nor every kernel. Consider this a "best effort" approach. The ``reserve_mem`` option takes a size, alignment and name as arguments. The name is used to map the memory to a label that can be retrieved by ramoops. reserve_mem=2M:4096:oops ramoops.mem_name=oops ”h]”(hÌ)”}”(hX¡A. Use the module parameters (which have the names of the variables described as before). For quick debugging, you can also reserve parts of memory during boot and then use the reserved memory for ramoops. For example, assuming a machine with > 128 MB of memory, the following kernel command line will tell the kernel to use only the first 128 MB of memory, and place ECC-protected ramoops region at 128 MB boundary::”h]”hX A. Use the module parameters (which have the names of the variables described as before). For quick debugging, you can also reserve parts of memory during boot and then use the reserved memory for ramoops. For example, assuming a machine with > 128 MB of memory, the following kernel command line will tell the kernel to use only the first 128 MB of memory, and place ECC-protected ramoops region at 128 MB boundary:”…””}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K@hj=ubhŒ literal_block”“”)”}”(hŒ4mem=128M ramoops.mem_address=0x8000000 ramoops.ecc=1”h]”hŒ4mem=128M ramoops.mem_address=0x8000000 ramoops.ecc=1”…””}”hjQsbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1jOh³hÊh´KGhj=ubhÌ)”}”(hŒ~B. Use Device Tree bindings, as described in ``Documentation/devicetree/bindings/reserved-memory/ramoops.yaml``. For example::”h]”(hŒ-B. Use Device Tree bindings, as described in ”…””}”(hjah²hh³Nh´NubjZ)”}”(hŒB``Documentation/devicetree/bindings/reserved-memory/ramoops.yaml``”h]”hŒ>Documentation/devicetree/bindings/reserved-memory/ramoops.yaml”…””}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhjaubhŒ. For example:”…””}”(hjah²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KIhj=ubjP)”}”(hX.reserved-memory { #address-cells = <2>; #size-cells = <2>; ranges; ramoops@8f000000 { compatible = "ramoops"; reg = <0 0x8f000000 0 0x100000>; record-size = <0x4000>; console-size = <0x4000>; }; };”h]”hX.reserved-memory { #address-cells = <2>; #size-cells = <2>; ranges; ramoops@8f000000 { compatible = "ramoops"; reg = <0 0x8f000000 0 0x100000>; record-size = <0x4000>; console-size = <0x4000>; }; };”…””}”hjsbah}”(h]”h ]”h"]”h$]”h&]”j_j`uh1jOh³hÊh´KMhj=ubhÌ)”}”(hŒ‹C. Use a platform device and set the platform data. The parameters can then be set through that platform data. An example of doing that is:”h]”hŒ‹C. Use a platform device and set the platform data. The parameters can then be set through that platform data. An example of doing that is:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KZhj=ubjP)”}”(hXŠ#include [...] static struct ramoops_platform_data ramoops_data = { .mem_size = <...>, .mem_address = <...>, .mem_type = <...>, .record_size = <...>, .max_reason = <...>, .ecc = <...>, }; static struct platform_device ramoops_dev = { .name = "ramoops", .dev = { .platform_data = &ramoops_data, }, }; [... inside a function ...] int ret; ret = platform_device_register(&ramoops_dev); if (ret) { printk(KERN_ERR "unable to register platform device\n"); return ret; }”h]”hXŠ#include [...] static struct ramoops_platform_data ramoops_data = { .mem_size = <...>, .mem_address = <...>, .mem_type = <...>, .record_size = <...>, .max_reason = <...>, .ecc = <...>, }; static struct platform_device ramoops_dev = { .name = "ramoops", .dev = { .platform_data = &ramoops_data, }, }; [... inside a function ...] int ret; ret = platform_device_register(&ramoops_dev); if (ret) { printk(KERN_ERR "unable to register platform device\n"); return ret; }”…””}”hjsbah}”(h]”h ]”h"]”h$]”h&]”j_j`Œforce”‰Œlanguage”Œc”Œhighlight_args”}”uh1jOh³hÊh´K]hj=ubhŒenumerated_list”“”)”}”(hhh]”jQ)”}”(hXMUsing a region of memory reserved via ``reserve_mem`` command line parameter. The address and size will be defined by the ``reserve_mem`` parameter. Note, that ``reserve_mem`` may not always allocate memory in the same location, and cannot be relied upon. Testing will need to be done, and it may not work on every machine, nor every kernel. Consider this a "best effort" approach. The ``reserve_mem`` option takes a size, alignment and name as arguments. The name is used to map the memory to a label that can be retrieved by ramoops. reserve_mem=2M:4096:oops ramoops.mem_name=oops ”h]”(hÌ)”}”(hXUsing a region of memory reserved via ``reserve_mem`` command line parameter. The address and size will be defined by the ``reserve_mem`` parameter. Note, that ``reserve_mem`` may not always allocate memory in the same location, and cannot be relied upon. Testing will need to be done, and it may not work on every machine, nor every kernel. Consider this a "best effort" approach. The ``reserve_mem`` option takes a size, alignment and name as arguments. The name is used to map the memory to a label that can be retrieved by ramoops.”h]”(hŒ&Using a region of memory reserved via ”…””}”(hj¹h²hh³Nh´NubjZ)”}”(hŒ``reserve_mem``”h]”hŒ reserve_mem”…””}”(hjÁh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj¹ubhŒE command line parameter. The address and size will be defined by the ”…””}”(hj¹h²hh³Nh´NubjZ)”}”(hŒ``reserve_mem``”h]”hŒ reserve_mem”…””}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj¹ubhŒ parameter. Note, that ”…””}”(hj¹h²hh³Nh´NubjZ)”}”(hŒ``reserve_mem``”h]”hŒ reserve_mem”…””}”(hjåh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj¹ubhŒ× may not always allocate memory in the same location, and cannot be relied upon. Testing will need to be done, and it may not work on every machine, nor every kernel. Consider this a “best effort†approach. The ”…””}”(hj¹h²hh³Nh´NubjZ)”}”(hŒ``reserve_mem``”h]”hŒ reserve_mem”…””}”(hj÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jYhj¹ubhŒ† option takes a size, alignment and name as arguments. The name is used to map the memory to a label that can be retrieved by ramoops.”…””}”(hj¹h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K{hjµubjF)”}”(hŒ0reserve_mem=2M:4096:oops ramoops.mem_name=oops ”h]”hÌ)”}”(hŒ/reserve_mem=2M:4096:oops ramoops.mem_name=oops”h]”hŒ/reserve_mem=2M:4096:oops ramoops.mem_name=oops”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K„hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jEh³hÊh´K„hjµubeh}”(h]”h ]”h"]”h$]”h&]”uh1jPhj²ubah}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œ upperalpha”Œprefix”hŒsuffix”Œ.”Œstart”Kuh1j°hj=ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jEh³hÊh´K@hjh²hubhÌ)”}”(hŒÆYou can specify either RAM memory or peripheral devices' memory. However, when specifying RAM, be sure to reserve the memory by issuing memblock_reserve() very early in the architecture code, e.g.::”h]”hŒÇYou can specify either RAM memory or peripheral devices’ memory. However, when specifying RAM, be sure to reserve the memory by issuing memblock_reserve() very early in the architecture code, e.g.:”…””}”(hj?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K†hjh²hubjP)”}”(hŒ_#include memblock_reserve(ramoops_data.mem_address, ramoops_data.mem_size);”h]”hŒ_#include memblock_reserve(ramoops_data.mem_address, ramoops_data.mem_size);”…””}”hjMsbah}”(h]”h ]”h"]”h$]”h&]”j_j`uh1jOh³hÊh´KŠhjh²hubeh}”(h]”Œsetting-the-parameters”ah ]”h"]”Œsetting the parameters”ah$]”h&]”uh1hµhh·h²hh³hÊh´K /sys/kernel/debug/pstore/record_ftrace # reboot -f [...] # mount -t pstore pstore /mnt/ # tail /mnt/ftrace-ramoops 0 ffffffff8101ea64 ffffffff8101bcda native_apic_mem_read <- disconnect_bsp_APIC+0x6a/0xc0 0 ffffffff8101ea44 ffffffff8101bcf6 native_apic_mem_write <- disconnect_bsp_APIC+0x86/0xc0 0 ffffffff81020084 ffffffff8101a4b5 hpet_disable <- native_machine_shutdown+0x75/0x90 0 ffffffff81005f94 ffffffff8101a4bb iommu_shutdown_noop <- native_machine_shutdown+0x7b/0x90 0 ffffffff8101a6a1 ffffffff8101a437 native_machine_emergency_restart <- native_machine_restart+0x37/0x40 0 ffffffff811f9876 ffffffff8101a73a acpi_reboot <- native_machine_emergency_restart+0xaa/0x1e0 0 ffffffff8101a514 ffffffff8101a772 mach_reboot_fixups <- native_machine_emergency_restart+0xe2/0x1e0 0 ffffffff811d9c54 ffffffff8101a7a0 __const_udelay <- native_machine_emergency_restart+0x110/0x1e0 0 ffffffff811d9c34 ffffffff811d9c80 __delay <- __const_udelay+0x30/0x40 0 ffffffff811d9d14 ffffffff811d9c3f delay_tsc <- __delay+0xf/0x20”h]”hXB# mount -t debugfs debugfs /sys/kernel/debug/ # echo 1 > /sys/kernel/debug/pstore/record_ftrace # reboot -f [...] # mount -t pstore pstore /mnt/ # tail /mnt/ftrace-ramoops 0 ffffffff8101ea64 ffffffff8101bcda native_apic_mem_read <- disconnect_bsp_APIC+0x6a/0xc0 0 ffffffff8101ea44 ffffffff8101bcf6 native_apic_mem_write <- disconnect_bsp_APIC+0x86/0xc0 0 ffffffff81020084 ffffffff8101a4b5 hpet_disable <- native_machine_shutdown+0x75/0x90 0 ffffffff81005f94 ffffffff8101a4bb iommu_shutdown_noop <- native_machine_shutdown+0x7b/0x90 0 ffffffff8101a6a1 ffffffff8101a437 native_machine_emergency_restart <- native_machine_restart+0x37/0x40 0 ffffffff811f9876 ffffffff8101a73a acpi_reboot <- native_machine_emergency_restart+0xaa/0x1e0 0 ffffffff8101a514 ffffffff8101a772 mach_reboot_fixups <- native_machine_emergency_restart+0xe2/0x1e0 0 ffffffff811d9c54 ffffffff8101a7a0 __const_udelay <- native_machine_emergency_restart+0x110/0x1e0 0 ffffffff811d9c34 ffffffff811d9c80 __delay <- __const_udelay+0x30/0x40 0 ffffffff811d9d14 ffffffff811d9c3f delay_tsc <- __delay+0xf/0x20”…””}”hjsbah}”(h]”h ]”h"]”h$]”h&]”j_j`uh1jOh³hÊh´K¢hjÕh²hubeh}”(h]”Œpersistent-function-tracing”ah ]”h"]”Œpersistent function tracing”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kœubeh}”(h]”Œramoops-oops-panic-logger”ah ]”h"]”Œramoops oops/panic logger”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”jGŒerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(j!jj#j jjj`j]j™j–jÒjÏjjuŒ nametypes”}”(j!‰j#‰j‰j`‰j™‰jÒ‰j‰uh}”(jh·j hÿjj&j]jj–jcjÏjœjjÕuŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”hŒsystem_message”“”)”}”(hhh]”hÌ)”}”(hŒ:Enumerated list start value not ordinal-1: "D" (ordinal 4)”h]”hŒ>Enumerated list start value not ordinal-1: “D†(ordinal 4)”…””}”(hj®h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËhj«ubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”ŒINFO”Œsource”hÊŒline”Kuh1j©hj=ubaŒtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.