下次只需一条wsl bash /mnt/d/tmp2/run_build10.sh。若环境被重置导致 wrapper 丢失,先跑wsl bash /mnt/d/tmp2/install_armlink_v3.sh再编译。
run_build10.s
#!/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
#!/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),但系统里安装的是一个把它翻译成 GNUld.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 注释感知 wrapper(arm-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 SIGNING和ERROR: 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)。
二、为了编译通过所做的修改
(这些是本地工具链替换带来的问题,不是高通源码问题)
| 问题 | 原因 | 解决 |
|---|---|---|
DevprogDASSERT 失败 | GNU LLD 链接器不支持 ARM armlink 的ASSERT()语法 | 修改链接脚本,去掉/改写 ASSERT |
GccBase.lds注释报错 | 源码注释跨了 token,GNU 语法解析不了 | 调整注释写法 |
| CRLF 行尾问题 | 从 Windows 拷文件导致行尾混乱 | 统一用tr -d '\r'转 LF |
| sectools 找不到 | /home/jc/bin/sectools不存在 | 建软链指向 wrapper |
核心背景:高通原版用 ARMarmlink编译,原生支持
-march、ASSERT()等语法。本地换成 GNU clang/LLD(CLANG140LINUX 16.1.2)后,需要通过一个注释感知的 arm-link v3 wrapper来适配,所以才会出现这些"原版不该有"的问题。
三、启动失败问题(本次重点修复)
现象:烧写后 SBL1 加载完 APDP 后报Error code 9c001008 at boot_elf_driver.c Line 363。
根因(完整链条):
0x9C001008 = BL_ERROR_GROUP_XBL_CONFIG | INITIALIZATION_ERROR—— SBL1 加载 xbl_config.elf 初始化失败;- 构建日志出现
SKIPPING IMAGE SIGNING,签名被跳过; buildconfig.json引用$SECTOOLSROOT/sectools_dir,但/home/jc/bin/sectools_dir当时不存在→GenConfigImage.py的isdir检查失败 → 不签名;- 而签名时
pboot_gen_elf()(elf_gen_tools.py)才会补上头部 NULL 段 + 尾部 hash NULL 段(并把e_phnum += 2); - 未签名版本只有 9 个 LOAD 段、没有 NULL 头段(135604 字节)→ SBL1 加载器初始化失败。
修复:
- 永久修复(建好缺失目录,以后编译自动签名):
已确认软链存在且指向正确。ln -sfn /pkg/sectools/v2/latest/Linux/sectools_dir /home/jc/bin/sectools_dir - 手动重新签名本次产物,得到可烧写文件:
- 大小 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(md5653a3d14f12c51cf01b044589e27fd16),可直接烧写。
- 大小 143544 字节,11 段(NULL 头 + 9 LOAD + NULL hash 尾),与已知可用版
四、下次重新编译步骤
前置:/home/jc/bin/sectools_dir软链已建好,无需再手动签名。
在 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在 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。编译后校验(可选但建议):
- 确认日志中 xbl_config 步骤没有
SKIPPING IMAGE SIGNING; - 检查产物程序头数:
应为11 段(readelf -l .../Build/AlisoLAA/xblconfig/auto_gen/elf_files/create_cli/xbl_config.elfLOAD segments: 9+NULL segments: 2); - 产物路径:
.../boot_images/Build/AlisoLAA/xblconfig/auto_gen/elf_files/create_cli/xbl_config.elf
- 确认日志中 xbl_config 步骤没有
如果是从 Windows 拷贝/编辑过任何 .dtsi/.py/.c 源文件再拷回 WSL,务必先
tr -d '\r'去掉 CR,避免 CRLF 编译问题。
现在就可以先用D:\tmp\xbl_config.elf(已签名修复版)重新烧写验证启动。