> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimize Boot time

Qualcomm<sup>®</sup> Linux kernel boot time spans from the first kernel log message to the first responsive user-space process. Reducing it requires profiling initcall overhead, enabling asynchronous driver probe, and eliminating unused compiled-in subsystems.

## **Measure boot time**

Establish a baseline measurement before optimizing.

### Add initcall\_debug

Add `initcall_debug` to the kernel command line. The kernel prints a timestamped entry for every initcall and its duration:

```text theme={null}
[    1.243718] calling  clk_init+0x0/0x48 @ 1
[    1.243851] initcall clk_init+0x0/0x48 returned 0 after 127 usecs
```

Sort the slowest initcalls:

```bash theme={null}
dmesg | grep "initcall.*after" \
      | sed 's/.*initcall \(.*\) returned.* after \([0-9]*\) usecs/\2 \1/' \
      | sort -rn | head -20
```

Generate a boot timeline SVG using `scripts/bootgraph.pl` from the kernel source tree:

```bash theme={null}
dmesg | perl scripts/bootgraph.pl > boot.svg
```

### Configure printk.time

Add `printk.time=1 loglevel=4` to the kernel command line. This attaches microsecond timestamps to every printk message while suppressing informational output. On slow UARTs, this can reduce serial console overhead by 200–500 ms.

### Run systemd-analyze

On systems running systemd, run after boot to see time spent in kernel, initrd, and user-space phases:

```bash theme={null}
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain
```

## **Enable asynchronous probe**

By default, the kernel probes platform devices sequentially. On Qualcomm SoCs, the probe chain for a single subsystem such as camera or display may involve dozens of dependent drivers running in series. Asynchronous probe allows independent drivers to probe in parallel across kernel threads.

### Enable Kconfig

```text theme={null}
CONFIG_ASYNC_PROBE=y
```

### Enable per driver

Drivers enable this feature by setting `probe_type` in the `driver` structure:

```c theme={null}
static struct platform_driver my_driver = {
    .driver = {
        .name           = "my-device",
        .of_match_table = my_dt_match,
        .probe_type     = PROBE_PREFER_ASYNCHRONOUS,
    },
    .probe  = my_probe,
    .remove = my_remove,
}
```

### Enable via kernel command line

Force any driver to use asynchronous probing without modifying the source code
by using the driver\_async\_probe parameter. Separate multiple driver names with
commas.

```bash theme={null}
driver_async_probe=qcom-smmu,qcom-cpufreq-hw,qcom-icc-bwmon
```

### Configure deferred probe timeout

When a driver returns -EPROBE\_DEFER because a dependency is not yet available,
the kernel retries the probe. Set deferred\_probe\_timeout (in seconds) to emit a
warning and continue booting if the device never resolves.

```bash theme={null}
deferred_probe_timeout=10
```

To inspect pending deferred devices at runtime, use the following command:

```bash theme={null}
cat /sys/kernel/debug/devices_deferred
```

<Warning>
  Do not set `deferred_probe_timeout` to a value lower than the time required for
  slow firmware loads (such as modem, DSP, and WPSS subsystems). Setting it too
  low can cause the platform to boot with missing peripherals.
</Warning>

## **Disable unused subsystems**

Unused compiled-in drivers add initcall overhead, even when the hardware is not
present. Review the following Kconfig symbols for your target board and disable
any drivers not listed in the bill of materials (BOM).

**Table: Kconfig symbols to review for boot time**

