
拿到全志T113-S3这颗料的时候我心里其实是有预期的双核Cortex-A7主频1.2GHz片上直接集成DDR画个四层板就能跑Linux做小HMI、边缘网关、充电桩主板这类项目再合适不过。但真正让我头疼的反而不是硬件而是那一大坨SDK。全志的Tina/Longan风格SDK继承了不少历史包袱目录多、脚本长、依赖杂如果搞不清楚“配置—编译—打包”这条链路很容易在“为什么我make完却没有img出来”这个问题上耗掉一整天。这篇东西就是我把从零开始编译T113-S3 SDK、烧录固件、再做产品定制的一整套过程记录下来给准备上这颗料的工程师做参考。开门见山地说这篇不是芯片数据手册的复读也不是SDK里每个脚本的逐行注释而是我从“拿到SDK压缩包”到“固件在板子上跑起来”的完整实操路径中间会穿插我自己踩过的坑和判断逻辑。适合自己画板子、需要移植BSP的硬件工程师也适合刚接手全志方案的Linux开发人员。对就是想捣鼓一块T113开发板做点东西的爱好者来说应该也能从中找到有用的东西。1. 开工前的两个关键认知芯片定位与SDK核心目录1.1 先搞清楚T113-S3能做什么再决定怎么玩SDKT113-S3这颗芯片定位非常清晰便宜、够用、集成度高。双核Cortex-A7主频1.2GHz片上直接封了DDR不需要外挂内存颗粒。这个特性对产品研发影响很大——BOM成本低、布线简单、板子面积可以做得非常小。接口方面显示支持RGB、LVDS、MIPI DSI网络有百兆以太网MAC工控场景关心的CAN、多路串口、I2C、SPI也都有。所以你会发现市面上大量用在光伏逆变器、电力采集终端、电梯楼层显示器、车载后装屏、充电桩HMI上的Linux方案都是T113系列。选SDK之前要判断自己到底是哪种用法。官方提供的SDK默认是Linux单系统也可以在Buildroot里把RTOS核配出来实现A7核跑Linux、RISC-V核跑RTOS的双系统方案。大部分产品用Linux单系统就够了编译流程和文件系统处理要简单得多。我建议第一次上手不要碰双系统先把单系统的编译链路跑通后面真有需要再研究核间通信和共享内存这类复杂问题。1.2 SDK目录结构先把“谁负责什么”看清楚SDK解压出来之后一眼望去目录非常多但真正核心的就那么几个。拿T113 SDK的常见布局来说通常会有 build、lichee、out、tools 这几大部分。build 里放的是顶层编译脚本和公共配置lichee 是真正的主力代码区下面一般分 brandy对应启动阶段的boot0和U-Boot、kernelLinux内核源码T113常见的是5.4版本线、buildroot根文件系统构建系统out 就是编译输出目录最后打包好的固件也在这里面。这个结构可以理解成一个组装电脑的类比brandy 相当于主板BIOS负责开机后把硬件初始化好然后引导内核kernel 是操作系统本体buildroot 负责准备C库、shell、各种应用层软件最终生成整个硬盘里的文件系统内容。全志的编译脚本会把这三个部分依次编译再通过 pack 脚本把它们按分区表组装进一个img文件里这就是你最后烧录到板子上的固件。所以拿到SDK第一件事不是急着敲make而是先找到这几个核心目录打开顶层README或者build目录下的脚本说明确认自己手上这个SDK的版本和编译入口。版本差异是真实存在的不同时期放出来的T113 SDK命令入口可能是 build.sh也可能是 envsetup.sh lunch路径也可能有出入但整体结构八九不离十。把这个流程理解透了换哪个版本都能很快上手。2. 编译环境搭建Ubuntu、依赖包与磁盘规划2.1 Ubuntu版本建议与依赖安装全志官方推荐的编译系统一般是Ubuntu我自己长期用Ubuntu 20.04和22.04编译T113 SDK都跑得通。Ubuntu 24.04我也试过能编但偶尔会遇到一些Python脚本兼容性问题如果不想在环境上浪费太多时间直接用20.04最稳。依赖包这块不同SDK版本要求的清单略有差别但以下这些基本是通用的建议一步到位全部装上sudo apt update sudo apt install -y git wget unzip zip python3 python3-pip \ build-essential gcc g gawk m4 make libncurses5-dev \ libssl-dev bc flex bison u-boot-tools dosfstools \ lib32z1 lib32ncurses6 lib32stdc6 file device-tree-compiler其中 lib32z1、lib32stdc6 这种32位兼容库特别重要。全志的某些编译工具链还是32位的或者编译过程中要调用32位程序缺了会在很诡异的地方报No such file or directory而且报错信息很可能让你先怀疑路径配置根本想不到是缺库。Python环境也需要留意。老一点的SDK可能依赖Python2新SDK基本都迁移到Python3了。如果编译过程中遇到configparser找不到、python: command not found这类报错多半是SDK脚本里写死了 python 而系统只有 python3。处理方法是在 /usr/bin 下做一个软链接sudo ln -s /usr/bin/python3 /usr/bin/python这种问题不会出现在官方文档里但基本每个编译全志SDK的人都会碰到。2.2 磁盘、内存与编译时长估算编译T113整套SDK对机器要求其实不高但有两样东西不能省磁盘和耐心。全量编译会在out目录下产生大量中间产物实测下来全新编译一次SDK解压加构建产物占用的磁盘空间大约在40到60GB。如果还打算同时保留多个方案或者多次clean后重新编译直接给虚拟机分配80GB以上会比较舒服。内存方面官方建议8GB以上。我在8GB内存的机器上编译过能过但会很吃力。尤其是Buildroot编译过程中会起多个并行任务内存吃满之后编译速度反而下降。建议至少16GB同时可以限制并行任务数避免把机器卡死。时间上第一次全量编译在8核16G的机器上大约需要40分钟到1小时。这个时间大部分花在Buildroot下载和编译交叉工具链、第三方库上。所以强烈建议在编译前确认网络状况或者提前把Buildroot的dl目录缓存准备好。网络不好下载源码包那一步就可能反复失败看起来是编译错误实际上是网络问题。2.3 串口、USB烧录驱动与常用工具交叉编译链、SDK这些是软件层面的事但当你第一次把固件烧进板子发现自己什么都看不到时就会意识到串口才是嵌入式开发里最靠谱的调试伙伴。T113的调试串口通常在UART0电平是TTL 3.3V用USB转串口模块接上波特率多数SDK默认是115200但个别方案会把内核打印波特率配成1500000。遇到串口输出乱码先别怀疑板子坏了把波特率挨个试一遍。USB烧录驱动也需要提前准备。T113板子进入烧录模式后Windows设备管理器里会看到一个未知设备VID/PID通常是 1f3a:efe8 这种全志FEL设备。PhoenixSuit自带驱动安装功能但经常在Win10/11上装不干净我习惯用Zadig手动把驱动指定成WinUSB成功率很高。Linux下也可以用 sunxi-fel 工具直接通过USB操作FEL模式对做产线或者批量烧录来说会更灵活。串口工具用 minicom 或者 PuTTY 都行关键是先确认/dev/ttyUSB0有权限。把自己加到 dialout 用户组sudo usermod -aG dialout $USER重新登录后就不用每次烧录都sudo了。3. SDK编译全流程从配置到固件打包3.1 首次初始化envsetup、lunch 与方案选择T113 SDK拿到手第一步永远是解压、确认目录、然后进入编译配置。以常见的Tina/Longan风格SDK为例命令大概是这样的cd /opt/t113-sdk source build/envsetup.sh lunchsource envsetup.sh 会把一批编译辅助函数加载进当前shell比如 lunch、m、pack 这些都是脚本定义的函数不是系统命令。所以每次新开终端都要重新source一次否则直接敲 m 会提示 command not found这是新手最容易踩的第一个坑。lunch 执行后会弹出方案列表里面会有官方EVB、第三方核心板的配置项。选哪个取决于你手上是哪块板子。如果是全志官方EVB或者通用底板直接选对应的 t113_evb1 之类的配置如果你用的是芒果派MQ-R这类第三方板子可能需要先在SDK里添加对应的board配置或者选择最接近的官方方案再改设备树。这一步选错不会导致编译失败但烧出来的固件可能外设、屏幕参数对不上跑起来显示不正常。选完方案后SDK会生成一套当前方案的配置缓存后续编译都会基于这套配置。全志为了方便还支持直接通过 build.sh 来走完整的 config/build/pack 流程有些版本的SDK里./build.sh一行就能依次完成配置、编译、打包。我自己的习惯是第一次用 envsetup lunch 手动选确认编译链路没问题后再写成脚本自动化方便后面反复打包。3.2 U-Boot、内核、根文件系统的编译链路配置完成后编译主流程实际上分三段bootloader、kernel、rootfs。全志的顶层脚本会用m命令或者 make把这三段按顺序执行但理解它的内部逻辑对排查问题非常重要。先编bootloader对应lichee/brandy目录。这里会产出boot0和U-Boot。boot0是芯片BootROM加载的第一段引导负责初始化DDR和关键外设然后跳转到U-Boot。U-Boot再负责加载内核镜像。这两段如果出了问题现象通常是串口打印到某个地方就停住、指示灯亮了但内核启动日志完全没有。遇到启动异常第一件事就是看串口打印停在哪就能快速定位是boot0、U-Boot还是内核阶段。然后是内核对应lichee/linux-5.4。全志内核编译会用到设备树但设备树来源有点特殊硬件配置源头是 sys_config.fex在方案configs目录下编译打包时会经过一个工具把fex转成 board.dts再参与到内核设备树编译中。这就是为什么很多全志工程师改屏参、改引脚复用都是去改fex文件而不是直接改dts。你如果直接改dts编译一次可能就被fex生成的board.dts覆盖了。最后是rootfs通过Buildroot构建。Buildroot会下载并编译基础的C库glibc或musl、busybox、各种应用库最终生成根文件系统镜像。第一次编译耗时主要就是耗在这里。如果产品只需要很精简的文件系统可以在menuconfig里裁剪如果要用Qt、GStreamer这类大件Buildroot里也都有现成的包选中即可。三段都编完后SDK会在out目录下生成对应的镜像文件但这时候还不能直接用因为还缺最后一步打包。3.3 打包固件pack脚本到底做了什么打包阶段是全志SDK里最容易被忽略、但实际最容易出问题的环节。执行 pack 命令后脚本会做这么几件事读取方案的分区表配置通常叫 sys_partition.fex这个文件规定了固件里有哪些分区、每个分区多大然后把boot0、U-Boot、内核、dtb、rootfs等镜像按照分区表填充到一个完整的img文件里同时把启动参数、硬件配置打包进对应区域最终生成一个可以烧录的固件常见名字类似 t113_evb1_uart0.img。理解打包过程很重要因为你碰到的很多“编译成功了但没有固件”的问题本质都是打包阶段出了问题。比如某个fex文件路径写错了、某个镜像文件缺失、分区总大小超过烧录介质容量pack都会报错中断。遇到打包报错先看它是在哪一步断的如果提示找不到 boot0_sdcard.fex说明前面bootloader没编成功或者out目录被清过如果提示分区大小超限那就去改 sys_partition.fex。另外打包脚本会读取当前方案配置所以如果你修改了内核设备树、Buildroot配置但没有重新编译对应模块直接pack固件里仍然是旧的内容。我惯用的流程是改了代码就m全量编译或者针对单模块编译SDK通常提供内核单独编译、Buildroot单独编译的入口再pack。图省事就全量mpack虽然慢一点但不会出现“我改了但固件里没有”的灵异现象。3.4 烧录验证PhoenixSuit与启动卡两种方式固件打包出来之后下一步就是烧录验证。Windows下最常用的是PhoenixSuit板子断电按住烧录键或者短接FEL相关测试点再上电此时板子进入FEL模式USB连接到电脑。PhoenixSuit识别到设备后选择刚才生成的img文件点击升级等进度条走完板子自动重启就看到串口输出Linux启动日志了。另一种方式是用PhoenixCard做启动卡。这个工具可以把img烧写到SD卡上然后板子通过SD卡启动。对开发调试来说启动卡方式非常方便因为不用反复操作烧录键。我习惯在调试阶段用SD卡确认固件没问题、要出样机时再用USB批量烧录到板载存储。烧录完看到串口有输出先用root登录默认密码通常写在SDK文档里然后检查几个基本项ip link看网络是否起来cat /proc/cmdline看启动参数df -h看根文件系统分区挂载是否正常dmesg | grep -i error看有没有明显的驱动错误这套排查习惯能帮你把“固件能启动”快速推进到“外设都正常”的状态。4. 产品定制中的实操要点改屏参、动分区、加驱动4.1 通过 sys_config.fex 点亮一块RGB/LVDS屏产品开发中第一个高频定制需求就是换屏幕。T113-S3内置显示控制器支持RGB、LVDS、MIPI DSI几种接口不同屏幕的初始化参数都在 sys_config.fex 的 [lcd0] 段里配置。修改这个文件重新编内核并打包就能适配新屏。改屏参有几步先确认屏的接口类型、分辨率、像素格式、时钟频率这些参数屏厂规格书里都有然后打开方案对应的 sys_config.fex找到 lcd0 配置段把 lcd_xres、lcd_yres、lcd_dclk_freq、lcd_hbp/lcd_hfp/lcd_vbp/lcd_vfp 等时序参数按规格书填入如果是LVDS屏还要确认lvds通道数和数据格式MIPI屏则要检查dsi相关配置和初始化序列。填完之后编译、打包、烧录如果屏不亮先用串口看内核有没有lcd驱动的报错再用示波器量一下时钟、数据线是否有波形基本就能定位是参数问题还是硬件连接问题。这里有个全志特有的坑sys_config.fex 修改后编译脚本会重新生成board.dts参与内核编译所以如果你改了fex记得要重新编译内核至少重编dtb再pack。只打包不重编屏参不会生效这一点我一开始就吃过亏。4.2 调整分区表与根文件系统大小第二个高频需求是调整存储分区。T113方案的片外存储通常是SD卡、eMMC或者SPI NOR/NAND不同的启动介质和存储大小需要不同的分区表。分区表配置在 sys_partition.fex 里你可以看到 boot0、uboot、boot、rootfs、misc、recovery 等分区定义。如果发现rootfs太小、装不下应用或者想单独划一个数据分区用来存日志、OTA升级包都可以直接改 sys_partition.fex。比如把 rootfs 的 size 从 256M 改成 512M或者新增一个名为 data 的 ext4 分区然后在文件系统挂载脚本里加上对应的挂载规则。改分区表之后一定要重新pack并且烧录时选择“整包升级”模式否则旧分区表还留在存储里会出现空间对不上或者挂载失败的问题。需要注意分区顺序和起始偏移尤其当你用的是小容量SPI NOR时整个固件必须压缩到很小分区表调整的余量有限。这时候建议精简Buildroot配置和内核驱动把固件压到芯片支持的最小体积而不是一味扩分区。4.3 新增加载一个内核驱动模块产品定制经常需要外接一些芯片比如4G模组、传感器、加密芯片。如果这个芯片内核已经支持通常只需要在设备树或fex里配置好I2C/SPI/串口引脚然后使能对应的内核驱动选项重新编译内核即可。内核配置通过make kernel_menuconfig进入图形界面搜索到你需要的驱动选中为模块M或编入内核*保存后重新编译。如果编译成模块.ko还需要把模块安装到rootfs的对应目录中Buildroot里通常有相关的配置或者在编译完成后手动拷贝到rootfs镜像中再打包。编入内核则更省事不需要处理模块加载问题代价是内核体积变大。我一般调试阶段用模块方式方便单独替换、insmod/rmmod测试确认稳定后再改成编入内核减少运行时依赖。加完驱动之后串口日志里如果看到xx_xxx: probe success这类打印基本就说明设备已经被正确识别。如果probe失败优先检查引脚复用是否冲突、供电和复位时序是否满足这些在dmesg里大多能看出端倪。5. 编译与烧录常见问题排查实录5.1 卡在最前面的环境类报错我把实际编译中遇到的高频问题整理成一个速查表方便对照排查典型现象根本原因处理方法m: command not found没有source envsetup.sh重新执行 source build/envsetup.sh新开终端都要做/usr/bin/env: ‘python’: No such file or directory脚本写死python系统只有python3建立/usr/bin/python - python3软链接编译中断报No such file or directory路径看着没问题缺32位库安装 lib32z1 lib32ncurses* lib32stdc6mkimage: command not found缺少U-Boot工具sudo apt install u-boot-toolsflex: command not found/bison: command not found基础构建工具缺失按依赖清单补齐 build-essential flex bisonBuildroot下载源码包失败网络问题配置国内镜像源或提前导入dl缓存这类环境问题最折磨人的地方在于报错信息往往有误导性。比如缺32位库时报的是No such file or directory看到的是某个可执行文件不存在很容易让人去改路径、改环境变量折腾半天。我的建议是看到奇怪的报错第一时间用file命令检查涉及的可执行文件格式如果是32位ELF而系统是64位纯净环境基本就是缺32位库了。5.2 打包阶段与固件产物异常打包阶段的报错通常集中在镜像缺失和分区超限两类。镜像缺失类比如ERROR: open boot0_sdcard.fex failed本质是前面某段编译没成功或者out目录被误删。我的排查思路是按顺序确认boot0、U-Boot、内核、rootfs各自的输出文件是否都在out目录对应位置缺哪个就回到对应目录单独重编哪个而不是从头全量编译浪费时间。分区超限类报错一般会提示固件大小超过目标存储容量。原因要么是rootfs做得太大、要么是内核开启了太多功能导致boot分区放不下。处理办法是先看哪一个镜像膨胀得厉害用du -sh查对应镜像大小再回到配置里裁剪。Linux内核我习惯用make kernel_menuconfig关掉不需要的文件系统、驱动、调试选项Buildroot里去掉不需要的包体积能明显降下来。还有一个容易忽略的点如果修改过 sys_partition.fex但之前的out目录里残留了旧镜像pack时可能因为文件时间戳或者缓存问题把旧产物打进去。稳妥的做法是修改分区表后把out目录下对应的镜像文件清理掉强制重新编译。5.3 烧录后串口无输出/启动异常的排查路径烧录成功后板子没反应这是最让人焦虑的场景但排查路径其实很固定。第一步按住烧录键重新上电如果电脑还能识别到FEL设备说明芯片本身是好的问题出在固件或者烧录过程如果设备管理器里完全没有反应先查USB线、供电、板子的启动模式引脚设置。固件能烧进去但串口没输出优先检查串口接线和波特率T113调试串口常用115200但有的SDK会配成1500000乱码就换波特率试。串口设置没问题仍无输出再考虑是不是boot0就没跑起来这时候用示波器量DDR供电、时钟是否正常如果boot0阶段有打印但到U-Boot停住重点查存储介质上U-Boot镜像是否匹配、DDR初始化参数是否和板子实际内存一致。启动到内核阶段崩溃通常是设备树和外设配置问题。内核日志里如果有Kernel panic - not syncing把最后几行日志记下来配合scripts/decodecode、addr2line等工具定位具体驱动。这类问题单靠猜效率很低我的习惯是先启动一个“最小系统”——把不必要的驱动全部关掉只保留串口、存储、基础网络确认最小系统稳定后再逐步打开外设驱动哪个驱动打开后崩溃问题就锁定在哪个模块。最后再说一点我自己的体会。全志T113-S3这套SDK篇幅确实大、历史包袱也不少但只要你愿意花一个下午把“配置—编译—打包—烧录—串口调试”这条闭环跑通后面所有定制工作都是在这个闭环上做加法。我后来做过的几个T113项目从改屏幕参数、调分区、加4G模组驱动到量产烧录的产线工具整合底层都是这套流程。遇到问题别急着怀疑工具链先看日志、看现象、拆环节大部分坑都能在文档和串口输出里找到答案。如果你也正在被某个编译错误卡住照着上面这些排查路径试一遍大概率能省下不少时间。