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

# IQ9 EVK as a Local Arm Build & Debug Machine for Mainline Linux Kernel

> Setup an IQ9-EVK for Local Arm Developement and Kernel Builds.

<div
  style={{
width: "100%",
borderRadius: "14px",
overflow: "hidden",
backgroundImage: "url('https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-staging/images/tutorials/my-post-hero.png')",
backgroundSize: "cover",
backgroundPosition: "center",
height: "260px",
display: "flex",
alignItems: "center",
justifyContent: "center",
position: "relative",
marginBottom: "1.5rem"
}}
>
  <div
    style={{
position: "absolute",
bottom: "16px",
left: "50%",
transform: "translateX(-50%)",
background: "rgba(255,255,255,0.15)",
border: "1px solid rgba(255,255,255,0.4)",
color: "#fff",
fontSize: "0.75rem",
fontWeight: 700,
letterSpacing: "1px",
padding: "5px 14px",
borderRadius: "20px",
textTransform: "uppercase",
whiteSpace: "nowrap",
zIndex: 1
}}
  >
    Dragonwing · Qualcomm
  </div>
</div>

<div style={{ marginBottom: "2rem" }}>
  <div
    style={{
fontSize: "0.72rem",
fontWeight: 700,
color: "#31017D",
letterSpacing: "1.5px",
textTransform: "uppercase",
marginBottom: "0.5rem"
}}
  >
    Category
  </div>

  <p style={{ fontSize: "0.95rem", color: "#555", lineHeight: 1.7, margin: "0 0 0.75rem" }}>
    Short deck for the post. Keep this aligned with the card summary on the tutorials landing page.
  </p>

  <div style={{ fontSize: "0.85rem", color: "#888", display: "flex", gap: "0.5rem", flexWrap: "wrap", alignItems: "center" }}>
    <span>Author or team</span>
    <span>·</span>
    <span>Month DD, YYYY</span>
    <span>·</span>
    <a href="/tutorial" style={{ color: "#31017D", fontWeight: 600, textDecoration: "none" }}>← All posts</a>
  </div>
</div>

<hr style={{ border: "none", borderTop: "1px solid #eee", margin: "0 0 2rem" }} />

## Introduction

The IQ9 EVK packs 8 Cortex-A78 cores at 1.9 GHz, 12 GB RAM, and 110 GB storage — powered by a single USB-C cable and easy to carry around. I was short of a local ARM build machine, and the IQ9 EVK was right there. So why not?

This blog covers two things:

1. **Local ARM build** — using the IQ9 EVK itself as the ARM native build machine for mainline kernel
2. **Mainline kernel debugging** — more importantly, the board runs what it builds, making it a self-contained platform for mainline kernel bring-up and debugging

## 1. Local ARM Build on IQ9 EVK

The IQ9 EVK ships with Qualcomm Linux (QLI 2.0) — a Yocto-based image designed for running prebuilt apps. It's locked down by design: no `apt-get`, no `opkg`.

```bash theme={null}
$ cat /etc/issue
Qualcomm Linux Reference Distro (OTA-enabled) 2.0 \n \l

$ apt-get update
sh: apt-get: command not found

$ opkg --version
sh: opkg: command not found
```

To get a proper build environment, flash Ubuntu using [Flash Using Qualcomm Launcher](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq9075-evk/update-software/flash-using-qualcomm-launcher)

```
$ cat /etc/issue
Ubuntu 24.04.4 LTS \n \l
```

Install build dependencies:

```
sudo apt update && sudo apt upgrade -y

sudo apt install -y \
    flex bison bc \
    build-essential \
    libssl-dev libelf-dev \
    libncurses-dev \
    git make gcc \
    kmod cpio rsync \
    python3 perl
```

Clone and build mainline kernel natively on the board:

```
git clone -b main https://github.com/qualcomm-linux/kernel-topics.git
make defconfig
make -j8
```

With 8 cores and 12 GB RAM, the build runs comfortably on the board itself — no cross-compilation needed.

## 2. Mainline Kernel Debugging on IQ9 EVK

We only have one IQ9 EVK — no backup machine, no second board. The goal: debug mainline kernel without bricking the board, with a clean fallback to the release Ubuntu image.

### What we tried (and why it didn't work)

**a. kexec** — the IQ9 watchdog kicks in and forces a reboot before the debug kernel can fully boot.

**b. fastboot boot** — not supported on IQ9 yet, and requires a separate host machine anyway.

**c. GRUB menu with concatenated kernel + DTB** — DTB couldn't be passed through correctly this way.

### What worked: custom GRUB menu entry

Add a new GRUB entry pointing to the debug kernel and DTB:

```bash theme={null}
# refer to /boot/grub/grub.cfg for the template
sudo vi /etc/grub.d/40_custom
```

```bash theme={null}
menuentry 'Ubuntu_debug' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-debug' {
        recordfail
        load_video
        gfxmode $linux_gfx_mode
        insmod gzio
        if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
        insmod part_gpt
        insmod ext2
        set root='hd0,gpt3'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt3 --hint-efi=hd0,gpt3 --hint-baremetal=ahci0,gpt3  c5de3ef5-e2b1-47ae-a2eb-34267d2d1441
        else
          search --no-floppy --fs-uuid --set=root c5de3ef5-e2b1-47ae-a2eb-34267d2d1441
        fi
        linux   /boot/Image dtb=/lemans-evk.dtb root=UUID=c5de3ef5-e2b1-47ae-a2eb-34267d2d1441 ro console=ttyMSM0,115200n8 pcie_pme=nomsi earlycon video=LVDS-1:d
        initrd  /boot/initramfs.cpio.gz
}
```

```bash theme={null}
sudo update-grub
```

Deploy the build artifacts:

```bash theme={null}
cd kernel-nord
# initramfs.cpio.gz must include the compiled kernel modules for this kernel build
sudo cp initramfs.cpio.gz /boot/
sudo cp arch/arm64/boot/dts/qcom/lemans-evk.dtb /boot/efi/
sudo cp arch/arm64/boot/Image /boot/

sudo reboot
```

At boot, when the console shows:

```
The highlighted entry will be executed automatically in 3s.
```

Select `*Ubuntu_debug` to boot into the mainline kernel.

### Verify

```bash theme={null}
$ uname -a
Linux qcom-armv8a 7.2.0-rc5-gf5098b6bae76 #1 SMP PREEMPT Fri Jul 31 07:31:15 UTC 2026 aarch64 GNU/Linux

$ mount /dev/sda3 /mnt
[   46.588831] EXT4-fs (sda3): mounted filesystem c5de3ef5-e2b1-47ae-a2eb-34267d2d1441 r/w with ordered data mode.

$ ls /mnt/home/ubuntu/
kernel-nord
```

Mainline kernel 7.2-rc5 is up and running. The release Ubuntu entry remains intact in GRUB — if anything goes wrong, just reboot and select the default entry. No bricks. 🎉

On the next reboot, GRUB defaults back to the release Ubuntu image automatically — no manual intervention needed. This gives us a safe, repeatable loop:

* Boot into `Ubuntu_debug` to test mainline kernel
* Reboot → back to stable release automatically
* Iterate, fix, repeat

This workflow makes it straightforward to debug the latest mainline kernel and send patches. For example, one of the first things I caught: **reboot doesn't work on mainline kernel for IQ9** — a quick find, thanks to a clean and low-risk debug environment.

Enjoy! 🚀
