# SPDX-License-Identifier: LicenseRef-SierraWireless-Proprietary
# SPDX-FileCopyrightText: 2026 Sierra Wireless, Inc.
RAM Dump Tool
---------------------
This tool supports the capturing of the device RAM contents when the device is in memory dump mode. RAM contents are saved in files written to the directory
specified by the command line argument


*******************************
ramdump static lib compilation
*******************************
- By default, the ramdump static lib is compiled for i386 Linux platform.
  "make -f LibMakefile"

- The ramdump static lib can be compiled for different platform using the CPU option:
  "make -f LibMakefile CPU=<platform>"
  where <platform> = win32 in case of compiling with Cygwin on Windows
                     arm9  in case of ARM and
                     ppc   in case of Power PC.

- For arm9, powerpc, and mips, platform specific tool chains are required. These must be
  installed to the $(HOME) directory once, and can be used for all SDK workspaces.
  If they do not exist, 
  "make  -f LibMakefile CPU=arm9",
  "make  -f LibMakefile CPU=mips",
  "make  -f LibMakefile CPU=mipsel", and
  "make  -f LibMakefile CPU=ppc"  will simply fail

- Upon successful compilation, the library libram-dump$(CPU).a will be generated.

*********************************************************
Building the Ramdump Application with the Static Library
*********************************************************
- Ensure the static library is present in the bin/ directory.

- Build the Application:
  Navigate to the directory containing the Makefile.
    make
  This will check for the static library and compile the source code.

- Clean Up:
  To remove build artifacts, run:
    make clean

- Note : This Makefile is a sample. Modify it as needed for specific platform and toolchain.
- Note : ramdump is built with PIE (Position Independent Executable) enabled by default. 
To build with it disabled, run the make with "NOPIE=1".

*********************************************************
ramdump application compilation using ramdump static lib
*********************************************************
- The ramdump static library currently exposes the following function via ramdump.h
  * \param argc The number of command-line arguments.
  * \param argv An array of strings representing the command-line arguments.
  *
  * \return Returns 0 if the RAM dump collection is successful, or a non-zero value if an error occurs.
  int ramdump_collect(int argc, const char *argv[]);

- To use ramdump_collect in an application (e.g., ramdump application), include this function along with the ramdump static library.
  for example, the following:
    int main( int argc, const char *argv[])
    { 
      // Example command line arguments
      const char *example_argv[] = {
        "ramdumptool",
        "-c", "0",
        "-o", "./",
        "-noreset",
        "-s"
      };

      // Call the function with example arguments
      ramdump_collect(sizeof(example_argv) / sizeof(example_argv[0]), example_argv);
    }
  (Note: user can pass the arguments as mentioned in Execution section below )
- By default, the ramdump is compiled for i386 Linux platform.
  "make ramdump"

- The application can be compiled for different platform using the CPU option:
  "make ramdump CPU=<platform>"
  where <platform> = win32 in case of compiling with Cygwin on Windows
                     arm9  in case of ARM and
                     ppc   in case of Power PC.

- For arm9, powerpc, and mips, platform specific tool chains are required. These must be
  installed to the $(HOME) directory once, and can be used for all SDK workspaces.
  If they do not exist, 
  "make ramdump CPU=arm9",
  "make ramdump CPU=mips",
  "make ramdump CPU=mipsel", and
  "make ramdump CPU=ppc"  will simply fail.

- Upon successful compilation, the application ramdump_$(CPU) will be generated.

Note on armv7l platforms (e.g. Raspberry Pi as reference):
  - Build via release/scripts: Use bin/ramdump_rpi (pre-built from MBPL package).
  - Local build (make ramdump without CPU=): Produces bin/ramdump_hostarmv7l. Use this
    binary when building manually on an armv7l host. "make clean" removes it
    (intended behavior). Run "make ramdump" to regenerate.

*******************
 Prior to Execution
