| Sergiu Iordache | 4126dac | 2011-08-13 12:34:56 -0700 | [diff] [blame] | 1 | Ramoops oops/panic logger | 
 | 2 | ========================= | 
 | 3 |  | 
 | 4 | Sergiu Iordache <sergiu@chromium.org> | 
 | 5 |  | 
| Kees Cook | 9ba80d9 | 2012-05-03 15:45:02 +1000 | [diff] [blame] | 6 | Updated: 17 November 2011 | 
| Sergiu Iordache | 4126dac | 2011-08-13 12:34:56 -0700 | [diff] [blame] | 7 |  | 
 | 8 | 0. Introduction | 
 | 9 |  | 
 | 10 | Ramoops is an oops/panic logger that writes its logs to RAM before the system | 
 | 11 | crashes. It works by logging oopses and panics in a circular buffer. Ramoops | 
 | 12 | needs a system with persistent RAM so that the content of that area can | 
 | 13 | survive after a restart. | 
 | 14 |  | 
 | 15 | 1. Ramoops concepts | 
 | 16 |  | 
 | 17 | Ramoops uses a predefined memory area to store the dump. The start and size of | 
 | 18 | the memory area are set using two variables: | 
 | 19 |   * "mem_address" for the start | 
 | 20 |   * "mem_size" for the size. The memory size will be rounded down to a | 
 | 21 |   power of two. | 
 | 22 |  | 
 | 23 | The memory area is divided into "record_size" chunks (also rounded down to | 
 | 24 | power of two) and each oops/panic writes a "record_size" chunk of | 
 | 25 | information. | 
 | 26 |  | 
 | 27 | Dumping both oopses and panics can be done by setting 1 in the "dump_oops" | 
 | 28 | variable while setting 0 in that variable dumps only the panics. | 
 | 29 |  | 
 | 30 | The module uses a counter to record multiple dumps but the counter gets reset | 
 | 31 | on restart (i.e. new dumps after the restart will overwrite old ones). | 
 | 32 |  | 
| Anton Vorontsov | 39eb7e97 | 2012-05-17 00:15:34 -0700 | [diff] [blame] | 33 | Ramoops also supports software ECC protection of persistent memory regions. | 
 | 34 | This might be useful when a hardware reset was used to bring the machine back | 
 | 35 | to life (i.e. a watchdog triggered). In such cases, RAM may be somewhat | 
 | 36 | corrupt, but usually it is restorable. | 
 | 37 |  | 
| Sergiu Iordache | 4126dac | 2011-08-13 12:34:56 -0700 | [diff] [blame] | 38 | 2. Setting the parameters | 
 | 39 |  | 
 | 40 | Setting the ramoops parameters can be done in 2 different manners: | 
 | 41 |  1. Use the module parameters (which have the names of the variables described | 
 | 42 |  as before). | 
 | 43 |  2. Use a platform device and set the platform data. The parameters can then | 
 | 44 |  be set through that platform data. An example of doing that is: | 
 | 45 |  | 
| Anton Vorontsov | 1894a25 | 2012-05-16 05:43:08 -0700 | [diff] [blame] | 46 | #include <linux/pstore_ram.h> | 
| Sergiu Iordache | 4126dac | 2011-08-13 12:34:56 -0700 | [diff] [blame] | 47 | [...] | 
 | 48 |  | 
 | 49 | static struct ramoops_platform_data ramoops_data = { | 
 | 50 |         .mem_size               = <...>, | 
 | 51 |         .mem_address            = <...>, | 
 | 52 |         .record_size            = <...>, | 
 | 53 |         .dump_oops              = <...>, | 
| Anton Vorontsov | 39eb7e97 | 2012-05-17 00:15:34 -0700 | [diff] [blame] | 54 |         .ecc                    = <...>, | 
| Sergiu Iordache | 4126dac | 2011-08-13 12:34:56 -0700 | [diff] [blame] | 55 | }; | 
 | 56 |  | 
 | 57 | static struct platform_device ramoops_dev = { | 
 | 58 |         .name = "ramoops", | 
 | 59 |         .dev = { | 
 | 60 |                 .platform_data = &ramoops_data, | 
 | 61 |         }, | 
 | 62 | }; | 
 | 63 |  | 
 | 64 | [... inside a function ...] | 
 | 65 | int ret; | 
 | 66 |  | 
 | 67 | ret = platform_device_register(&ramoops_dev); | 
 | 68 | if (ret) { | 
 | 69 | 	printk(KERN_ERR "unable to register platform device\n"); | 
 | 70 | 	return ret; | 
 | 71 | } | 
 | 72 |  | 
 | 73 | 3. Dump format | 
 | 74 |  | 
 | 75 | The data dump begins with a header, currently defined as "====" followed by a | 
 | 76 | timestamp and a new line. The dump then continues with the actual data. | 
 | 77 |  | 
 | 78 | 4. Reading the data | 
 | 79 |  | 
| Kees Cook | 9ba80d9 | 2012-05-03 15:45:02 +1000 | [diff] [blame] | 80 | The dump data can be read from the pstore filesystem. The format for these | 
 | 81 | files is "dmesg-ramoops-N", where N is the record number in memory. To delete | 
 | 82 | a stored record from RAM, simply unlink the respective pstore file. |