内核编译与更新

概述

本文档介绍如何编译 Quectel Pi H1 的 Linux 内核、打包内核镜像以及更新到设备的完整流程。Quectel Pi H1 使用基于 Yocto 的构建系统,采用 Qualcomm 定制的 Linux 内核(基于 Linux 6.6)。

内核 Recipes 说明

Qualcomm Linux 的内核 recipes 位于 /layers/meta-qcom-hwe/recipes-kernel/linux 目录,该层提供两种内核方案:

Recipes 文件 内核类型 源码来源 说明
linux-qcom-custom_6.6.bb Custom BSP git.codelinaro.org 高通定制内核(当前使用)
linux-qcom-base_6.6.bb Base BSP git.kernel.org 标准内核

当前使用:Custom 内核源码方案

目录结构

内核相关文件主要分为两个目录:

qcm6490-idp/
├── kernel-source/               # 内核源码目录
└── kernel-build-artifacts/      # 构建产物目录

kernel-source/ 目录

存放 Linux 内核的完整源码,包括:

  • 内核核心代码(arch/, drivers/, fs/, net/ 等)
  • 设备树源文件(.dts/.dtsi,描述硬件配置)
  • 内核配置文件(Kconfig
  • 编译脚本(Makefile

源码目录详解

内核源码目录结构

目录/文件 说明 目录/文件 说明
arch 架构相关代码(ARM64、x86 等) scripts 编译和配置脚本
block 块设备子系统 security 安全框架(SELinux、AppArmor 等)
certs 内核证书和签名 sound 音频子系统(ALSA)
crypto 加密 API 和算法 tools 内核相关工具
Documentation 内核文档 usr initramfs 生成相关
drivers 设备驱动程序 virt 虚拟化支持(KVM)
fs 文件系统实现 rust Rust 语言支持
include 内核头文件 Makefile 主编译文件
init 内核初始化代码 Kbuild 内核构建系统配置
ipc 进程间通信机制 Kconfig 内核配置界面定义
kernel 内核核心功能(调度器、进程管理等) MAINTAINERS 维护者名单
lib 通用库函数 CREDITS 贡献者列表
mm 内存管理子系统 COPYING 版权声明(GPL)
net 网络协议栈
samples 内核编程示例代码

kernel-build-artifacts/ 目录

存放内核编译后的构建产物,包括:

  • 内核镜像文件Image(未压缩)或 Image.gz(压缩版)
  • 设备树二进制文件.dtb 文件(由 .dts 编译生成)
  • 内核模块.ko 文件(可加载的驱动模块)
  • 配置文件.configbuild.log

编译内核

1. 配置编译环境

进入代码工作目录,执行以下命令配置编译环境:

source quectel_build/compile/build.sh

2. 执行编译

使用 Yocto 的 bitbake 命令编译内核:

bitbake linux-qcom-custom

3. 编译产物路径

编译完成后,内核镜像生成在以下位置:

临时工作目录

build-qcom-wayland/tmp-glibc/work/qcm6490_idp-qcom-linux/linux-qcom-custom/6.6/deploy-linux-qcom-custom

最终部署目录(Yocto 自动复制):

build-qcom-wayland/tmp-glibc/deploy/images/qcm6490-idp/

编译产物目录

说明:Yocto 会自动将内核镜像从工作目录复制到部署目录,后续打包流程会从部署目录获取内核镜像。

编译时间参考

  • 首次编译:约 30-60 分钟(取决于硬件配置)
  • 增量编译:约 5-15 分钟

打包内核和设备树镜像

1. 安装 ukify 工具

首先安装打包所需的 Python 依赖:

sudo pip install pefile

2. 执行打包命令

运行以下命令打包内核镜像和设备树:

do_kernel_images

3. ukify 警告说明

执行打包过程中,会出现以下警告信息,可以忽略

Kernel version not specified, starting autodetection .
Real-Mode Kernel Header magic not found
+ readelf --notes {TOPDIR}/quectel_build/alpha/tools/pack/image_temp/Image
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
Found uname version: 6.6.52-qli-1.3-ver.1.1
Wrote unsigned ${TOPDIR}/quectel_build/alpha/tools/pack/image_temp/uki.efi

说明:这些警告是由于 ARM64 内核格式与 EFI 工具预期格式的差异导致,不影响最终镜像的正确性。

4. 获取打包镜像

打包完成后,从以下路径获取生成的镜像文件:

${TOPDIR}/quectel_build/alpha/output/pack/efi.bin

更新镜像到设备

方法一:通过调试串口进入 Fastboot

1. 进入 Fastboot 模式

选项 A - 通过串口命令

连接调试串口,在系统中执行:

reboot bootloader

选项 B - 通过 ADB 命令

确保设备已连接 USB 并启用 ADB 调试,执行:

adb shell
reboot bootloader

2. 验证 Fastboot 模式

设备进入 Fastboot 后,在主机上运行:

fastboot devices

应该能看到设备列表。

3. 烧写内核镜像

使用 fastboot 命令烧写新的内核镜像:

fastboot flash efi efi.bin

4. 重启设备

烧写完成后,重启设备:

fastboot reboot

方法二:自动化脚本(可选)

如果需要频繁更新内核,可以创建自动化脚本:

#!/bin/bash
# update_kernel.sh

# 检查 efi.bin 是否存在
if [ ! -f "quectel_build/alpha/output/pack/efi.bin" ]; then
    echo "错误:efi.bin 不存在,请先编译和打包内核"
    exit 1
fi

# 进入 Fastboot
adb reboot bootloader
sleep 5

# 等待 Fastboot 就绪
fastboot devices

# 烧写镜像
fastboot flash efi quectel_build/alpha/output/pack/efi.bin

# 重启
fastboot reboot

echo "内核更新完成!"

使用方法:

chmod +x update_kernel.sh
./update_kernel.sh

注意事项

  1. 备份重要数据:更新内核前请确保重要数据已备份
  2. 电源充足:烧写过程中请确保设备电量充足或连接电源
  3. USB 连接稳定:使用质量好的 USB 线缆,避免烧写中断
  4. 版本匹配:确保内核版本与系统其他组件兼容

常见问题

Q1: bitbake 编译失败?

可能原因

  • 磁盘空间不足
  • 网络连接问题
  • 依赖包缺失

解决方法

# 清理编译缓存
bitbake -c cleanall linux-qcom-custom
# 重新编译
bitbake linux-qcom-custom

Q2: fastboot devices 看不到设备?

解决方法

  • 检查 USB 驱动是否正确安装
  • 尝试更换 USB 端口或线缆
  • 确认设备已正确进入 Fastboot 模式(屏幕显示 Fastboot 字样)

Q3: 烧写后无法启动?

解决方法

  • 使用原厂镜像恢复系统
  • 检查编译过程是否有错误
  • 确认设备树配置是否正确

相关文档