高通学习24--XBL(TODO)

下次只需一条 wsl bash /mnt/d/tmp2/run_build10.sh。若环境被重置导致 wrapper 丢失,先跑 wsl bash /mnt/d/tmp2/install_armlink_v3.sh 再编译。

run_build10.s

bash 复制代码
#!/bin/bash
set -x
ROOT=/home/jc/ar1/aliso-la-1-0_amss_standard_oem/BOOT.MXF.2.2
PYBIN=/home/jc/py3bin
mkdir -p $PYBIN
if [ -e "$PYBIN/python" ] || [ -L "$PYBIN/python" ]; then rm -f "$PYBIN/python"; fi
ln -s /usr/bin/python3.8 "$PYBIN/python"
export PATH="$PYBIN:$PATH"
echo "python now resolves to: $(which python)"
python --version
cd $ROOT/boot_images
if [ ! -e /home/jc/bin/sectools ] && [ ! -L /home/jc/bin/sectools ]; then
  ln -s /home/jc/bin/sectools_wrapper /home/jc/bin/sectools
fi
ls -la /home/jc/bin/sectools
python -u boot_tools/buildex.py -t Aliso -v LAA -r RELEASE > /mnt/d/tmp2/xbl_build_run10.log 2>&1
echo "BUILD EXIT CODE: $?"

install_armlink_v3.sh

bash 复制代码
#!/bin/bash
# Install arm-link v3 (comment-aware ASSERT stripping) and verify against
# both GccBase.lds (multi-line comments, no ASSERT) and generated DevPrgD.ld
# (orphan trailing */ on ASSERT line + multi-line ASSERT).
set -e
BIN=/pkg/qct/software/llvm/release/arm/14.0.0/bin
SRC=/mnt/d/tmp2/new_arm-link_v3.sh
ROOT=/home/jc/ar1/aliso-la-1-0_amss_standard_oem/BOOT.MXF.2.2

echo "=== backup current arm-link as arm-link.bak.v2 ==="
if [ -f "$BIN/arm-link.bak.v2" ]; then
  echo "arm-link.bak.v2 already exists, overwriting"
fi
cp -f "$BIN/arm-link" "$BIN/arm-link.bak.v2"

echo "=== install v3 (strip CR from Windows drive copy) ==="
tr -d '\r' < "$SRC" > /tmp/arm-link.v3.lf
cp -f /tmp/arm-link.v3.lf "$BIN/arm-link"
chmod +x "$BIN/arm-link"

echo "=== verify line endings (must be ASCII text, LF only) ==="
file "$BIN/arm-link"
if grep -q $'\r' "$BIN/arm-link"; then
  echo "ERROR: CR still present in installed arm-link"
  exit 1
else
  echo "OK: no CR characters"
fi

echo "=== direct python test of v3 preprocess logic ==="
cat > /tmp/preprocess_v3.py <<'PYEOF'
import sys
src, dst = sys.argv[1], sys.argv[2]
out = []
in_comment = False
in_assert = False

def strip_trailing_comment_close(s):
    while s.rstrip().endswith('*/'):
        s = s.rstrip()[:-2].rstrip()
    return s

for ln in open(src, 'r').read().splitlines():
    s = ln
    if in_assert:
        out.append('/* stripped ASSERT cont: ' + s.strip() + ' */')
        code = strip_trailing_comment_close(s)
        if ');' in code:
            in_assert = False
        continue
    parts = []
    i = 0
    n = len(s)
    while i < n:
        if in_comment:
            j = s.find('*/', i)
            if j == -1:
                parts.append(('comment', s[i:]))
                i = n
            else:
                parts.append(('comment', s[i:j + 2]))
                i = j + 2
                in_comment = False
        else:
            j = s.find('/*', i)
            if j == -1:
                parts.append(('code', s[i:]))
                i = n
            else:
                parts.append(('code', s[i:j]))
                parts.append(('comment', s[j:j + 2]))
                i = j + 2
                in_comment = True
    code_str = ''.join(t for k, t in parts if k == 'code')
    comments_str = ''.join(t for k, t in parts if k == 'comment')
    if 'ASSERT' in code_str:
        code_c = strip_trailing_comment_close(code_str)
        out.append('/* stripped ASSERT: ' + code_c.strip() + ' */')
        if comments_str:
            out.append(comments_str)
        if not code_c.rstrip().endswith(');'):
            in_assert = True
        continue
    out.append(''.join(t for k, t in parts))

