TinaSDK Linux Kernel 基本使用(全志T113开发板)

TinaSDK Linux Kernel 基本使用(全志T113开发板)

本文基于全志Tina-SDK,详细介绍如何配置、编译、修改Linux内核,涵盖内核源码位置、设备树、环境变量、Kconfig/menuconfig配置、打印等级调整、打包烧录等完整流程。你将会学到:在Tina-SDK中单独编译内核、用make kernel_menuconfig裁剪/配置内核、修改内核打印级别、打包生成镜像并烧录验证。文末附面试高频题。


文章目录

    • [TinaSDK Linux Kernel 基本使用(全志T113开发板)](#TinaSDK Linux Kernel 基本使用(全志T113开发板))
    • [一、Tina-SDK Linux系统启动流程简介](#一、Tina-SDK Linux系统启动流程简介)
    • 二、内核源码与设备树的位置
      • [2.1 内核源码目录](#2.1 内核源码目录)
      • [2.2 板级内核配置文件(defconfig片段)](#2.2 板级内核配置文件(defconfig片段))
      • [2.3 板级设备树文件(board.dts)](#2.3 板级设备树文件(board.dts))
    • 三、环境变量(bootargs)配置
    • 四、设备树打包与U-Boot中的fdt切换
      • [4.1 boot_package.cfg 描述设备树位置](#4.1 boot_package.cfg 描述设备树位置)
      • [4.2 U-Boot中切换生效的设备树](#4.2 U-Boot中切换生效的设备树)
    • 五、单独编译Linux内核
      • [5.1 准备环境](#5.1 准备环境)
      • [5.2 执行单独编译](#5.2 执行单独编译)
    • [六、Kconfig 配置方法(menuconfig 使用详解)](#六、Kconfig 配置方法(menuconfig 使用详解))
      • [6.1 进入内核配置界面](#6.1 进入内核配置界面)
      • [6.2 菜单符号含义](#6.2 菜单符号含义)
      • [6.3 实际操作示例:进入 Device Drivers 并理解符号](#6.3 实际操作示例:进入 Device Drivers 并理解符号)
      • [6.4 修改选项:以 Multimedia support 为例](#6.4 修改选项:以 Multimedia support 为例)
      • [6.5 查看选项依赖关系(Help界面)](#6.5 查看选项依赖关系(Help界面))
      • [6.6 搜索功能(/ 键)](#6.6 搜索功能(/ 键))
      • [6.7 实战任务:调整内核默认打印等级(从7改为4)](#6.7 实战任务:调整内核默认打印等级(从7改为4))
    • 七、打包内核生成最终烧录镜像
    • 八、烧录与验证
      • [8.1 烧录方式](#8.1 烧录方式)
      • [8.2 验证内核打印等级](#8.2 验证内核打印等级)
    • 九、面试官提问环节
    • 十、总结

一、Tina-SDK Linux系统启动流程简介

在全志T113平台中,整个系统从上电到应用运行的顺序为:

boot0 → optee → uboot → env → linux → dtb → dsp → rootfs → app

  • boot0:一级引导程序,初始化DDR等。
  • optee:可信执行环境(可选)。
  • uboot:U-Boot引导加载程序。
  • env:U-Boot环境变量。
  • linux:内核镜像(zImage / uImage)。
  • dtb:设备树二进制。
  • dsp:数字信号处理器固件(如有)。
  • rootfs:根文件系统。
  • app:用户应用程序。

理解这个顺序有助于排查启动卡在哪个阶段。


二、内核源码与设备树的位置

在Tina-SDK中,内核源码和设备树配置都位于特定目录,SDK提供了快捷命令方便跳转。

2.1 内核源码目录

路径lichee/linux-5.4

bash

复制代码
# 进入SDK根目录后
cd lichee/linux-5.4

快捷命令 :在source build/envsetup.sh之后,任意目录下执行 ckernel 即可直接跳转到内核源码根目录。

bash

复制代码
source build/envsetup.sh
lunch 4   # 选择t113_100ask-tina
ckernel
pwd
# 输出:/home/ubuntu/tina-d1-h/lichee/linux-5.4

2.2 板级内核配置文件(defconfig片段)

路径device/config/chips/t113/configs/100ask/linux/config-5.4

这个文件是T113百问网开发板的内核配置文件 (实际是一个config fragment,与通用配置合并生成最终.config)。

快捷命令 :执行 ccconfigs 会直接进入该目录。

bash

复制代码
ccconfigs
ls
# board.dts  config-5.4  config-5.4-mem-optimize

2.3 板级设备树文件(board.dts)

路径device/config/chips/t113/configs/100ask/board.dts(实际是一个软链接指向 linux-5.4/board.dts

bash

复制代码
ls -l board.dts
# board.dts -> linux-5.4/board.dts

该设备树文件包含 了父级芯片设备树 sun8iw20p1.dtsi,其完整路径为:

bash

复制代码
lichee/linux-5.4/arch/arm/boot/dts/sun8iw20p1.dtsi

快捷命令 :执行 cdts 可直接跳转到内核源码下的设备树目录。

bash

复制代码
cdts
pwd
# /home/ubuntu/tina-d1-h/lichee/linux-5.4/arch/arm/boot/dts

注意:board.dts 是最终板级设备树,其中通过 #include "sun8iw20p1.dtsi" 引入基础定义,然后追加或覆盖板级特性。


三、环境变量(bootargs)配置

内核启动命令行(bootargs)由U-Boot环境变量传递。在Tina-SDK中,默认启动参数定义在文件:

路径device/config/chips/t113/configs/100ask/env.cfg

打开该文件,你会看到以下关键片段:

bash

复制代码
#kernel command arguments
earlyprintk=sunxi-uart,0x02500C00
initcall_debug=0
console=ttyS3,115200
nand_root=/dev/ubiblock0_5
mmc_root=/dev/mmcblk0p5
mtd_name=sys
rootfs_type=squashfs
root_partition=rootfs
boot_partition=boot
init=/sbin/init
loglevel=8
cma=8M
...

# 定义nand启动时的bootargs
setargs_nand=setenv bootargs ubi.mtd=${mtd_name} ubi.block=0,${root_partition} earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${nand_root} rootfstype=${rootfs_type} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1

# 定义mmc启动时的bootargs
setargs_mmc=setenv bootargs earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${mmc_root} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1

# U-Boot自身配置
bootdelay=1
bootcmd=run setargs_nand boot_normal

重要参数解读

  • console=ttyS3,115200:调试串口为UART3,波特率115200。
  • loglevel=8:内核打印级别最高(所有信息都输出)。
  • root=/dev/ubiblock0_5/dev/mmcblk0p5:根文件系统所在分区。
  • rootwait(隐含在setargs中):等待设备就绪。
  • bootdelay=1:U-Boot倒计时1秒。

修改env.cfg后需要重新编译打包才会生效。也可以在U-Boot命令行中临时修改并保存。


四、设备树打包与U-Boot中的fdt切换

4.1 boot_package.cfg 描述设备树位置

文件 device/config/chips/t113/configs/default/boot_package.cfg 包含了打包时要合并的各个组件:

bash

复制代码
[package]
item=u-boot, u-boot.fex
item=optee, optee.fex
item=scp, scp.fex
item=logo, bootlogo.bmp.lzma
item=shutdowncharge, bempty.bmp.lzma
item=androidcharge, battery_charge.bmp.lzma
item=dtb, sunxi.fex

其中 item=dtb, sunxi.fex 表示设备树文件会被打包为 sunxi.fex,在U-Boot启动时会加载该设备树。

4.2 U-Boot中切换生效的设备树

U-Boot启动过程中,可能会使用两份设备树:一份是U-Boot自己的(用于驱动显示、存储等),另一份是内核设备树。在U-Boot命令行中,可以使用 set_working_fdt 命令切换当前生效的设备树(用于调试)。

bash

复制代码
=> set_working_fdt 0x7bebee58
change working_fdt 0x7be8ee58 to 0x7bebee58

这通常用于在烧录前验证设备树修改是否正确。


五、单独编译Linux内核

在Tina-SDK中,单独编译内核非常方便,使用 mkernel 命令即可。

5.1 准备环境

每次新开终端,都需要先加载环境:

bash

复制代码
source build/envsetup.sh
lunch
# 选择 4. t113_100ask-tina

如果之前编译过且有缓存问题,建议先清理:

bash

复制代码
make clean   # 清理整个SDK的编译产物

然后重新 lunch 选择正确的单板。

5.2 执行单独编译

bash

复制代码
mkernel

mkernel 会根据当前配置:

  • 合并板级配置文件(device/config/.../config-5.4)和通用配置,生成最终.config
  • 交叉编译内核,生成zImage(或uImage)和设备树
  • 自动挂载模块编译(如果需要)
  • 最后生成用于打包的内核镜像

编译成功时你会看到类似的结束信息:

bash

复制代码
#### make completed successfully (25 seconds) ####

注意mkernel 只会编译内核及设备树,不会重新编译U-Boot、rootfs等,因此非常快(几秒到半分钟)。如果你修改了内核Kconfig配置,它会自动检测并重新生成.config


六、Kconfig 配置方法(menuconfig 使用详解)

这是本节最重要的技能:如何通过图形化菜单修改内核配置。

6.1 进入内核配置界面

bash

复制代码
make kernel_menuconfig

你会看到类似下面的菜单(蓝底白字):

6.2 菜单符号含义

在菜单中,每个选项前有不同的符号,表示该选项的状态和可能的操作。

符号 含义 操作键
[ ] 未选中(不编译) Y 变为 [*];按 N 保持
[*] 编译进内核(built-in) N 变为 [ ];按 M 变为 <M>(如果支持)
<M> 编译为模块(module) Y 变为 [*];按 N 变为 [ ]
< > 未选中,但支持模块 Y 变为 [*];按 M 变为 <M>
-*- 被其他选项强制选中,无法修改 需查看依赖关系
-M- 被其他选项强制选为模块 需查看依赖关系

操作键

  • Y:选中为 built-in
  • M:选中为 module(如果支持)
  • N:排除
  • 空格:循环切换(适用部分情形)
  • ?:查看当前选项的帮助信息(包括依赖关系)

6.3 实际操作示例:进入 Device Drivers 并理解符号

在 menuconfig 主界面,选择 Device Drivers ---> 回车进入。

你会看到很多驱动类目,有些前面是 < >,有些是 [ ],还有些是 <M>。例如:

text

复制代码
< >   Memory Technology Device (MTD) support
<*>   Block devices
[ ]   Network device support
<M>   USB support
  • < > MTD support:未选中,但可以编为模块。
  • <*> Block devices:已选中且为 built-in。
  • [ ] Network device support:未选中,且不支持模块(只能 built-in或排除)。
  • <M> USB support:已选为模块。

6.4 修改选项:以 Multimedia support 为例

使用方向键 移动到 Multimedia support 行。目前可能是 [ ]< >。按下 空格 键或 Y 键:

  • 第一次按 空格:变为 <M>(模块)。
  • 第二次按 空格:变为 [*](built-in)。
  • 第三次按 空格:变回 [ ](排除)。

也可以直接按 Y 变成 [*],按 M 变成 <M>,按 N 变成 [ ]

6.5 查看选项依赖关系(Help界面)

如果遇到某个选项是灰色的或者前面是 -*-(被强制选中),你可以查看它的依赖项。选中该选项后按 ? 键(或选择下方的 <Help>)。

例如 Hardware Monitoring support 选项,进入其 Help 页面会显示:

在这里插入图片描述

text

复制代码
Symbol: HWMON [=y]
Type : boolean
Prompt: Hardware Monitoring support
Location:
    -> Device Drivers
(1)   -> Hardware Monitoring support
  Depends on: HAS_IOMEM [=y]
  Selected by: SENSORS_ABITUGURU3 [=n] && HWMON [=y] ...

这告诉你:该选项依赖于 HAS_IOMEM,并且被其他选项(如 SENSORS_ABITUGURU3)选择。如果你试图取消它,需要先取消那些选中它的选项。

6.6 搜索功能(/ 键)

当你不确定某个配置项在哪里时,可以使用搜索。在 menuconfig 界面按 / 键,弹出搜索框。

例如搜索 icn6202(一款LCD驱动IC),输入后回车:

text

复制代码
Search Results
Symbol: LCD_SUPPORT_ICN6202 [=y]
Location:
  -> Device Drivers
    -> Graphics support
      -> Frame buffer Devices
        -> Video support for sunxi
          -> LCD support icn6202 panel (LCD_SUPPORT_ICN6202)

按对应的数字(比如 1)即可直接跳转到该选项位置。

6.7 实战任务:调整内核默认打印等级(从7改为4)

需求:降低内核默认控制台打印级别,减少启动时的冗余信息。

步骤

  1. 在 menuconfig 中按 / 键,搜索 printk
  2. 你会看到多个结果:
    • Enable support for printk(基本支持,保持y)
    • Delay each boot printk message(不重要)
    • Early printk(用于调试,保持y)
    • 关键项:CONFIG_MESSAGE_LOGLEVEL_DEFAULT
  3. 选择 CONFIG_MESSAGE_LOGLEVEL_DEFAULT,回车进入位置(在 Kernel hackingprintk and dmesg options)。
  4. 你会看到一行:

text

复制代码
(7) Default message log level (1-7)
  1. 按回车,将 7 改为 4,然后按 OK
  2. 保存配置(退出时选择保存为 .config)。

修改后的效果:内核默认控制台打印级别从 KERN_WARNING (4) 变成了 KERN_ERR (3) 等更低级别,启动信息会大幅减少。

注意:loglevel 内核启动参数可以运行时覆盖;但修改默认值可以避免每个板子都要加参数。


七、打包内核生成最终烧录镜像

内核编译完成后(无论是否修改配置),执行打包命令:

bash

复制代码
pack

pack 命令会:

  • 收集 U-Boot、optee、内核镜像、设备树、rootfs 等
  • 按照分区表(sys_partition.fex)打包成单个 .img 文件
  • 最终输出路径类似:

text

复制代码
/home/ubuntu/tina-d1-h/out/t113-100ask/tina_t113-100ask_uart3.img

打包成功后,尾部会显示:

text

复制代码
pack finish

使用 ls -lh 可看到镜像大小(约43MB)。

bash

复制代码
ls -lh out/t113-100ask/tina_t113-100ask_uart3.img
# -rwxrwxr-x 1 ubuntu ubuntu 43M Mar 12 07:37 ...img

可以通过 VMware 拖拽、共享文件夹或 scp 将此镜像复制到 Windows,然后使用 PhoenixSuit 或 PhoenixCard(推荐线刷)烧录到开发板的 SPI NAND 或 TF 卡。


八、烧录与验证

8.1 烧录方式

  • 线刷(推荐) :使用 PhoenixSuit 将 tina_t113-100ask_uart3.img 烧录进 SPI NAND。开发板需进入烧录模式(按住烧录键然后上电)。
  • TF卡方式:使用 PhoenixCard 制作启动卡。

具体步骤参考官方文档或视频。

8.2 验证内核打印等级

启动开发板,进入系统后,执行:

bash

复制代码
cat /proc/sys/kernel/printk

输出四个数字,分别代表:当前控制台日志级别、默认消息日志级别、最低控制台日志级别、默认控制台日志级别。

如果你将 CONFIG_MESSAGE_LOGLEVEL_DEFAULT 改为4,那么第二个数字应该是4。实际输出示例:

text

复制代码
8    4    1    7

说明当前控制台级别仍是8(可能被内核命令行参数覆盖),但默认消息级别已变成4。若想令 quiet 生效,可以在U-Boot中修改 loglevel 环境变量。


九、面试官提问环节

第1问:Tina-SDK中如何单独编译Linux内核?用什么命令?

参考答案

使用 mkernel 命令。前提是需要先 source build/envsetup.shlunch 选择正确的单板。mkernel 只编译内核,不重新编译U-Boot和根文件系统,大大提高调试效率。


第2问:在内核配置 make kernel_menuconfig 中,选项前的 <*><M>[ ] 分别代表什么?如何修改?

参考答案

  • <*>:该功能编译进内核(built-in),内核镜像包含了它,无法卸载。
  • <M>:编译为内核模块(module),生成 .ko 文件,可动态加载/卸载。
  • [ ]:排除,不编译该功能。

使用 Y 键变为 <*>M 键变为 <M>N 键变为 [ ]。某些选项只支持 built-in 或排除,没有 <M>


第3问:如果某个配置选项是灰色的无法修改,如何查看它的依赖关系?

参考答案

选中该选项后按 ? 键(或选择界面下方的 <Help>)。在帮助页面中,可以看到 Depends onSelected by 信息。灰色表示依赖条件不满足(比如 depends on XXX 未选中),或者被其他选项强制选中。需要先修改那些依赖项或取消选中它的上游选项。


第4问:在 make kernel_menuconfig 中如何快速定位一个驱动选项(例如 icn6202)?

参考答案

/ 键进入搜索模式,输入关键词 icn6202,搜索结果会列出匹配的符号及其路径。按对应数字可直接跳转到该选项所在位置。


第5问:内核默认的 printk 打印级别如何修改?修改后如何验证?

参考答案

进入 make kernel_menuconfigKernel hackingprintk and dmesg optionsDefault message log level (1-7),将值从7改为所需数字(例如4)。保存配置,重新编译内核并烧录。启动后执行 cat /proc/sys/kernel/printk,观察第二个数字是否变为修改的值。


十、总结

本文覆盖了Tina-SDK中Linux内核开发的完整流程:

  • 熟悉内核源码、设备树、环境变量的存放位置及快捷命令。
  • 学会单独编译内核(mkernel)。
  • 掌握 make kernel_menuconfig 修改配置:符号含义、依赖查看、搜索功能、打印级别调整。
  • 打包(pack)、烧录、验证。

这些技能是嵌入式Linux工程师的必备基础,在实际工作中会频繁使用。建议你在开发板上反复练习,直至能够熟练裁剪内核、调试启动参数。

相关推荐
嵌入式×边缘AI:打怪升级日志2 小时前
Linux内核基础完全入门指南(理论篇)
linux·运维·服务器
Muyuan19982 小时前
28.Paper RAG Agent 开发记录:修复 LLM Rerank 的解析、Fallback 与可验证性
linux·人工智能·windows·python·django·fastapi
比昨天多敲两行2 小时前
Linux进程概念
linux·运维·服务器
HLC++2 小时前
Linux的基本指令+权限+基础开发工具
linux·运维·服务器
一拳一个娘娘腔2 小时前
红队与蓝队视角:现代网络安全攻防中的Linux命令深度解析
linux·安全
daino3 小时前
国内 PyPI 常用镜像源汇总(HTTPS 版)
运维
以太浮标3 小时前
华为eNSP模拟器综合实验之- MGRE多点GRE隧道详解
运维·网络·网络协议·网络安全·华为·信息与通信
杨云龙UP4 小时前
ODA运维实战:Oracle 19c YJXT PDB表空间在线扩容全过程_20260503
linux·运维·服务器·数据库·oracle
郝学胜-神的一滴4 小时前
跨平台动态库与头文件:从原理到命名的深度解析
linux·c++·程序人生·unix·cmake