T113S3系统移植(基于T113S3 TinaSDK5.0V1.2)
T113S3系统移植(基于T113S3 TinaSDK5.0V1.2)
一、启动介质和启动框架
1. 启动介质确认 (Hardware Boot)
- 逻辑:板载Flash选用W25N01GVZEIG,1Gbit,是SPI NAND FLASH所以基于
evb1_auto_nand方案,明确硬件通过 SPI NAND 启动 - 支撑:确保板子 BOOT 引脚电平正确,且
sys_config.fex中的storage_type = 5(SPI NAND)。
2. Init 启动框架切换 (Software Init)
-
问题:由于我们选择方案时选用的是
evb1_auto_nand openwrt方案,此方案默认采用的是openwrt的procd启动,不便在 <sdk_dir>/openwrt/target/t113/<自己的方案> 目录下的 busybox-init-base-files 文件夹中的一些自动加载驱动脚本设置,故我们需要先将openwrt系统默认启动方式设置为busybox启动 -
操作:(默认已经source build/envsetup.sh并且lunch完毕)
- 在
croot路径下执行:make menuconfig - 将procd-init修改为busybox-init
- 进入Base system选项,取消procd勾选
- 选中 Customize busybox init base files options ,会识别到target中自定义板卡配置文件夹
- 取消选中setusbconfig
- 保存退出后重新编译
- 在
二、方案原型克隆和注册自己的方案
第一步:硬件方案克隆 (device 目录)
核心动作:
cd <sdk_dir>/device/config/chips/t113/configs
cp -r evb1_auto_nand <your_board_name>
vim <your_board_name>/sys_config.fex
原理解析: 在全志的架构里,device/ 目录存放的是纯硬件的描述(比如 U-Boot 怎么起、引脚怎么分配、分区表怎么切)。
- 为什么选
evb1_auto_nand? 因为你的硬件使用的是 SPI NAND Flash。克隆这个目录,意味着你继承了原厂经过严格测试的 NAND 时序和驱动配置,能最大程度避免底层存储报错。 sys_config.fex的作用:你把machine改成custom_board,这相当于给你的板子发了一张“身份证”。后续全志独有的打包工具(pack)在生成镜像时,就是靠匹配这个名字来寻找对应的硬件配置文件的。如下
;---------------------------------------------------------------------------------
; version:版本1.00
; machine:板级文件名
;---------------------------------------------------------------------------------
[product]
version = "100"
machine = "<your_board_name>"
板级方案添加完成,后续外设调试涉及的文件修改将在 custom_board 目录下完成
第二步:系统文件目录克隆 (openwrt/target 目录)
核心动作: 建立并配置 OpenWrt 编译靶点。
cd <sdk_dir>/openwrt/target/t113
cp t113-evb1_auto_nand t113-<your_board_name> -r
cd t113-<your_board_name>
mv t113_evb1_auto_nand.mk t113_<your_board_name>.mk
vim t113_<your_board_name>.mk
- 修改
t113_<your_board_name>.mk文件
$(call inherit-product-if-exists, target/allwinner/t113-common/t113-common.mk)
PRODUCT_PACKAGES +=
PRODUCT_COPY_FILES +=
PRODUCT_AAPT_CONFIG := large xlarge hdpi xhdpi
PRODUCT_AAPT_PERF_CONFIG := xhdpi
PRODUCT_CHARACTERISTICS := musicbox
PRODUCT_BRAND := allwinner
PRODUCT_NAME := t113_<your_board_name>
PRODUCT_DEVICE := t113-<your_board_name>
PRODUCT_MODEL := Allwinner t113 <your_board_name> board
- 修改 defconfig 和 defconfig_ota 文件(打包openwrt文件系统使用的默认配置)
vim defconfig
vim defconfig_ota
内容如下主要修改板名
#
# Automatically generated file; DO NOT EDIT.
# OpenWrt Configuration
#
CONFIG_MODULES=y
CONFIG_HAVE_DOT_CONFIG=y
# CONFIG_TARGET_t113_awol_evb1 is not set
# CONFIG_TARGET_t113_dev is not set
# CONFIG_TARGET_t113_evb1 is not set
# CONFIG_TARGET_t113_evb1_auto is not set
CONFIG_TARGET_t113_<your_board_name>=y
# CONFIG_TARGET_t113_evb1_auto_nor is not set
# CONFIG_TARGET_t113_pro is not set
CONFIG_TARGET_t113_<your_board_name>_Default=y
CONFIG_TARGET_BOARD="t113-<your_board_name>"
- 修改 TinaProducts.mk 文件:
vim TinaProducts.mk
#
# Copyright (C) 2013 The Android Open-Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/t113_<your_board_name>.mk
- 修改 vendorsetup.sh 文件
vim vendorsetup.sh
add_lunch_combo t113-<your_board_name>
- 修改 Makefile文件:
vim Makefile
#
# Copyright (C) 2013-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
ARCH:=arm
BOARD:=t113-<your_board_name>
BOARDNAME:=t113-<your_board_name>
FEATURES:=fpu dt
CPU_TYPE:=cortex-a7
CPU_SUBTYPE:=neon
MAINTAINER:=Allwinner
KERNEL_PATCHVER:=5.4
UBOOT_PATCHVER:=2018
KERNELNAME:=zImage dtbs
include $(INCLUDE_DIR)/target.mk
TinaProducts.mk 与 vendorsetup.sh:
- 这两个文件是 Android 风格编译系统的残留(Tina 融合了 Android 的 envsetup 和 OpenWrt 的底层)。它们的作用是把你的板卡名称暴露给全局环境,让你在敲
lunch时能看到选项2。
第三步:环境初始化与方案选择 (envsetup.sh & lunch)
核心动作: 注入环境变量并锁定编译上下文。 原理解析:
source build/envsetup.sh:这不是简单的运行脚本,source(或.)意味着将脚本里的变量和函数注入到你当前的终端窗口里。执行完这句,你的终端就拥有了超能力,多出了croot(回到根目录)、cout(去输出目录)、pack(打包)等快捷命令。lunch 2: 当你选择t113-<your_board_name>后,终端打印了一大堆 Log(比如Prepare toolchain、kernel defconfig: generate ...)。在这个瞬间,后台干了三件大事:- 找到了交叉编译工具链的路径。
- 提取了
device目录下的内核默认配置(config-5.4),将其复制到out/.../kernel/build/.config中。 - 将所有的路径变量(
TINA_TOPDIR,TARGET_BOARD等)设置完毕。
第四步:编译与打包 (make & pack)
核心动作: 生成二进制文件并合成最终固件。 原理解析:
make -j1 V=s:- 这是 OpenWrt 最经典的单步调试编译命令。
-j1:强制使用单核单线程编译。如果你用-j8多线程编译,一旦某个组件报错,错误信息会被其他线程的输出淹没。首次编译新方案,强烈建议用-j1,排错最准。V=s:Verbose = stdout。打印出所有的编译细节和警告信息。- 它干了什么:它会依次编译 Toolchain(交叉编译器)、U-Boot、Kernel(生成
zImage和dtb),最后编译所有的用户态软件包(生成rootfs)。
pack命令:- 编译出来的 U-Boot、内核和文件系统是零散的文件。
pack是全志特有的打包脚本。 - 它会读取你第一步修改的
sys_config.fex和sys_partition.fex,计算分区大小,给镜像加上全志特有的文件头(Boot0、TOC0/TOC1 等),最后将它们全部“缝合”成一个可以直接用 PhoenixSuit 烧录到 NAND Flash 里的t113_linux_<your_board_name>_uart0.img镜像包。
- 编译出来的 U-Boot、内核和文件系统是零散的文件。
三、核心硬件抽象层适配 (U-Boot & Kernel)
主要工作目录:<sdk_dir>/device/config/chips/t113/configs/<your_board_name>
ubuntu@ubuntu1804:~/tina5_sdk/T113-Tina5.0-V1.2/device/config/chips/t113/configs/custom_sym_board$ tree -L 2
.
├── bin
│ └── amp_dsp0.bin
├── board.dts -> linux-5.4/board.dts
├── bootlogo.bmp
├── bootlogo.bmp.old
├── boot-resource
│ └── bootlogo.bmp
├── bsp
│ ├── env.cfg
│ └── sys_partition.fex
├── buildroot
│ ├── BoardConfig.mk
│ ├── env.cfg
│ └── sys_partition.fex
├── linux-5.4
│ ├── board.dts
│ └── config-5.4
├── openwrt
│ ├── BoardConfig.mk
│ ├── env.cfg
│ └── sys_partition.fex
├── sys_config.fex
└── uboot-board.dts
6 directories, 17 files
核心硬件全局配置层 (Global Hardware Config)
这部分文件是整个板子的“总纲”,跨越了 Bootloader 和 Kernel,由全志专属的打包工具(pack)直接读取。
sys_config.fex- 专业解析:全志平台特有的硬件描述文件(FEX 格式)。它比 Linux 设备树(Device Tree)生效更早,是整个系统上电后第一道关卡,主要被 Boot0(SPL)和 U-Boot 解析与执行。
- 核心功能:作为早期引导阶段的“硬件总闸”。根据当前板级配置,它主要负责四大核心任务:
- 确立启动介质:声明系统默认的存储类型(
storage_type = 5,即锁定为 SPI NAND 启动)。 - 初始化内存:定义 DRAM 的运行频率(792MHz)、类型及几十项精细的阻抗与时序参数(
[dram_para]),确保主核能正确在内存中跑代码。 - 绑定调试通道:指定 Boot 阶段的底层调试串口(
[uart_para]配置为 UART3 及 PB06/PB07 引脚),确保上电第一秒就能输出 Log。 - 配置刷机与测试接口:初始化用于量产烧录的 SD 卡控制器(
[card0_boot_para])以及底层的 JTAG 硬件调试接口([jtag_para])。
- 确立启动介质:声明系统默认的存储类型(
- 适配重点:当你更换了不同容量/型号的内存颗粒、更改了存储芯片类型(如换成 eMMC),或者需要修改底层 Debug 串口位置时,必须优先修改此文件。
board.dts -> linux-5.4/board.dts- 专业解析:这是一个软链接(Symlink),指向底层特定内核版本里的设备树文件。
- 核心功能:方便开发者在主目录下直接
vim board.dts进行修改,而不需要每次都进入深深的内核目录。
Bootloader 与底层引导层 (Boot & Early Init)
决定了 U-Boot 阶段的硬件状态和视觉呈现。
uboot-board.dts- 专业解析:U-Boot 阶段专属的设备树源文件(Device Tree Source)。现代 U-Boot 引入了类似 Linux 内核的驱动模型(Driver Model),它不再强依赖代码中的硬件宏定义,而是通过解析这个独立的文件来识别和配置硬件。
- 核心功能:为引导阶段提供最关键的底层驱动资源地图。结合源码,其核心功能分为三块:
- 存储总线挂载:初始化了 TF 卡/SD 卡 (
&sdc0,&sdc2)、SPI NOR/NAND Flash (&spi0) 以及原始 NAND Flash (&nand0) 的引脚复用和控制器。这保证了 U-Boot 能顺利从对应介质中读取内核镜像。 - 显示系统先期点亮 (Early Display):包含了
&disp(显示引擎) 和&lcd0节点的完整配置。在这里,指定了屏幕驱动 (fl7707n_mipi)、MIPI DSI 的 4-lane 引脚、以及详细的时序参数(如lcd_ht,lcd_vt等)。正是有了这段配置,U-Boot 才能在进入内核前提前点亮屏幕并显示开机 Logo。 - 安全与内存保护:通过顶部的
firmware/optee节点,为可信执行环境(TEE)划分了专用的安全共享内存(SHM)区域,保障系统的安全引导。
- 存储总线挂载:初始化了 TF 卡/SD 卡 (
- 适配重点:
- 启动介质变更:如果板子修改了 SPI 接口的引脚或换了存储芯片,必须在此文件修正
spi0_pins并在&target节点中检查storage_type。 - 屏幕更换:这是一个高频踩坑点! 如果你更换了屏幕面板,不仅要在 Linux 内核设备树(
board.dts)中修改参数,必须同时在这个文件中同步更新&lcd0的所有时序参数(hbp, vbp 等)和 Reset 引脚 (lcd_gpio_0)。如果两边参数不一致,会导致开机有 Logo,但进入内核瞬间黑屏或花屏的诡异现象。
- 启动介质变更:如果板子修改了 SPI 接口的引脚或换了存储芯片,必须在此文件修正
bootlogo.bmp/bootlogo.bmp.old/boot-resource/bootlogo.bmp- 专业解析:开机第一屏的位图图像资源。
- 核心功能:打包时,
pack工具会将这些 BMP 图片压入启动镜像包中。系统上电几百毫秒内,U-Boot 会直接将此图片推送到 Framebuffer 中显示。
bin/amp_dsp0.bin- 专业解析:T113 芯片内置了一颗 HiFi4 DSP(数字信号处理器),用于音频处理或实时算力卸载。
- 核心功能:这是提供给 DSP 运行的裸机或 RTOS 固件(AMP 异构多核架构)。系统启动时,主核 Cortex-A7 会将这个 bin 文件加载到特定内存区域并唤醒 DSP。
Linux 内核配置层 (Kernel Domain)
进入 Linux 操作系统后,这里是硬件描述和底层驱动配置的**“总闸门”**。
linux-5.4/board.dts- 专业解析:Linux 内核真正的板级设备树文件。它彻底接管了 U-Boot 传递过来的硬件控制权,并以节点(Node)树的形式,向 Linux 内核极其详细地描述了所有外设的物理属性。
- 核心功能:结合本方案源码,其核心功能体现在四大模块的深度定制:
- 外设驱动的实体化 (User Define):包含开发者自定义的硬件绑定。例如通过 GPIO 控制的心跳指示灯(
led_syson PD11)、带 20ms 消抖的用户独立按键(User Keyon PD10),以及 256 级细腻调光的 PWM 背光通道(pwm 7)。 - 显示与触摸子系统:详细定义了
fb0的分辨率(720x1424),挂载了fl7707n_mipi屏幕驱动及&dsi4lane_pins引脚复用;同时在&twi1(I2C1)总线上挂载了gt9xxnew_ts触摸屏控制器,并分配了唤醒(PE4)和中断(PE5)引脚。 - USB 角色与通信:配置了
&usbc0为 OTG 模式(usb_port_type = <0x2>),并绑定了 PE12 作为 VBUS/ID 状态检测引脚,这是实现后续 ADB 通信的物理基础。 - 异构多核内存映射:通过
reserved-memory节点,为 T113 内部的 HiFi4 DSP(dsp0)和 RISC-V 协处理器划分了专用的物理内存区域和共享环形缓冲区(Vring),实现了基于 RPMSG 框架的核间通信。
- 外设驱动的实体化 (User Define):包含开发者自定义的硬件绑定。例如通过 GPIO 控制的心跳指示灯(
- 适配重点:这是 BSP 工程师每天打交道最多的文件。 解决引脚冲突(同一 Pin 被多处占用)、适配屏幕时序、修改 I2C 从设备地址(如触摸屏的
reg = <0x5d>),全部在这里完成。
linux-5.4/config-5.4- 专业解析:内核的系统“菜单”快照(Defconfig 文件)。它记录了执行
make kernel_menuconfig后的最终选择,直接决定了内核编译时哪些代码会参与构建。 - 核心功能:统筹内核的驱动集与系统特性。在当前方案中:
- 模块化驱动加载 (
=m):将XR819/XR829/RTL8723DSWi-Fi 驱动以及GT9XX触摸驱动编译为外置的.ko模块,方便在应用层通过脚本动态加载,优化了开机速度。 - 核心驱动内置 (
=y):将显示引擎(DISP2_SUNXI)、MIPI 屏幕驱动(LCD_SUPPORT_FL7707N_MIPI)、PWM 背光直接编入内核,确保屏幕在开机第一梯队被点亮。 - 现代 USB Gadget 框架:开启了
CONFIG_USB_CONFIGFS及其子宏(ADB、HID、FS),配合全志特有的SUNXI_USB_MANAGER,使得通过脚本动态切换 USB 模式成为可能。
- 模块化驱动加载 (
- 适配重点(排坑提示):当前配置中
CONFIG_DEBUG_INFO=y处于开启状态,这会生成庞大的带调试信息的内核镜像。如果在后续打包 SPI NAND(通常容量仅 128MB)时遇到pack fail(固件体积过大),必须首选关闭此宏进行内核瘦身。另外,底层的低级调试串口已精准锁定为CONFIG_DEBUG_SUNXI_UART3=y,保障了内核崩溃时的 Log 输出。
- 专业解析:内核的系统“菜单”快照(Defconfig 文件)。它记录了执行
文件系统与构建环境层 (OS & Build System Domains)
Tina SDK 支持多种文件系统方案,因此在 configs/custom_sym_board/ 下会看到 bsp、buildroot、openwrt 三个并列的文件夹。目前使用的是 openwrt 目录。
为什么这几个文件要分开放?因为不同的操作系统,其镜像大小和环境变量需求完全不同! 以下是你当前 OpenWrt 方案的核心配置解析:
openwrt/sys_partition.fex(分区表)- 专业解析:固件烧录时的物理存储分区地图。全志的打包工具
pack会严格按照这个文件来切割 Flash 空间,并将编译好的二进制文件塞入对应的区域。 - 核心功能与源码印证:
- 逻辑大小分配:NAND 方案特有的
size单位是“逻辑擦除块”的换算值。例如rootfs分区分配了50400。 - 双备份机制:定义了
env和env-redund两个大小同为504的环境变量分区,这与之前配置的 UBI 双备份卷机制完美契合,防止掉电变砖。 - 用户数据区:预留了
rootfs_data(25200)和不限制大小的UDISK(user_type = 0x8100),用于存放用户自己的应用数据或日志。
- 逻辑大小分配:NAND 方案特有的
- 适配重点:如果开启了大量内核 Debug 宏或装了太多 OpenWrt 软件包,导致
pack时报错size too large,必须来这里调大对应分区的size,同时确保后面的分区不越界。
- 专业解析:固件烧录时的物理存储分区地图。全志的打包工具
openwrt/env.cfg(环境变量)- 专业解析:U-Boot 传递给 Linux 内核的“第一句话”。系统上电后,U-Boot 会读取这个文件并执行里面的命令。
- 核心功能与源码印证:
- 控制台重定向:
console=ttyS3,115200和loglevel=8确保内核启动信息从物理 UART3 引脚全量输出。 - 根文件系统挂载:
nand_root=/dev/ubiblock0_5和rootfstype=squashfs。这明确告诉内核:去第 5 个 UBI 块设备上,以只读压缩格式(SquashFS)挂载根目录。 - 启动命令流 (
bootcmd):这是 U-Boot 的最终执行动作。代码中的bootcmd=run setargs_nand boot_normal,表示先设置 NAND 启动的环境变量(setargs_nand),然后执行boot_normal(将boot分区的镜像读入内存地址43000000并启动)。
- 控制台重定向:
- 适配重点:如果修改了调试串口(比如改回
ttyS0),必须在这里同步修改console=的值,否则内核启动后串口将无输出。
openwrt/BoardConfig.mk(构建统筹配置)- 专业解析:Tina 编译框架的板级总纲。当你执行
lunch选择方案时,构建系统会读取这个文件来确定所需的编译器和核心组件版本。 - 核心功能与源码印证:
- 内核与 U-Boot 绑定:声明内核使用
config-5.4,U-Boot (Brandy 2.0) 使用sun8iw20p1_custom_sym_board_defconfig。 - 环境变量空间:
LICHEE_REDUNDANT_ENV_SIZE:=0x20000(128KB),这与sys_partition.fex中分配给 env 分区的实际大小以及/etc/fw_env.config中的配置是严格对应的。 - 编译器指定:强制使用
gcc-linaro-5.3.1交叉编译链。
- 内核与 U-Boot 绑定:声明内核使用
- 适配重点:如果需要更换内核版本(比如升级到 Linux 5.10),或者更换 U-Boot 的 defconfig 文件,必须在此处修改对应的
LICHEE_KERN_DEFCONF等变量。
- 专业解析:Tina 编译框架的板级总纲。当你执行
外设适配的流程
在通读了上述所有底层架构和配置文件后,我们在日常开发中进行任何外设适配(屏幕、触摸、Wi-Fi 等),都应严格遵循: 看原理图明确引脚 -> 修改设备树(描述硬件) -> menuconfig 勾选驱动(使能软件) -> 编译烧录验证。
如果系统原生已经包含了驱动,我们只需改设备树和勾选菜单;但如果遇到像 FL7707 MIPI 屏幕 这种全志原厂 SDK 未自带的非标外设,我们就需要进行驱动级移植。
以下结合 FL7707 屏幕的移植过程,演示“无中生有”添加新驱动的标准流程:
1. 驱动源码注入 (Code Injection)
由于我需要在开机阶段显示 Logo,且在进入系统后持续显示,因此 U-Boot 和 Kernel 两端都必须移植该屏幕的驱动。
- U-Boot 端路径:通过
croot回到根目录后,进入<sdk>/brandy/brandy-2.0/u-boot-2018/drivers/video/sunxi/disp2/disp/lcd。 - Kernel 端路径:进入
<sdk>/kernel/linux-5.4/drivers/video/fbdev/sunxi/disp2/disp/lcd。 - 动作:在这两个目录下,分别新建
fl7707n_mipi.c和fl7707n_mipi.h文件,并将屏幕厂商提供的初始化序列代码填入其中。
2. 构建系统注册 (Makefile & Kconfig)
放入了 .c 源码,编译系统是不知道的。必须修改同级目录下的构建文件,将其暴露给菜单。
- 修改
Makefile: 在Makefile中添加编译规则,告诉编译器如果宏被打开,就把源码编译成.o文件:
disp-$(CONFIG_LCD_SUPPORT_FL7707N_MIPI) += lcd/fl7707n_mipi.o
- 修改
Kconfig: 在Kconfig中添加菜单选项,让开发者能在界面里看到它:
config LCD_SUPPORT_FL7707N_MIPI
bool "LCD support FL7707N_MIPI panel"
default n
help
If you want to support FL7707N_MIPI panel for display driver, select it.
3. 配置菜单使能 (Menuconfig Activation)
源码和编译规则就绪后,接下来就是打开这个总闸。
- U-Boot 配置:在<sdk_dir>/brandy/brandy-2.0/u-boot-2018/configs目录下找到你的方案所选中的defconfig文件并添加
CONFIG_LCD_SUPPORT_FL7707N_MIPI=y。 - Kernel 配置:执行
make kernel_menuconfig,在Device Drivers -> Graphics support -> Frame buffer Devices -> Video support for sunxi -> LCD panels select中勾选刚才添加的屏幕,并确保背光(Backlight)、触摸(Touchscreen)等相关依赖宏(如CONFIG_BACKLIGHT_CLASS_DEVICE=y)也一并开启。
4. 设备树参数绑定 (DTS Binding)
最后一步,让设备树中的参数与你刚写的驱动“接头”。
- 进入
uboot-board.dts和board.dts。 - 在
&lcd0节点中,将lcd_driver_name严格设定为你刚才添加的驱动名:
&lcd0 {
lcd_used = <1>;
lcd_driver_name = "fl7707n_mipi"; // 必须与源码中注册的名称一致
lcd_if = <4>; // MIPI DSI 接口
// ... 同步填入正确的时序参数 (hbp, vbp, width, height 等)
};
四、文件系统构建与运行环境初始化 (OpenWrt & Init Layer)
主要工作目录:<sdk_dir>/openwrt/target/t113/t113-<your_board_name>/
ubuntu@ubuntu1804:~/tina5_sdk/T113-Tina5.0-V1.2/openwrt/target/t113/t113-custom_sym_board$ tree -L 1
.
├── base-files
├── BoardRules.mk
├── busybox-init-base-files
├── busybox-init-base-files_generate
├── defconfig
├── defconfig_ota
├── Makefile
├── modules.mk
├── swupdate
├── t113_custom_sym_board.mk
├── tina_busybox-init-base-files.mk
├── TinaProducts.mk
└── vendorsetup.sh
4 directories, 9 files
ubuntu@ubuntu1804:~/tina5_sdk/T113-Tina5.0-V1.2/openwrt/target/t113/t113-custom_sym_board/busybox-init-base-files$ tree -L 3
.
├── bin
│ └── setusbconfig
├── data
├── etc
│ ├── asound.conf
│ ├── fw_env.config
│ ├── hostname
│ ├── init.d
│ │ ├── load_script.conf
│ │ ├── rc.final
│ │ ├── rc.modules
│ │ ├── rc.preboot
│ │ └── wifideamon
│ ├── inittab
│ ├── profile
│ ├── udhcpd.conf
│ └── wpa_supplicant.conf
├── home
├── mnt
│ ├── extsd
│ └── sdcard
├── squashfs
└── usr
├── bin
└── lib
├── libbz2.so
├── libbz2.so.1.0
├── libmbedcrypto.so
├── libmbedcrypto.so.3
├── libmbedtls.so
├── libmbedtls.so.11
├── libmbedx509.so
├── libmbedx509.so.0
└── libwpa_client.so
12 directories, 22 files
第一部分:构建系统与包管理控制台 (外层目录)
这层目录不参与板子的实际运行,它是给**编译器(Build System)**看的,决定了最终生成的固件(rootfs)里包含什么内容。
defconfig&defconfig_ota(系统菜单快照)- 专业解析:系统软件包的“采购清单”。当你执行
make menuconfig并在Base system、Network等菜单中勾选了某些工具(如adb、wpa_supplicant)后,所有的选择最终都会沉淀并保存在这两个文件中。 - 适配重点:如果系统缺命令(如敲
ifconfig提示 command not found),第一反应就应该来这里检查对应的包有没有被选上。
- 专业解析:系统软件包的“采购清单”。当你执行
modules.mk(内核模块打包规则)- 专业解析:内核
.ko模块进入文件系统的“通行证”。你在kernel_menuconfig中将某个驱动编译成模块(=m),它仅仅会生成在内核目录下。想要让它随系统打包进/lib/modules/并在开机时加载,必须在这里显式声明。 - 源码印证:从提供的源码中可以看到两个核心模块的注册:
- 摄像头驱动 (
sunxi-vin-n5_dvp):不仅声明了需要拷贝videobuf2-memops.ko等 5 个底层驱动文件,还用KCONFIG锁定了它对CONFIG_MEDIA_SUPPORT等内核宏的强制依赖。 - Wi-Fi 驱动 (
net-rtl8723ds):声明了拷贝8723ds.ko,更重要的是使用了AUTOLOAD:=$(call AutoProbe,8723ds)。这句魔法代码告诉 OpenWrt 系统:不仅要把驱动打包进去,还要在开机时自动调用modprobe去加载它!
- 摄像头驱动 (
- 适配重点:高频踩坑点! 如果你发现内核编译出了
.ko但板子里找不到,或者开机不会自动加载(比如你的 Wi-Fi 或触摸屏不工作),一定要来这里检查是否写漏了$(eval $(call KernelPackage,xxx))。
- 专业解析:内核
.mk家族与构建骨架 (t113_custom_sym_board.mk,TinaProducts.mk)- 专业解析:编译框架的“粘合剂”与目标定义。
- 源码印证:
t113_custom_sym_board.mk中极其关键的一句:PRODUCT_DEVICE := t113-custom_sym_board。这不仅是板子的名字,更是编译系统在target/目录下寻址文件夹的唯一依据。TinaProducts.mk则是 Android 编译系统的遗留产物,负责将上述.mk文件抛出给全局的 Makefile 树。
vendorsetup.sh- 专业解析:编译环境注册脚本。
- 作用:里面只有一行代码
add_lunch_combo t113-custom_sym_board。执行source build/envsetup.sh后,它负责把你的方案挂到lunch的交互式选择菜单里。
tina_busybox-init-base-files.mk(自定义 Init 脚本生成器)- 专业解析:当我们将系统启动方式从
procd切换为busybox init后,这个 Makefile 负责执行hook脚本(rootfs_hook_squash.sh)。 - 作用:它会在编译的最后阶段,动态生成并清理
busybox-init-base-files目录下的/etc/init.d/脚本群(如你源码中注释掉的S40network、S50usb等),从而确保最终的根文件系统拥有干净、定制化的启动逻辑。
- 专业解析:当我们将系统启动方式从
swupdate/- 专业解析:OTA 升级策略目录。
- 作用:里面存放了
sw-description等文件,定义了在双分区备份架构(如前面sys_partition.fex中划分的两个env分区)下,系统如何校验并安全地覆写远程下发的固件。
第二部分:文件系统骨架与开机脚本 (内层目录)
目录位置: .../busybox-init-base-files/
核心概念(Overlay 覆盖机制): 这个目录是一个“覆盖层”。编译时,这里面的所有文件会原封不动地、按照同等目录结构,直接拷贝到最终板子的根目录(/)下,覆盖掉 OpenWrt 原生的默认文件。
1. 系统生命周期控制 (etc/)
这是整个嵌入式系统启动的“大纲”。
etc/inittab- 专业解析:内核启动后接管系统的第一个配置文件。
- 作用:它告诉 BusyBox 的
init进程:开机先去执行rc.preboot,最后把命令行的控制台(Shell)抛给哪个物理串口(例如ttyS3)。
etc/init.d/(启动脚本三部曲)rc.preboot:最先执行。主要挂载sysfs、procfs等虚拟文件系统,初始化最基础的环境。rc.modules:重中之重! 按照顺序执行insmod来加载底层驱动(例如你的触摸屏gt9xxnew_ts.ko和 Wi-Fi8723ds.ko)。rc.final:开机前的临门一脚。通常在这里执行amixer设置音频通路音量,或者执行setusbconfig adb拉起调试服务。
2. 系统外围配置 (etc/)
etc/fw_env.config- 专业解析:U-Boot 与 Linux 的“翻译官”。
- 作用:告诉 Linux 系统的
fw_printenv命令,去 NAND Flash 的哪个物理块读取 U-Boot 的环境变量。没有它,Linux 下无法读写启动参数。
etc/wpa_supplicant.conf&udhcpd.conf- 作用:前者配置 Wi-Fi 的连接账号、密码和 Socket 路径;后者配置板子做 AP 热点时,给其他设备分配 IP 的 DHCP 服务器规则。
etc/asound.conf- 作用:ALSA 声卡的高级路由配置,比如软件混音或重采样。
3. 预编译二进制与动态库 (bin/ & usr/lib/)
bin/setusbconfig- 作用:全志提供的一个现成的二进制小工具。你在
rc.final里就是调用它,通过操作 ConfigFS 快速把 USB 接口切换成 ADB 或 U 盘模式的。
- 作用:全志提供的一个现成的二进制小工具。你在
usr/lib/(如libmbedtls.so,libwpa_client.so)- 专业解析:预置的共享动态链接库。
- 作用:有些底层库(如 MbedTLS 加密库,供 Wi-Fi 使用)编译太慢或有特定的版本依赖,原厂直接把编译好的
.so文件放在这里,打包时直接塞入固件,省去了重新编译的麻烦。
附录:BSP 硬核调试工具箱速查表
| 调试维度 | 核心命令 / 工具集 | 专业功能定义 | 结合 T113 LVGL 智能面板项目的实战应用 |
|---|---|---|---|
| 源码编译配置检索 | `find . -name “*.mk” | xargs grep -Hn “xxx”` | 构建规则与宏定义追踪:在高度耦合的 Makefile 树中执行深层文本匹配,定位内核宏或编译选项的声明位置。 |
| 方案版本控制 | git diff --no-index <Dir_A> <Dir_B> | 跨目录树差异比对:在脱离 Git 仓库的物理目录间进行逐行代码比对。 | Init 框架迁移验证:在将启动方式从 procd 切换至 busybox init 时,对比原 evb1 方案与 custom_sym_board 的 busybox-init-base-files 差异,确认自启脚本覆盖情况。 |
| 打包流程校验 | `cat out/…/pack_out/sys_config.fex | grep lcd` | 固件打包前置校验:直接读取 pack 工具汇聚后的中间产物,验证硬件描述配置(FEX)的最终合成状态。 |
| 硬件级寄存器操作 | devmem <物理地址> [位宽] [值] | 物理内存与寄存器直接寻址:绕过内核保护机制,直接读写 SoC 内部控制寄存器。 (注:越界操作会引发 Kernel Panic) | Pin Mux 硬件状态核验:若怀疑 board.dts 中的引脚复用未生效,直接读取 T113 手册中 PD20(LCD Reset)或 PD22(PWM7)的寄存器基地址,验证硬件层面的输入/输出状态及电平。 |
| I2C 总线通信 | i2cdetect -y -r <总线号> i2cdump / i2cget | I2C 设备枚举与通信验证:扫描指定 I2C 总线上的从设备地址,验证时钟与数据线的电气连通性。 | GT9xx 触摸屏排障:在 LVGL 缺少触摸反馈时,扫描 T113 的 &twi1 (I2C1)。若显示 5d,证明 I2C 硬件通信正常;若显示 UU,证明该地址已被 gt9xxnew_ts.ko 驱动成功接管。 |
| ALSA 音频链路 | aplay -l / arecord amixer | 音频子系统底层路由控制:脱离应用层(如 GStreamer/PulseAudio),直接控制 Codec 芯片的 DAC/ADC 增益及数据流。 | 中控语音提示调试:在使用 LVGL 播放按键音前,先通过 amixer 设置底层通道,解除 DAC 静音状态并分配 HPOUT 路由,随后用 aplay 直接播放测试音频,隔离应用层错误。 |
| 网络栈与带宽 | wifi -o sta -c "SSID" "PWD" iperf -c <IP> -t 10 | WLAN 协议栈激活与吞吐量评估:在终端拉起 wpa_supplicant 进行鉴权,并通过 TCP/UDP 流量打压测试 SDIO 接口性能。 | OTA 及远程资源就绪:依赖 rc.modules 加载的 8723ds.ko 连接无线路由。通过 iperf 测试吞吐量,评估后续 LVGL 界面从网络拉取天气数据或进行整机 OTA 固件下载的网络可靠性。 |
| USB 主从枚举 | lsusb adb kill-server / devices | USB 总线拓扑分析与守护进程管理:查看设备枚举状态,重启上位机 ADB Server 清理僵尸进程及权限。 | 无线/有线调试桥建立:验证 rc.final 中的 setusbconfig adb,hid 命令。确认 T113 的 OTG 接口(PE12 ID 引脚检测)成功作为 Device 被上位机识别(VID:18d1 PID:d002),为后续 adb push LVGL 编译产物提供通道。 |
| 内核态运行追踪 | `dmesg | grep -i panel lsmod` | 内核环形缓冲区日志过滤与模块依赖审查:提取驱动 Probe 阶段的警告/错误上下文,确认 LKM(可加载内核模块)的驻留状态。 |
| GPIO 伪驱动控制 | echo 118 > /sys/class/gpio/export … | Sysfs 虚拟文件系统 IO 控制:利用内核导出的 sysfs 节点,强行改变 GPIO 方向与电平,替代传统的硬连线测试。 | 背光电路物理验证:当屏幕背光不亮时,绕过 PWM 软件驱动,将 PD22(118号引脚)强制配置为 out 并拉高至 1,以此区分是 T113 芯片端无输出,还是背光升压电路硬件损坏。 |
| 显示子系统同步 | cat /sys/class/disp/disp/attr/sys | 显示控制器(DE)状态查询:获取 Display Engine 的垂直同步(vsync)、图层(Layer)配置及硬件报错统计。 | LCD 时序握手诊断:在 LVGL 应用程序启动前,读取该节点确认 T113 的 DISP 模块是否在持续输出 vsync 信号,判定主板控制器与 FL7707 屏幕接口的物理同步状态。 |
五、 全局总结与后续开发展望
通过上述四个核心阶段的深度拆解与实战,我们完成了一块基于 T113-S3 芯片的新主板从“点亮”到“完全可用”的全链路移植闭环。
- 向下扎根(底层破冰):理清了 SPI NAND 的启动逻辑,精准配置了 U-Boot 与 Linux Kernel 的软硬件交接点(FEX 与 DTS),并成功完成了 FL7707 MIPI 屏幕等非标外设的驱动级移植与时序同步。
- 向上生长(系统重构):通过果断剥离 OpenWrt 黑盒的
procd,换用线性可控的busybox init框架,彻底接管了系统的启动生命周期。如今,Wi-Fi 动态加载、ADB 调试通道、底层的音视频路由均已在开机时顺畅就绪。 - 排障体系建立:文档最后沉淀的“BSP 硬核调试工具箱”,将排错维度从单纯的看 Log 提升到了物理寄存器级(
devmem)、总线级(i2c-tools)和状态机级(sysfs)。这套工具和排障逻辑,将是未来应对复杂客诉或莫名死机问题时的核心武器。
底层的“修路”工作已经圆满竣工,一块拥有健壮网络、顺畅交互与高清显示的系统基石已经搭建完毕。舞台准备就绪,系统的核心任务将正式由“驱动硬件”转向“业务实现”。
更多推荐
所有评论(0)