open(dst, 'w').write('\n'.join(out) + '\n')
PYEOF

echo "--- Test 1: GccBase.lds (multi-line comments) ---"
GCC=$ROOT/boot_images/edk2/BaseTools/Scripts/GccBase.lds
python3.8 /tmp/preprocess_v3.py "$GCC" /tmp/GccBase.v3.test.ld
sed -n '15,30p' /tmp/GccBase.v3.test.ld
echo "..."
echo "--- verify no stray directives / balanced comments ---"
grep -n 'stripped orphan\|unknown' /tmp/GccBase.v3.test.ld && echo "PROBLEM" || echo "OK: no orphan marks"

echo
echo "--- Test 2: generated DevPrgD.ld (ASSERT + orphan */) ---"
LD=$ROOT/boot_images/Build/AlisoLAA/DevprogD/RELEASE_CLANG140LINUX/AARCH64/DevPrgD.ld
python3.8 /tmp/preprocess_v3.py "$LD" /tmp/DevPrgD.v3.test.ld
echo "--- lines 44-66 ---"
sed -n '44,66p' /tmp/DevPrgD.v3.test.ld
echo
echo "--- check Image\$\\\$DEVPRG_DATA_RO\\\$\\\$Base present ---"
grep -n 'DEVPRG_DATA_RO.*Base' /tmp/DevPrgD.v3.test.ld || echo "MISSING!"

echo "=== DONE ==="

问题原因:

这套构建工具链 CLANG140LINUX 实际指向的是 clang/LLD 16.1.2。EDK2 构建系统调用 arm-link 链接(本应是 ARM 的 armlink),但系统里安装的是一个把它翻译成 GNU ld.lld 的 wrapper 脚本 。这个 wrapper 是问题根源,因为 ld.lld 与 ARM 工具链行为不同,构建脚本喂给它的参数和链接脚本内容它都处理不了。


问题 1:DevprogD 链接失败(第一次 build 的硬错误)

报错ld.lld: error: /tmp/DevPrgD.ld.noassert.*.ld:60: symbol not found: Image$$DEVPRG_DATA_RO$$Base

排查过程

  • 我先写了 check_noassert.sh 检查 wrapper 生成的中间脚本,定位到根因。
  • 生成的 DevPrgD.ld 第 50 行是一条被注释掉的 ASSERT ,格式为 ASSERT(...); */ ------ clang -E 预处理时把开头的 /* 剥掉了,只留下孤儿的 */
  • v2 wrapper 的 in_assert 状态机逻辑是:进入 ASSERT 后,检查行尾是否以 ); 结束来退出断言状态。但这一行*/ 结尾而不是 ); ,导致 in_assert 一直卡在 True,把后面紧跟的 DEVPRG_DATA_RO整段吞掉 ,于是 Image$$DEVPRG_DATA_RO$$Base 符号缺失。

解决 :重写为 v3 注释感知 wrapperarm-link,备份为 arm-link.bak.v2)。核心逻辑:

  • strip_trailing_comment_close() 先剥掉行尾孤儿 */ ,再做 ); 完整性判断 → 不再误吞后续 section。
  • 同时覆盖单行、多行(第 107-108 行)、带孤儿 */ 三种 ASSERT 形态。

问题 2:Core Sec.dll 链接失败(修完问题 1 后暴露的下一个错误)

报错ld.lld: error: /tmp/GccBase.lds.noassert.651580.ld:23: unknown directive: */

排查过程

  • 这发生在 Core.dsc 的 Sec 模块链接,用的是 EDK2 标准脚本 GccBase.lds
  • 关键发现:GccBase.lds 里有真实的多行注释 (第 18 行 /* 打开,第 23 行 */ 闭合),里面没有 ASSERT
  • 我 v3 第一版的"孤儿 */ 处理"写得太激进:只要检测到 */ 就剥掉。结果把合法的闭合 */ 也剥了,留下悬空的 /*,导致第 23 行出现 unknown directive: */

解决 :把 v3 重写为完整的注释感知状态机

  • 用标志位 in_comment 跟踪 /* */ 块注释(含多行跨行),合法的注释原样透传、保持顺序;
  • 只在非注释代码 中剥离 ASSERT(...)
  • 分别用 GccBase.lds(验证注释完整保留)和生成的 DevPrgD.ld(验证 ASSERT 剥离 + DEVPRG_DATA_RO 保留)做了单元验证通过后,才重新跑 build。

