2. 开发环境搭建:Ubuntu虚拟机安装、Tina SDK获取与解压、编译环境依赖安装、首次编译体验

说实话,做嵌入式Linux开发,环境搭建往往是第一道坎。很多新手一上来就被各种依赖报错劝退了。我当年第一次搞全志平台时,光装依赖就折腾了大半天。嗯,今天咱们就把这事捋清楚,一步到位。

2.1 Ubuntu虚拟机安装

我个人习惯用VMware Workstation,当然VirtualBox也行。Tina SDK官方推荐Ubuntu 18.04或20.04 LTS,我建议你直接用20.04,兼容性更好。

硬件建议: 至少分配4核CPU、8GB内存、80GB硬盘空间。编译时CPU会跑满,内存不够容易OOM。

安装步骤很简单,但有几个坑要注意:

  1. 下载Ubuntu 20.04.6 LTS镜像 —— 别下成Server版,要Desktop版
  2. 创建虚拟机时选"稍后安装操作系统" —— 这样能手动调配置
  3. 磁盘类型选NVMe —— 比SATA快不少,编译能省几分钟
  4. 网络适配器选NAT模式 —— 方便共享主机网络

装完系统后,第一件事换源。国内用清华或阿里源,不然下载SDK能急死人。

# 备份原源
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

# 替换为清华源(Ubuntu 20.04)
sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo sed -i 's/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list

sudo apt update && sudo apt upgrade -y

2.2 Tina SDK获取与解压

Tina SDK通常由芯片原厂或方案商提供。我接触过的有两种获取方式:

方式 来源 特点
官方发布包 全志开发者社区 / 客户专区 版本稳定,文档齐全
Git仓库 公司内部GitLab / 原厂Git 更新频繁,可能包含未发布补丁

拿到压缩包后,解压前先检查MD5校验值。我曾经遇到过下载损坏的情况,编译到一半报错,排查了半天才发现是SDK包坏了。

# 校验MD5
md5sum tina-sdk-v2.0.tar.gz

# 解压(建议用tar,别用图形界面解压,容易丢权限)
tar -xzf tina-sdk-v2.0.tar.gz -C ~/workspace/

# 解压后目录结构
cd ~/workspace/tina-sdk-v2.0/
ls -la
注意: 解压路径不要包含中文或空格,不要放在共享目录或NTFS分区上。Linux原生文件系统(ext4)性能最好,符号链接也不会出问题。

2.3 编译环境依赖安装

Tina SDK的编译依赖比较多。官方文档里列了一长串,但实际项目中我发现有些包是冗余的,有些又漏了。下面是我整理的最小依赖集:

sudo apt install -y \
    build-essential \
    git \
    swig \
    python3-dev \
    python3-pip \
    libncurses5-dev \
    libncursesw5-dev \
    zlib1g-dev \
    libssl-dev \
    libffi-dev \
    gettext \
    file \
    unzip \
    bc \
    bison \
    flex \
    u-boot-tools \
    device-tree-compiler \
    cpio \
    rsync \
    dos2unix

为什么强调这些?我踩过几个坑:

  • libncurses-dev 不装的话,make menuconfig 界面显示乱码
  • device-tree-compiler 缺失会导致设备树编译失败,而且报错信息很隐晦
  • dos2unix 用来处理Windows下编辑过的脚本,换行符不对会报语法错误

装完后验证一下关键工具:

gcc --version
python3 --version
make --version
dtc --version

2.4 首次编译体验

环境搭好了,咱们来跑一遍完整流程。第一次编译主要是验证环境,顺便熟悉SDK的操作方式。

2.4.1 配置目标平台

cd ~/workspace/tina-sdk-v2.0/
source build/envsetup.sh   # 加载编译环境
lunch                      # 选择目标平台

lunch 后会列出所有支持的开发板。我手头是R329开发板,所以选对应的序号。如果你不确定,可以看SDK里的 target/allwinner/ 目录,里面每个子目录对应一个平台。

2.4.2 make menuconfig

这是配置内核和系统组件的核心界面:

make menuconfig

你会看到一个蓝底白字的菜单界面。这里可以配置:

  • Kernel modules —— 内核模块开关
  • Filesystem packages —— 文件系统里装哪些应用
  • Hardware drivers —— 外设驱动选择
  • Boot options —— 启动参数

第一次编译先别改任何配置,直接按 Exit 保存退出。确认一下配置是否生效:

# 查看生成的.config文件
ls -la .config
wc -l .config   # 一般有3000-5000行

2.4.3 开始编译

make -j$(nproc)

-j$(nproc) 表示用所有CPU核心并行编译。我第一次编译R329的SDK,大概用了40分钟。期间可以去喝杯咖啡,但别关终端——编译过程中会输出大量信息,如果报错能第一时间看到。

编译产物: 编译完成后,在 out/ 目录下会生成镜像文件,包括boot.img、rootfs.img、system.img等。这些就是最终要烧录到开发板上的固件。

2.5 SDK目录结构解析

编译完了,咱们来解剖一下SDK的目录结构。搞清楚每个目录干什么,后面开发才能找对地方。

tina-sdk-v2.0/
├── build/               # 编译系统核心脚本
├── config/              # 全局配置文件
├── device/              # 设备相关配置(dts、分区表等)
├── kernel/              # Linux内核源码
├── lichee/              # 启动引导(boot0、uboot)
├── out/                 # 编译输出目录
├── package/             # 应用软件包(Makefile + 源码)
├── prebuilt/            # 预编译工具链
├── target/              # 目标平台配置
├── tools/               # 主机端工具
├── build.sh             # 一键编译脚本
└── envsetup.sh          # 环境初始化脚本

几个重点目录我展开说说:

目录 作用 你以后会经常打交道的子目录
device/ 设备树、分区表、板级配置 device/config/chips/ 下按芯片分
kernel/ Linux内核源码 + 驱动 kernel/linux-4.9/drivers/
package/ 用户态应用和库 package/allwinner/ 全志自研组件
out/ 编译产物 out/<平台>/ 下按镜像类型分

举个例子,如果你想修改某个GPIO的驱动配置,路径大概是:

device/config/chips/r329/configs/default/board.dts   # 设备树源文件
kernel/linux-4.9/drivers/gpio/                       # GPIO驱动源码

下面这张图能帮你快速建立SDK的整体认知:

Tina SDK 核心目录与编译流程 tina-sdk-v2.0/ device/ (板级配置) kernel/ (内核源码) package/ (应用包) board.dts / sys_config.fex drivers/ / arch/ / include/ allwinner/ / utils/ / libs/ make menuconfig make -j$(nproc) out/ → boot.img / rootfs.img

这张图把SDK的三大源码模块和编译流程串起来了。你从 device/ 配硬件,kernel/ 写驱动,package/ 加应用,最后通过 make menuconfig 整合配置,make 编译输出镜像。逻辑很清晰。

我的习惯: 每次拿到新SDK,我会先跑一遍 tree -L 2 看看整体结构,然后重点关注 device/config/chips/ 和 kernel/linux-*/drivers/ 这两个目录。驱动开发90%的工作都在这两个地方。

好了,环境搭建这块就到这。SDK能正常编译,说明你的开发环境已经就绪。后面咱们就可以开始真正的外设驱动配置了。