| Symbol                | Notes                                                                                                                                                     |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CONFIG_USB_XHCI_HCD` | Disable if no USB 3.0 host controller is present on the BOM.                                                                                              |
| `CONFIG_SOUND`        | Disable the entire ALSA (Advanced Linux Sound Architecture) tree if audio is handled by DSP firmware only.                                                |
| `CONFIG_DRM_*`        | Disable display subsystems not populated such as HDMI (High-Definition Multimedia Interface), eDP (Embedded DisplayPort), DSI (Display Serial Interface). |
| `CONFIG_CRYPTO_*`     | Disable unused cipher suites; retain hardware crypto engine drivers.                                                                                      |
| `CONFIG_NETFILTER`    | Disable if no iptables or nftables support is required.                                                                                                   |
| `CONFIG_BT`           | Disable if Bluetooth<sup>®</sup> is fully handled inside the WLAN co-processor firmware.                                                                  |
| `CONFIG_NFS_FS`       | Disable if network file systems are not used.                                                                                                             |
| `CONFIG_DEBUG_*`      | Disable all debug Kconfig symbols in production builds.                                                                                                   |
| `CONFIG_KALLSYMS`     | Consider disabling for shipping images to reduce image size and boot time.                                                                                |
| `CONFIG_KPROBES`      | Disable in production; adds a per-function trampoline overhead.                                                                                           |

Use a board-specific configuration fragment rather than editing `defconfig` directly. In the Yocto workflow, add a `.cfg` fragment to the kernel `bbappend`:

```text theme={null}
# <layer>/recipes-kernel/linux/linux-qcom-base_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += "file://disable-unused.cfg"
```

Example contents of `disable-unused.cfg`:

```text theme={null}
# CONFIG_SOUND is not set
# CONFIG_USB_XHCI_HCD is not set
```

## **Optimize initramfs**

The initramfs is decompressed and executed before the root file system mounts. A large initramfs adds both decompression time and storage I/O overhead.

### Select a fast compression algorithm

On Cortex-A55 and Cortex-A78 cores, LZ4 decompresses much faster than gzip, but
it produces a slightly larger image size:

```text theme={null}
CONFIG_RD_LZ4=y
# CONFIG_RD_GZIP is not set
# CONFIG_RD_XZ is not set
```

### Reduce the package set

Edit `meta-qcom/recipes-kernel/images/initramfs-qcom-image.bb` to remove packages not required during early boot. Remove `initramfs-module-copy-modules` if all required drivers are compiled in (set to `=y` rather than `=m`).

Ensure all initramfs binaries are stripped by setting the following in the Yocto configuration:

```text theme={null}
INHIBIT_PACKAGE_STRIP = "0"
```

## **Optimize Qualcomm remoteproc firmware loading**

On QCS6490, IQ-9075, and related SoCs, the aDSP, cDSP, and WPSS subsystems load their firmware during `device_initcall` via the `qcom_q6v5_pas` driver. Each image is authenticated by TrustZone before the subsystem starts. The combined load time for all subsystems can exceed two seconds.

If any firmware file is missing from `/lib/firmware`, the `request_firmware()` call times out after 60 seconds per subsystem, stalling boot entirely. Verify the firmware is staged correctly:

```bash theme={null}
ls /lib/firmware/qcom/qcs6490/
# Expected: adsp.mdt, cdsp.mdt, wpss.mdt (and associated .bNN segments)
```

If WLAN or audio are not required during early boot, disable the corresponding remoteproc in the board device tree overlay and start it from user space after the critical path completes:

```text theme={null}
/* In board DTS overlay */
&remoteproc_wpss {
    status = "disabled";
};
```

Start it from user space when ready:

```bash theme={null}
echo start > /sys/class/remoteproc/remoteproc2/state
```

For remoteproc driver configuration details, see [Configure the RemoteProcessor (remoteproc) subsystems](./configure-the-remoteprocessor-remoteproc-subsystems).

## **Kernel command line quick reference**

The following parameters have a measurable impact on boot time:

**Table: Boot-time kernel command line parameters**

| Parameter                    | Effect                                                                                     |
| ---------------------------- | ------------------------------------------------------------------------------------------ |
| `quiet`                      | Suppresses most kernel log messages; reduces serial I/O on slow UARTs by 200–500 ms.       |
| `loglevel=0`                 | Silences all printk output below `KERN_EMERG`. Use with `quiet` for maximum suppression.   |
| `initcall_debug`             | Enables per-initcall timing. Use only for profiling, not production builds.                |
| `driver_async_probe=<list>`  | Forces listed drivers into async probe mode.                                               |
| `deferred_probe_timeout=<s>` | Continues boot after this many seconds if deferred devices do not resolve.                 |
| `cma=<size>`                 | Reduces CMA reservation when DSP or camera memory requirements are lower than the default. |
| `audit=0`                    | Disables the Linux audit subsystem; reduces syscall overhead.                              |