问题 3:Windows 换行符(CRLF)破坏 wrapper

现象 :从 Windows 盘(D:\tmp2)拷贝 wrapper 到 WSL 工具链目录后,脚本无法执行(shebang 被 \r 污染)。

解决 :安装时统一用 tr -d '\r' 去除 CR,安装脚本里还带自检(grep -q $'\r' 检查并报错)。这是后续所有脚本安装的固定套路。


问题 4:xbl_config 签名警告(非致命)

现象 :构建日志出现 No Sectools Folder provided. SKIPPING IMAGE SIGNINGERROR: Could not generate Signed XBL Config

判定非致命 ------ 构建继续执行并最终报告全部 8 个镜像成功(含 xbl_config)。属于开发环境签名路径配置为空的行为,走的是 unsigned 路径。不影响产物,无需修复。


最终结果

修复完问题 1+2(即 v3 注释感知 wrapper)后,run10 完整编译成功,0:36mins 产出全部 8 个镜像:XBL_S、XBL_RAMDUMP、UEFI、XBL_S_DEVPRG_NS、JtagProgrammer、xbl_config、SHRM、ImageFv

关键经验总结

报错 根因 修复
symbol not found: Image$$DEVPRG_DATA_RO$$Base v2 状态机被"孤儿 */ 结尾的注释 ASSERT"卡死,吞掉后续 section v3 加 strip_trailing_comment_close() 先剥 */ 再判断
unknown directive: */ v3 第一版把合法的多行注释闭合符 */ 也剥掉了 v3 重写为完整注释感知状态机,合法注释透传
wrapper 无法执行 Windows CRLF 污染 shebang tr -d '\r' + 自检
SKIPPING IMAGE SIGNING 开发环境无签名路径 非致命,忽略

本次改动完整总结

一、GPIO 修改(产品功能改动)

文件pinctrl.dtsi(WSL 路径 .../boot_images/boot/Settings/Soc/Aliso/Core/SocInfra/TLMM/pinctrl.dtsi

改动内容 :把 GPIO 150--153 (SSC_QUP_2 的 SSC_4--7)从原配置改为 Hi-Z(高阻/浮空)

复制代码
(GPIO_INPUT | GPIO_NO_PULL | GPIO_OUT_LOW | GPIO_PRG_YES) /* PIN 150 */
(GPIO_INPUT | GPIO_NO_PULL | GPIO_OUT_LOW | GPIO_PRG_YES) /* PIN 151 */
(GPIO_INPUT | GPIO_NO_PULL | GPIO_OUT_LOW | GPIO_PRG_YES) /* PIN 152 */
(GPIO_INPUT | GPIO_NO_PULL | GPIO_OUT_LOW | GPIO_PRG_YES) /* PIN 153 */
  • 关键区别:原来 150--153 和 148--149 一样是 GPIO_PRG_NO;现在改为 GPIO_PRG_YES(程序可配置 = Hi-Z/浮空)。
  • 数值 0x151 = INPUT(0x1) | NO_PULL(0x10) | OUT_LOW(0x40) | PRG_YES(0x100)
  • 该配置编译进 post-ddr dtb ,最终打入 xbl_config.elf,已反复验证(源码 → dtb → ELF 三段链路全部确认 150--153 = 0x151)。

二、为了编译通过所做的修改

(这些是本地工具链替换带来的问题,不是高通源码问题)

问题 原因 解决
DevprogD ASSERT 失败 GNU LLD 链接器不支持 ARM armlink 的 ASSERT() 语法 修改链接脚本,去掉/改写 ASSERT
GccBase.lds 注释报错 源码注释跨了 token,GNU 语法解析不了 调整注释写法
CRLF 行尾问题 从 Windows 拷文件导致行尾混乱 统一用 tr -d '\r' 转 LF
sectools 找不到 /home/jc/bin/sectools 不存在 建软链指向 wrapper

核心背景:高通原版用 ARM armlink 编译,原生支持 -marchASSERT() 等语法。本地换成 GNU clang/LLD(CLANG140LINUX 16.1.2)后,需要通过一个注释感知的 arm-link v3 wrapper 来适配,所以才会出现这些"原版不该有"的问题。

三、启动失败问题(本次重点修复)

现象 :烧写后 SBL1 加载完 APDP 后报 Error code 9c001008 at boot_elf_driver.c Line 363

根因(完整链条):

  1. 0x9C001008 = BL_ERROR_GROUP_XBL_CONFIG | INITIALIZATION_ERROR ------ SBL1 加载 xbl_config.elf 初始化失败;
  2. 构建日志出现 SKIPPING IMAGE SIGNING,签名被跳过;
  3. buildconfig.json 引用 $SECTOOLSROOT/sectools_dir,但 /home/jc/bin/sectools_dir 当时不存在GenConfigImage.pyisdir 检查失败 → 不签名;
  4. 而签名时 pboot_gen_elf()elf_gen_tools.py)才会补上 头部 NULL 段 + 尾部 hash NULL 段 (并把 e_phnum += 2);
  5. 未签名版本只有 9 个 LOAD 段、没有 NULL 头段(135604 字节)→ SBL1 加载器初始化失败。

