> ## 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.

# 不使用 Yocto 构建内核

独立（standalone）工作流让您无需构建完整的 Yocto 镜像即可编译、测试和部署内核更改。
所有必需的交叉编译和镜像打包工具都捆绑在 `kmake-image` Docker 容器中。

## 限制和注意事项

<Warning>
  独立工作流仅构建和打包内核及模块。它不会生成根文件系统。若要构建或修改
  依赖完整 Yocto BSP 的树外（out-of-tree）内核模块，请改用基于 Yocto 的
  工作流。
</Warning>

* **工具链**：`kmake-image` Docker 镜像提供 `aarch64` 交叉工具链、
  `systemd ukify` 以及镜像打包脚本。无需在主机上安装工具链。
* **DTB 打包**：独立构建时，您必须使用来自
  [qcom-dtb-metadata](https://github.com/qualcomm-linux/qcom-dtb-metadata) 仓库的
  静态 ITS 配置手动打包 DTB。Yocto 构建通过 `meta-qcom` 自动处理此步骤。

## 获取内核源码

直接克隆内核仓库：

```bash theme={null}
git clone --branch qcom-6.18.y \
    https://github.com/qualcomm-linux/kernel.git kernel
```

**表：内核分支**

| 分支 | 使用场景 |
| - | - |
| `qcom-6.18.y` | LTS 生产构建；推荐用于 SoC 启用和集成 |
| `qcom-next` | 向上游贡献以及针对最新内核进行验证 |

### 检出确切的内核源码修订版本

检出分支会跟随该分支上的最新提交。为了实现可复现的独立验证，请检出所需分支，
并使用构建目标镜像的 `meta-qcom` 发布标签中的内核 `SRCREV`。

在该发布标签处克隆 `meta-qcom`，并检查 LTS 内核 recipe：

```bash theme={null}
git clone --branch <release-tag> --depth 1 \
    https://github.com/qualcomm-linux/meta-qcom.git meta-qcom

grep -E '^(SRCREV|SRCBRANCH)' \
    meta-qcom/recipes-kernel/linux/linux-qcom_6.18.bb
```

发布标签遵循 `qli-<version>` 命名约定。请使用被测镜像的发行说明中指定的标签，
并从该标签获取 `SRCREV`。不要使用 `master` 分支，因为它可能引用更新的内核修订版本。

从 recipe 中复制完整的 40 个字符的 `SRCREV` 值，然后在内核克隆中检出对应的提交：

```bash theme={null}
SRCREV="<40-character-SRCREV-from-recipe>"
git -C kernel checkout --detach "${SRCREV}"
git -C kernel rev-parse HEAD
```

构建之前，请确认 `git rev-parse HEAD` 输出的值与 `SRCREV` 完全一致。对于
`qcom-next` 构建，请改用 `meta-qcom/recipes-kernel/linux/linux-qcom-next_git.bb`
并克隆 `qcom-next` 内核分支。

## 设置 Docker 工具链

### 选项 1：拉取预构建镜像（推荐）

首选方法是从镜像仓库拉取预构建的 `kmake-image`：

```bash theme={null}
docker pull artifacts.codelinaro.org/clo-420-qli-registry/kmake-image:ver.1.0
docker tag artifacts.codelinaro.org/clo-420-qli-registry/kmake-image:ver.1.0 kmake-image
```

<Note>
  除非您计划为 kmake-image Docker 镜像做贡献，否则请拉取托管的镜像。
  这种方法可以避免因网络连接或容器镜像仓库访问问题导致的 Docker 构建失败。
</Note>

### 选项 2：在本地构建镜像

仅当需要开发或自定义 kmake-image 容器时，才在本地克隆并构建它：

```bash theme={null}
git clone https://github.com/qualcomm-linux/kmake-image.git
cd kmake-image
docker build --build-arg USER_ID=$(id -u) \
             --build-arg GROUP_ID=$(id -g) \
             --build-arg USER_NAME=$(whoami) \
             -t kmake-image .
cd ..
```

<Warning>
  如果在 Docker 构建期间遇到 "failed to resolve source metadata" 错误，
  请参阅[排查 Docker 构建失败问题](#troubleshooting-docker-build-failures)。
</Warning>

### 设置 shell 别名

为方便起见，设置 shell 别名。将以下内容添加到您的 shell 配置文件中，
以便在多个会话间保持有效：

```bash theme={null}
alias kmake-image-run='docker run -it --rm \
  --user $(id -u):$(id -g) \
  --workdir="$PWD" \
  -v "$(dirname $PWD)":"$(dirname $PWD)" \
  kmake-image'
alias kmake='kmake-image-run make'
```

## 收集构建工件

创建一个 `artifacts/` 目录，用于存放组装最终镜像所需的 ramdisk、启动
二进制文件和 DTB 元数据：

```bash theme={null}
mkdir artifacts
```

**获取 initramfs ramdisk**

```bash theme={null}
wget -O artifacts/ramdisk.gz \
    http://storage.kernelci.org/images/rootfs/buildroot/buildroot-baseline/20230703.0/arm64/rootfs.cpio.gz
```

**获取 systemd-boot 二进制文件**

```bash theme={null}
wget -O artifacts/systemd-boot-efi.deb \
    http://ports.ubuntu.com/pool/universe/s/systemd/systemd-boot-efi_255.4-1ubuntu8_arm64.deb
dpkg-deb -xv artifacts/systemd-boot-efi.deb artifacts/systemd
```

**获取 DTB 元数据**

独立构建时，必须使用静态 ITS 配置手动打包 DTB。克隆 `qcom-dtb-metadata`
仓库以获取所需的 `qcom-metadata.dts` 和 `qcom-next-fitimage.its` 文件：

```bash theme={null}
git clone https://github.com/qualcomm-linux/qcom-dtb-metadata.git \
    artifacts/qcom-dtb-metadata
```

## 构建内核和模块

使用标准的 Qualcomm<sup>®</sup> 配置片段来配置并构建内核，然后将模块
安装到暂存目录中：

```bash theme={null}
cd kernel
mkdir -p ../kobj

env -u KCONFIG_CONFIG ./scripts/kconfig/merge_config.sh -m -O ../kobj \
    arch/arm64/configs/defconfig \
    arch/arm64/configs/prune.config \
    arch/arm64/configs/qcom.config

kmake O=../kobj olddefconfig
kmake O=../kobj -j$(nproc)
kmake O=../kobj -j$(nproc) dir-pkg INSTALL_MOD_STRIP=1
```

将构建好的内核模块（DLKM）打包进 ramdisk：

```bash theme={null}
(cd ../kobj/tar-install ; \
 find lib/modules | cpio -o -H newc -R +0:+0 | gzip -9 >> ../../artifacts/ramdisk.gz)
```

## 打包启动镜像

**生成 `efi.bin`（ESP 分区）**

`efi.bin` 镜像包含 systemd-boot、内核（打包为 UKI type-2 镜像）以及
initramfs：

```bash theme={null}
cd ..
# Default command line matches the Yocto UKI_CMDLINE from esp-qcom-image.bb.
# Override CMDLINE if your rootfs partition label or console differs.
CMDLINE="root=PARTLABEL=rootfs rw rootwait console=ttyMSM0,115200"
kmake-image-run generate_boot_bins.sh efi \
    --ramdisk artifacts/ramdisk.gz \
    --systemd-boot artifacts/systemd/usr/lib/systemd/boot/efi/systemd-bootaa64.efi \
    --stub artifacts/systemd/usr/lib/systemd/boot/efi/linuxaa64.efi.stub \
    --linux kobj/arch/arm64/boot/Image \
    --cmdline "${CMDLINE}" \
    --output images
```

**生成 `dtb.bin`（DTB 分区）**

为所有支持设备树的目标构建基于 FIT 的 `dtb.bin`：

```bash theme={null}
kmake-image-run make_fitimage.sh \
    --metadata artifacts/qcom-dtb-metadata/qcom-metadata.dts \
    --its artifacts/qcom-dtb-metadata/qcom-next-fitimage.its \
    --kobj kobj \
    --output images
```

`efi.bin` 和 `dtb.bin` 都会被放置在 `images/` 目录中，可直接烧写。

## 内核镜像构建脚本

Docker 镜像包含一个 `build.sh` 脚本，它封装了上述构建和打包步骤，并生成
`efi.bin`、`dtb.bin` 和 `boot.img`。

将 `--dtb` 设置为验证目标对应的 DTB。对于 IQ-9075 EVK，请运行：

```bash theme={null}
kmake-image-run build.sh --dtb lemans-evk.dtb \
        --out kobj \
        --systemd artifacts/systemd/usr/lib/systemd/boot/efi \
        --ramdisk artifacts/ramdisk.gz \
        --images images \
        --cmdline "${CMDLINE}"
```

<Note>
  * `--dtb` 参数指定要打包到目标专用镜像中的设备树 Blob（Device Tree Blob）。
    请选择与目标设备匹配的 DTB。
  * 初始化 `CMDLINE` 以设置您的内核命令行参数；否则将使用通用默认命令行。
</Note>

## 排查 Docker 构建失败问题

如果 Docker 构建失败并出现 "failed to resolve source metadata" 错误：

1. **使用预构建镜像（推荐）**

   有关说明，请参阅[选项 1：拉取预构建镜像](#option-1-pull-the-pre-built-image-recommended)。

2. **检查防火墙和网络访问**

   验证您的网络是否允许访问 Docker 镜像仓库：

   ```bash theme={null}
   # Test connectivity to Docker Hub
   curl -I https://registry-1.docker.io

   # Test connectivity to Codelinaro registry
   curl -I https://artifacts.codelinaro.org
   ```

   如果上述命令失败，请联系您的网络管理员，允许到 Docker 镜像仓库的出站 HTTPS 连接。

3. **向构建传递代理设置**

   ```bash theme={null}
   docker build --build-arg HTTP_PROXY=$http_proxy \
                --build-arg HTTPS_PROXY=$https_proxy \
                --build-arg USER_ID=$(id -u) \
                --build-arg GROUP_ID=$(id -g) \
                --build-arg USER_NAME=$(whoami) \
                -t kmake-image .
   ```

## 烧写和启动

将设备置于 fastboot 模式，然后烧写两个镜像：

```bash theme={null}
fastboot flash efi images/efi.bin
fastboot flash dtb_a images/dtb.bin
fastboot reboot
```

设备重启后，请按照
[安装和启动内核](./install-and-boot-the-kernel#verify-the-running-kernel)
中所述验证正在运行的内核版本。