*******************
1. Enter the following AT commands:
    at!entercnd="A710"
    at!eroption=0

2. Either reproduce a crash you are investigating, or reset the device

**********
Execution
**********
Within a shell, execute the following (for i386):
   ./ramdump_i386 [-d <device>] [-c <comport>] [-o <output directory>] [-noreset] [-s]

  -d <device>
       Optionally specify device type. i.e -d 9x30.
  -c <comport>
       Optional parameter to specify the DM port, example: -c 3 for COM3 on Windows
       or -c 0 for /dev/ttyUSB0 on Linux
  -pcie
       Optional parameter for using /dev/mhiqdl* pcie channel to collect crash dump.
  -o <output_directory>
       Optional parameter to specify where to store the crash dump.
       If this is not specified, '<current dir>/MemDumpOut' will be used as default
  -noreset
       Optional Parameter to not reset the device after collecting a crash dump
  -s
       Collect crash summary. Only works with devices that support custom Sahara commands.
  -h
       Display this help menu

/dev/ttyUSB<digit> = DM interface ttyUSB device file in boot and hold mode (usually /dev/ttyUSB0)
/dev/mhiqdl<digit> = DM interface mhi device file(PCIe channel) in boot and hold mode (usually /dev/mhiqdl0)

-----
NOTE 1:
-----
  To execute the program in Windows shell command prompt, cygwin dll path needs to be added to Windows environment variable.

-----
NOTE 2:
-----
When running ramdumptool_i386 on Ubuntu, ramdumptool may exit and prompt message 
"
DM port not detected
Failed to open port
Could not find DM port
"
That means the DM port (/dev/ttyUSBx) is not created, user can add new Id as follow.

user@Ubuntu:~$ lsusb | grep Sierra
Bus 003 Device 035: ID 1199:9100 Sierra Wireless, Inc. 
user@Ubuntu:~$ 
user@Ubuntu:~$ sudo echo 1199 9100 > /sys/bus/usb-serial/drivers/generic/new_id 
user@Ubuntu:~$


************
Logging
************
The RAM Dump Tool library integrates a logging mechanism to track and manage log messages during execution.

This library provides customizable logging functions to enhance debugging and monitoring.
eLOG_LEVEL: Defines logging levels (DEBUG, INFO, WARN, ERROR).

Functions:
- ramdump_log_func_t: A function pointer type that defines a custom logging function. 
  It accepts a log level (uint8_t lvl) and a formatted message string (const char* fmt, ...).
- set_ramdump_logger_func(ramdump_log_func_t func):
  Sets a custom logger function to handle messages at specified log levels.
- get_ramdump_logger_func():
  Retrieves the currently set logger function.

Refer: ramdump.h for more information

*****************************
Progress Callback Function
*****************************
The RAM Dump Tool library integrates progress_callback function whcih is used to report progress updates during operations like RAM dump collection.

- Callback Type:
 ramdump_progress_callback_func_t:
 A function pointer type that accepts an integer parameter representing the progress percentage (int progress).

- Function:
set_ramdump_progress_callback_func(ramdump_progress_callback_func_t callback):
 Registers a custom callback function to receive progress updates during operations, such as RAM dump collection.

This function allows user to set the custom function to handle progress notifications.

Refer: ramdump.h for more information

************
Known Issues
************
1.
  On Linux, device sometimes does not reset when -noreset option is not specified. This has not been seen on Windows
2.
  The DM port detection logic on Linux relies on 'udevadm' and is rather simple and has not been tested for more complicated setup.
3.
  The application has not been compiled and tested for arm9 and ppc target.
4.
  When using the ramdump tool on a Linux platform, ensure that the minicom session is closed if it was used to send the firmware 
  crash command (e.g., AT!ERTEST=1,2) to put the modem into boot and hold mode. This is necessary because /dev/ttyUSB0 is utilized by the QDLoader.
5.
  The creation of the static library and its integration with an application has only been tested on the Linux platform.
 