修复

  1. 永久修复 (建好缺失目录,以后编译自动签名):

    复制代码
    ln -sfn /pkg/sectools/v2/latest/Linux/sectools_dir /home/jc/bin/sectools_dir

    已确认软链存在且指向正确。

  2. 手动重新签名 本次产物,得到可烧写文件:

    • 大小 143544 字节,11 段 (NULL 头 + 9 LOAD + NULL hash 尾),与已知可用版 xbl_config_fp.elf 结构完全一致;
    • post-ddr dtb 段中 GPIO 150--153 = 0x151(Hi-Z)确认保留
    • 已复制到 D:\tmp\xbl_config.elf (md5 653a3d14f12c51cf01b044589e27fd16),可直接烧写。

四、下次重新编译步骤

前置/home/jc/bin/sectools_dir 软链已建好,无需再手动签名。

  1. 在 Windows 打开 D:\tmp2\run_build10.sh,按需确认顶部路径(当前为 BOOT.MXF.2.2):

    复制代码
    ROOT=/home/jc/ar1/aliso-la-1-0_amss_standard_oem/BOOT.MXF.2.2
  2. 在 WSL 执行:

    复制代码
    bash /mnt/d/tmp2/run_build10.sh

    脚本会自动:建 /home/jc/py3bin/python 软链(→ python3.8)、把 py3bin 加进 PATH、确保 /home/jc/bin/sectools 软链存在、然后跑

    复制代码
    python -u boot_tools/buildex.py -t Aliso -v LAA -r RELEASE

    完整日志写到 D:\tmp2\xbl_build_run10.log

  3. 编译后校验(可选但建议):

    • 确认日志中 xbl_config 步骤没有 SKIPPING IMAGE SIGNING

    • 检查产物程序头数:

      复制代码
      readelf -l .../Build/AlisoLAA/xblconfig/auto_gen/elf_files/create_cli/xbl_config.elf

      应为 11 段LOAD segments: 9 + NULL segments: 2);

    • 产物路径:.../boot_images/Build/AlisoLAA/xblconfig/auto_gen/elf_files/create_cli/xbl_config.elf

  4. 如果是从 Windows 拷贝/编辑过任何 .dtsi/.py/.c 源文件再拷回 WSL,务必先 tr -d '\r' 去掉 CR,避免 CRLF 编译问题。

现在就可以先用 D:\tmp\xbl_config.elf(已签名修复版)重新烧写验证启动。

相关推荐
咸甜适中1 小时前
rust语言AI编程学习笔记(五)clap命令行参数解析
学习·rust·ai编程
诗句藏于尽头2 小时前
deepseek harness对接商汤科技免费大模型使用教程
人工智能·科技·学习
chemddd2 小时前
豆包生成 亚马逊链接的视频
学习·交友
weixin_431600442 小时前
NestJS 入门(7):生命周期钩子——构造函数和 `OnModuleInit` 差在哪?
前端·后端·学习·node.js·nest.js
工业HMI实战笔记2 小时前
解放双手,声控未来:抗噪语音交互如何革新嘈杂车间的HMI操作体验
人工智能·学习·自动化·制造
知识分享小能手3 小时前
线性代数学习教程,从入门到精通,相似矩阵及二次型 — 知识点详解(9)
学习·线性代数·机器学习
小弥儿3 小时前
GitHub今日热榜 | 2026-08-14:OSINT情报工具回流,本地AI赛道升温
人工智能·学习·开源·github
小黄人软件4 小时前
【证书批量转换】PEM->CER证书批量转换工具.exe 纯 Python实现,无需安装OpenSSL
人工智能·学习
青山是哪个青山5 小时前
LangChain 学习笔记(五):Tools 工具调用
笔记·学习·langchain