Buildroot 开发指南

本文档介绍基于 XNIUPI-R 系列产品,如何使用官方Buildroot发行版来构建和适配相关硬件功能的开发文档。

1. buildroot 简介

Buildroot是一个可以使用交叉编译简单且自动化地为嵌入式系统构建完整Linux系统的工具。 整个 Buildroot 是由 Makefile(*.mk) 脚本和 Kconfig(Config.in) 配置文件构成的。你可以和编译 Linux 内核一样,通过 buildroot 配置,menuconfig 修改,编译出一个完整的可以直接烧写到机器上运行的 Linux 系统软件(包含 boot、kernel、rootfs 以及 rootfs 中的各种库和应用程序)。

buildroot项目路径:XXX_SDK/buildroot,其目录结构如下:

buildroot/
├── arch                # CPU 架构的构建、配置文件
├── board               # 具体单板相关的文件
├── boot                # Bootloaders 的构建、配置文件
├── build
├── CHANGES             # Buildroot 修改日志
├── Config.in
├── Config.in.legacy
├── configs             # 具体单板的 Buildroot 配置文件
├── COPYING
├── DEVELOPERS
├── dl                  # 下载的程序、源码压缩包、补丁等
├── docs                # 文档
├── fs                  # 各种文件系统的构建、配置文件
├── linux               # Linux 的构建、配置文件
├── Makefile
├── Makefile.legacy
├── output              # 编译输出目录
├── package             # 所有软件包的构建、配置文件
├── README              # Buildroot 简单说明
├── support             # 为 Bulidroot 提供功能支持的脚本、配置文件
├── system              # 制作根文件系统的构建、配置文件
├── toolchain           # 交叉编译工具链的构建、配置文件
└── utils               # 实用工具

警告

必须使用普通用户权限构建系统,Buildroot中没有任何需要root权限的地方。使用普通用户权限执行所有命令,可以保护你的系统防止软件包配置错误导致的编译和安装问题。

下面以 RK356x 平台的 Buildroot 开发为例进行介绍。

2. 配置

2.1 选择默认配置文件

进入xniupi_linux_SDK/buildroot目录:

source envsetup.sh <config_name>

比如我们以R600所搭载的RK3568平台为例,即执行如下指令:

source envsetup.sh rockchip_rk3568

执行完成后会生成编译输出目录,output/rockchip_rk3568,后续也可以在该目录下执行 make 相关操作。

:::info 说明 其中<config_name> 可以执行source envsetup.sh列出来,选择具体平台编译。例如我们执行source envsetup.sh,列出了所有预置的环境变量,因为我们的R600平台采用的RK3568平台,因此我们选择rockchip_rk3568这个预置的环境变量配置文件:

$ source envsetup.sh

############### Rockchip Buildroot SDK ###############

Pick a board:
...
49. rockchip_rk3528
50. rockchip_rk3528_recovery
51. rockchip_rk3562
52. rockchip_rk3562_32
53. rockchip_rk3562_dictpen
54. rockchip_rk3562_ramboot
55. rockchip_rk3562_recovery
56. rockchip_rk3562_robot
57. rockchip_rk3566
58. rockchip_rk3566_32
59. rockchip_rk3566_recovery
60. rockchip_rk3566_rk3568_base
61. rockchip_rk3566_rk3568_ramboot
62. rockchip_rk3568
63. rockchip_rk3568_32
64. rockchip_rk3568_recovery
65. rockchip_rk3576
66. rockchip_rk3576_ipc
67. rockchip_rk3576_multi_ipc
68. rockchip_rk3576_ramboot
69. rockchip_rk3576_recovery
70. rockchip_rk3588
71. rockchip_rk3588_base
72. rockchip_rk3588_ramboot
73. rockchip_rk3588_recovery
Which would you like? [1]: 

备注:

  1. 无后缀 表示标准版本,一般我们选择该版本即可。

  2. _32 和 _64 _32 一般表示该版本是 32 位系统的配置,_64 则代表 64 位系统的配置。

  3. _ramboot 表示该版本采用的是从 RAM(随机存取存储器)启动的模式。这种启动模式通常速度较快,因为它直接从 RAM 加载系统,无需从存 储设备读取数据,适合快速启动和调试的场景。

  4. _recovery 表示这是一个恢复模式的版本。当系统出现故障无法正常启动时,可以使用这个版本进入恢复模式,对系统进行修复、备份或还原等 操作。

  5. _base 表示基础版本,只包含芯片平台最基本的功能和驱动,没有额外的扩展功能或定制化配置。

  6. _multi-cam 表示支持多摄像头功能。这意味着该版本在硬件驱动和软件配置上进行了优化,能够同时连接和使用多个摄像头,适用于需要多摄 像头协同工作的场景,如监控系统、智能安防等。

  7. _npu 表示该版本集成了神经网络处理单元(NPU)。NPU 专门用于加速人工智能和深度学习任务,带有这个后缀的版本适合运行 AI 相关的应用 程序,如人脸识别、图像识别等。

  8. _ipc 表示该版本适用于网络摄像机(IPC)应用场景。这种版本在视频编码、网络传输等方面进行了优化,以满足 IPC 设备对高清视频采集、 传输和处理的需求。

  9. _robot 表示该版本是为机器人应用场景定制的。它可能在运动控制、传感器驱动、人机交互等方面进行了优化,以适应机器人的各种功能需求。

  10. _tiny 通常表示精简版,这个版本会去除一些不必要的功能和组件,以减小系统体积和资源占用,适合对存储空间和性能要求较低的设备。 :::

2.2 软件包配置

软件包是包含了可执行程序、库文件、配置文件等相关资源的集合,用于为操作系统或其他软件提供特定功能或服务。Buildroot 软件包配置就是利用 Buildroot 工具,针对目标嵌入式系统,在配置界面里选择所需软件包并设置其参数,以构建出满足特定功能和资源要求的定制化系统镜像。

如下为软件配置示例:

进入xniupi_linux_SDK/buildroot目录,执行以下命令打开软件包配置界面:

make menuconfig

我们可以在配置界面添加或者删减一些软件包,也可以根据实际需要修改软件包的一些参数,从而实现系统功能定制。以添加qt53d为例进行简要介绍:

make menuconfig界面,输入/进入搜索模式,输入想要查找的内容qt53d

按回车进行搜索

选择1跳转到对应配置界面,按空格选中配置,然后回车进入下一级配置界

配置完成后,移动到save,按回车保持到.config;移动到exit,按回车退出。

:::tip 保存修改到配置文件 在make menuconfig中完成配置以后,一定要记得执行如下指令,将修改保存到配置文件configs/rockchip_rk3568_defconfig, 否则编译以后配置文件会重新被编译然后覆盖掉.config文件,导致配置不生效!

make savedefconfig

:::

2.3 BusyBox 配置

BusyBox 是一个集成了众多常见 Unix/Linux 命令和工具于单一可执行文件的软件,可高度定制以满足嵌入式系统资源受限情况下的基本操作与管理需求。BusyBox 配置指的就是在构建嵌入式系统时,借助特定工具和界面来定制 BusyBox 所包含的工具、功能及特性,以适配系统资源与实际功能需求。 进入xniupi_linux_SDK/buildroot目录,执行以下命令打开软件包配置界面:

make busybox-menuconfig

空格选中配置,配置完成后,移动到 Exit 按回车退出,在弹窗页面选择 Yes 保存到 .config

:::tip 保存修改到配置文件 在make busybox-menuconfig中完成配置以后,一定要记得执行如下指令,将修改保存到配置文件board/rockchip/common/base/busybox.config, 否则编译以后配置文件会重新被编译然后覆盖掉.config文件,导致配置不生效!

make busybox-update-config

:::

3. 编译

3.1 编译 buildroot

按照2. 配置一节配置好buildroot后,直接运行make指令,即可进行编译。

:::info 编译说明 运行make进行编译时,会执行以下过程:

  1. 下载源码;

  2. 配置、编译、安装交叉编译工具链;

  3. 配置、编译、安装选择的软件包;

  4. 按选择的格式生成根文件系统; :::

想要连接更多make指令的更多用法,可通过make help查看。

3.2 编译输出目录

编译完成后,在编译输出目录 output/rockchip_rk3568 会生成子目录,说明如下:

  • build/ 包含所有的源文件,包括 Buildroot 所需主机工具和选择的软件包,这个目录包含所有软件包源码。

  • host/ 主机端编译需要的工具,包括交叉编译工具。

  • images/ 包含压缩好的根文件系统镜像文件。

  • staging/ 这个目录类似根文件系统的目录结构,包含编译生成的所有头文件和库,以及其他开发文件,不过它们没有裁剪,比较庞大,不适用于目标文件系统。

  • target/ 包含完整的根文件系统,对比 staging/,它没有开发文件,不包含头文件,二进制文件也经过 strip 处理。

3.3 单独编译某一个软件包

我们也可以执行 make <package>单独编译某个软件包。

软件包的编译主要包括:下载,解压,打补丁,配置,编译,安装等过程,具体可以查看 package/pkg-generic.mk。

  • 下载

    Buildroot 会根据配置 package/<package>/<package>.mk,自动从网络获取对应的软件包,包括一些第三方库,插件,实用工具等,放在 dl/ 目录。

  • 解压

    软件包会解压在 output/rockchip_rk3568/build/<package>-<version> 目录下。

  • 打补丁

    补丁集中放在 package/<packgae>/ 目录,Buildroot 会在解压软件包后为其打上相应的补丁。如果要修改源码,可以通过打补丁的方式进行修改。

  • 配置

  • 编译

  • 安装

编译完成后,会将需要的编译生成文件拷贝到 output/rockchip_rk3568/target/ 目录。

对于某个软件包,我们可以通过 make <package>-<target> 调用软件包构建中的某一步骤,如下:

Package-specific:
  <pkg>                  - Build and install <pkg> and all its dependencies
  <pkg>-source           - Only download the source files for <pkg>
  <pkg>-extract          - Extract <pkg> sources
  <pkg>-patch            - Apply patches to <pkg>
  <pkg>-depends          - Build <pkg>'s dependencies
  <pkg>-configure        - Build <pkg> up to the configure step
  <pkg>-build            - Build <pkg> up to the build step
  <pkg>-graph-depends    - Generate a graph of <pkg>'s dependencies
  <pkg>-dirclean         - Remove <pkg> build directory
  <pkg>-reconfigure      - Restart the build from the configure step
  <pkg>-rebuild          - Restart the build from the build step

3.4 使用交叉编译工具编译程序

buildroot 编译完成后,会在 output/rockchip_rk3568/host/ 目录下,生成交叉编译工具,我们可以用来编译目标程序。

交叉编译工具路径output/rockchip_rk3568/host/bin/

:::info 举个例子 我们使用该交叉编译工具,编译一个会打印hello World!的C语言程序hello.c

程序源码:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
        printf("Hello World!\n");
        return 0;
}

编译:

.../host/bin/arm-buildroot-linux-gnueabihf-gcc hello.c -o hello

运行:

将可执行程序hello拷贝到设备,运行./hello,就可以看到打印信息hello worls!,这证明我们的程序已正常运行起来。

:::

4. 交叉编译工具链

Buildroot是一个用于生成嵌入式Linux系统根文件系统的工具,在Buildroot中,工具链是构建整个系统的关键部分,可分为内部工具链和外部工具链。通过make menuconfig配置界面可以选择内部或者外部工具链。

  • 内部工具链后端,在配置界面中称为Buildroot工具链

  • 外部工具链后端,在配置界面中称为外部工具链

:::info 举个例子

$ make menuconfig
 -> Toolchain
 │ -> Toolchain type ( [=y])

SDK默认使用内部工具链 :::

以下是关于它们的介绍:

4.1 内部工具链

  • 特点

    • Buildroot可以自行构建内部工具链,这是其默认的行为。内部工具链的构建过程完全由Buildroot控制,它会根据配置选项下载、编译和安装工具链的各个组件,包括编译器、链接器、调试器等。

    • 内部工具链与Buildroot的集成度高,能够很好地适应Buildroot构建系统的整体流程和需求。

    • 可以方便地进行定制,用户可以通过修改Buildroot的配置选项来调整工具链的特性,如目标架构、编译器优化选项、支持的库等。

  • 使用场景

    • 当需要一个高度定制化的工具链,并且希望Buildroot完全控制工具链的构建过程时,内部工具链是一个很好的选择。例如,针对特定的嵌入式硬件平台,需要构建一个具有特定指令集优化或支持特定外设驱动的工具链。

:::info 优缺点分析

优点:

  • 与Buildroot有良好的兼容性

  • 快速,只构建必要的东西

缺点:

  • 在进行清洁工作时,需要重建工具链,这需要耗费一些时间。如果你想减少你的构建时间,考虑使用外部工具链后端。

  • 仅限于uClibc C库

:::

4.2 外部工具链

  • 特点

    • 外部工具链是指使用已经预先构建好的、独立于Buildroot的工具链。这些工具链可以是由芯片厂商提供的,也可以是从其他开源项目或商业渠道获取的(Buildroot能识别几种常见的交叉编译工具链:从ARM的Linaro,ARM的Sourcery CodeBench,x86,x86-64,PowerPC,MIPS和SuperH,来自ADI的Blackfin工具链, Xilinx用于Microblaze的工具链,等等。)。

    • 使用外部工具链可以节省Buildroot构建工具链的时间和资源,特别是对于一些复杂的、需要大量编译时间的工具链,直接使用预构建的外部工具链可以显著提高构建效率。

    • 外部工具链的稳定性可能更高,因为它们通常经过了一定的测试和验证。

  • 使用场景

    • 如果已经有一个成熟的、经过测试的外部工具链,并且不希望在Buildroot中重新构建工具链,那么可以选择使用外部工具链。例如,某些商业芯片厂商会提供专门针对其芯片的高性能工具链,开发者可以直接将其集成到Buildroot项目中。

    • 当需要与现有的开发环境或工作流程进行集成时,外部工具链也很有用。例如,团队中已经在使用特定的工具链进行其他项目的开发,为了保持一致性,在Buildroot项目中也可以使用相同的外部工具链。

:::info 优缺点分析

优点:

  • 避免交叉编译工具链的构建时间,这在嵌入式Linux系统的总体构建时间中通常非常重要。

  • 不局限于uClibc:glibc和eglibc工具链得到了支持。

缺点:

  • 如果你的预构建的外部工具链有缺陷,可能很难从工具链供应商那里得到解决方案,除非你构建外部工具使用交叉的工具链。

:::

SDK 目录内设置交叉编译,当 Buildroot 外部工具链使用 SDK prebuilt 目录预置交叉编译时,如下:

目录 说明
prebuilt/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu gcc arm 10.3.1 64位工具链
prebuilt/gcc/linux-x86/arm/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf gcc arm 10.3.1 32位工具链

:::info ⼯具链下载 点击下载⼯具链 :::

SDK若需要编译单个模块或者第三⽅应⽤,需交叉编译环境进⾏配置。⽐如RK3562其交叉编译⼯具位于:

buildroot/output/rockchip\_rk3562/host/usr

需要将⼯具的bin/⽬录和aarch64-buildroot-linux-gnu/bin/⽬录设为环境变量,在顶层⽬录执⾏⾃动配置环境变量的脚本:

source buildroot/envsetup.sh rockchip_rk3562

输⼊命令查看:

cd buildroot/output/rockchip_rk3562/host/usr/bin
./aarch64-linux-gcc --version

此时会打印如下信息:

aarch64-linux-gcc.br_real (Buildroot) 12.3.0

外部⼯具链如果需要SDK⾃带的⼯具链,可集成 configs/rockchip/toolchain/\* 相关配置。

5. 重建

对于重建的具体说明,可以查看文档 buildroot/docs/manual/rebuilding-packages.txt

5.1 重建软件包

在开发过程中,若修改了某个软件包的源码,Buildroot 是不会重新编译该软件包的。可以按如下方式操作重建:

  • 方式一

make <package>-rebuild
  • 方式二

# 删除软件包的编译输出目录
rm -rf output/rockchip_rk3568/build/<package>-<version>
# 编译
make <package>

5.2 完全重建

当通过 make menuconfigmake xconfig其他配置工具更改系统配置时,Buildroot 不会尝试检测应重建系统的哪些部分。在某些情况下,Buildroot 应该重建整个系统,在某些情况下,仅应重建软件包的特定子集。但是以完全可靠的方式检测到这一点非常困难,因此一般情况下我们都是完全重建。

5.2.1 何时需要完全重建

  • 更改目标体系结构配置时,需要完全重建;

  • 更改工具链配置时,需要完全重建;

  • 将其他软件包添加到配置中时,不一定需要完全重建;

  • 从配置中删除软件包时,Buildroot 不会执行任何特殊操作。它不会从目标根文件系统或工具链中删除此软件包安装的文件。需要完全重建才能删除这些文件;

  • 更改软件包的子选项时,不会自动重建软件包;

  • 对根文件系统框架进行更改时,需要完全重建;

一般而言,当你遇到构建错误并且不确定所做的配置更改可能带来的后果时,请进行完全重建。具体说明可以查看文档 rebuilding-packages.txt

5.2.2 如何完全重建

  • 方式一

直接删除编译输出目录,之后重新进行配置、编译。

rm -rf output/
  • 方式二

执行如下命令,会删除编译输出并重新编译。

make clean all

6. 新增本地源码包

开发过程中,Buildroot 自带的软件包有时可能无法满足我们的需求,为此我们需要添加自定义的软件包。Buildroot 支持多种格式的软件包,包括 generic-package、cmake-package、autotools-package 等。

这里我们以新增一个 xniupi_demo 的 generic-package 举例说明,用户也可参考builroot/package/rockchip/* 相关包添加

6.1 创建工程目录

进入XXX_SDK/buildroot目录,然后创建工程目录:

mkdir package/rockchip/xniupi_demo/

6.2 新建 Config.in ⽂件

xniupi_demo/创建⼀个Config.in⽂件。这个⽂件将包含与我们的新增加的软件包相关的选项描述,这些配置选项描述会在配置⼯具中被调用并显⽰。

一般包含以下内容:

menuconfig BR2_PACKAGE_XNIUPI
   bool "XNIUPI Platform"

if BR2_PACKAGE_XNIUPI

config BR2_PACKAGE_XNIUPI_DEMO
    bool "Simple XNIUPI Demo"

6.3 新建xniupi_demo.mk⽂件

xniupi_demo/创建⼀个xniupi_demo.mk⽂件,并添加如下内容:

##################################################
###########
#
### xniupi_demo
#
##################################################
###########
ifeq ($(BR2_PACKAGE_XNIUPI_DEMO), y)

        XNIUPI_DEMO_VERSION:=1.0.0
        XNIUPI_DEMO_SITE=$(TOPDIR)/../external/xniupi_demo/src
        XNIUPI_DEMO_SITE_METHOD=local

define XNIUPI_DEMO_BUILD_CMDS
        $(TARGET_MAKE_ENV) $(MAKE) CC=$(TARGET_CC) CXX=$(TARGET_CXX) -C $(@D)
endef

define XNIUPI_DEMO_CLEAN_CMDS
        $(TARGET_MAKE_ENV) $(MAKE) -C $(@D) clean
endef

define XNIUPI_DEMO_INSTALL_TARGET_CMDS
        $(TARGET_MAKE_ENV) $(MAKE) -C $(@D) install
endef

define XNIUPI_DEMO_UNINSTALL_TARGET_CMDS
        $(TARGET_MAKE_ENV) $(MAKE) -C $(@D) uninstall
endef

$(eval $(generic-package))
endif

6.4 创建源码目录

上文的 Makefile 文件里已经指定了源码目录 external/xniupi_demo/src

进入XXX_SDK目录,创建源码目录:

mkdir external/xniupi_demo/src

6.5 编写源码 xniupi_demo.c

XXX_SDK/external/xniupi_demo/src/目录下添加xniupi_demo.c。 :::info 举个例子

xniupi_demo.c

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
        printf("Hello World!\n");
        return 0;
}

:::

6.6 编写 Makefile

XXX_SDK/external/xniupi_demo/src/目录下添加Makefile

DEPS =
OBJ = xniupi_demo.o
CFLAGS =
%.o: %.c $(DEPS)
        $(CC) -c -o $@ $< $(CFLAGS)

xniupi_demo: $(OBJ)
        $(CXX) -o $@ $^ $(CFLAGS)

.PHONY: clean
clean:
        rm -f *.o *~ xniupi_demo

.PHONY: install
install:
        cp -f xniupi_demo $(TARGET_DIR)/usr/bin/

.PHONY: uninstall
uninstall:
        rm -f $(TARGET_DIR)/usr/bin/xniupi_demo

6.7 修改上一级 Config.in 文件

在 buildroot/package/rockchip/Config.in 末尾添加一行:

source "package/rockchip/xniupi_demo/Config.in"

:::info 备注

buildroot/package/rockchip/Config.in 末尾添加 source "package/rockchip/xniupi_demo/Config.in" 这一行代码,主要目的是将 package/rockchip/xniupi_demo/Config.in 这个配置文件引入到 Buildroot 的配置系统中。下面为你详细解释其背后的原理和作用:

Buildroot配置系统概述

Buildroot 是一个用于生成嵌入式 Linux 系统根文件系统的工具,它使用 Kconfig 语言来管理配置选项。Kconfig 文件定义了一系列的配置菜单、选项和依赖关系,用户可以通过 make menuconfig 命令来可视化地选择和配置这些选项。

引入子配置文件的作用

模块化管理

Buildroot 项目通常会包含大量的软件包和配置选项,如果将所有的配置信息都集中在一个文件中,会导致文件变得非常庞大和复杂,难以维护。通过将不同软件包或功能模块的配置信息放在独立的 Config.in 文件中,可以实现模块化管理。在这个例子中,package/rockchip/xniupi_demo/Config.in 可能包含了与 xniupi_demo 这个软件包或功能模块相关的所有配置选项,将其引入到 buildroot/package/rockchip/Config.in 中,使得 rockchip 相关的配置信息更加清晰和有条理。

扩展功能

当你开发了一个新的软件包或功能模块(如 xniupi_demo),并为其编写了相应的配置文件 Config.in 后,需要将这个配置文件集成到 Buildroot 的整体配置系统中,以便用户可以通过 make menuconfig 来选择是否启用这个新的软件包或功能模块。通过在 buildroot/package/rockchip/Config.in 中添加 source 语句,可以将新的配置文件引入到 Buildroot 的配置菜单中,从而实现功能的扩展。

保持独立性

每个 Config.in 文件可以独立开发和维护,不会影响到其他模块的配置。当需要对 xniupi_demo 进行修改或更新时,只需要修改 package/rockchip/xniupi_demo/Config.in 文件,而不会对其他模块的配置产生影响。

示例说明

假设 package/rockchip/xniupi_demo/Config.in 文件内容如下:

config BR2_PACKAGE_XNIUPI_DEMO
    bool "xniupi_demo"
    help
      This is a demo package for rockchip platform.

buildroot/package/rockchip/Config.in 中添加 source "package/rockchip/xniupi_demo/Config.in" 后,当你运行 make menuconfig 时,在 rockchip 相关的配置菜单中会出现一个名为 xniupi_demo 的选项,你可以选择是否启用这个软件包。

综上所述,添加 source "package/rockchip/xniupi_demo/Config.in" 这一行代码的目的是将 xniupi_demo 相关的配置选项集成到 Buildroot 的配置系统中,实现模块化管理和功能扩展。 :::

6.8 配置软件包

打开配置菜单 make menuconfig,找到 xniupi_demo 并选中配置。

6.9 编译

进入XXX_SDK/buildroot目录

# 编译 xniupi_demo
make xniupi_demo
# 打包进根文件系统
make
# 若修改源码,重新编译软件包
make xniupi_demo-rebuild

6.10 软件包名、配置条⽬名称和 makefile 变量关系

:::info Buildroot中,有⼀些关联:

  • the package name,它是包⽬录名(以及*.mk⽂件的名称);

  • 配置条⽬名称在 Config.in ⽂件中声明;

  • makefile变量前缀

必须使⽤以下规则来保持这些要素之间的⼀致性:

  • 包⽬录和*mk名字是包名本⾝(例如:package/foo-bar_boo/foo-bar_boo.mk);

  • ⽬标名称是包名本⾝(如:foo-barboo);

  • 配置条⽬是⼤写的包名。 - 字符替换为 _,前缀为BR2_PACKAGE_。(例如:BR2_PACKAGE_FOO_BAR_BOO);

  • 后缀.mk变量的以⼤写的包名为前缀,字符替换为_(例如:FOO_BAR_BOO_VERSION); :::

7. 如何从 github 中添加⼀个软件包

在使用 Buildroot 构建嵌入式系统时,需要将各种软件包集成到构建系统中。有些软件包可能是在 GitHub 上进行管理的,并且这些软件包可能没有发布包的明确下载地址。这时就需要直接从 GitHub 仓库下载软件包,可以参考以下步骤配置。

通过设置 FOO_VERSION 和 FOO_SITE 这两个变量,就可以在 Buildroot 的 .mk 文件中配置从 GitHub 上下载指定版本的软件包。

FOO_VERSION = v1.0 # tag or (abbreviated) commit ID
FOO_SITE = http://github.com/<user>/<package>/tarball/$(FOO_VERSION)

:::info 注意

  • FOO_VERSION可以是标签也可以是提交ID

  • github⽣成的tarball名称与Buildroot的默认值匹配(例如:foo-1234567.tar.gz),所以它不需要在.mk⽂件中指定。

  • 当使⽤提交ID作为版本时,通常情况下,SHA1的前7个字符就⾜够了。 :::

8. rootfs-overlay

8.1 rootfs-overlay 简介

rootfs-overlay 是指在已有的根文件系统(rootfs)基础上,通过一种叠加的方式来添加、修改或替换文件和目录,而不直接修改原始的根文件系统。它利用了文件系统的挂载机制,将一个或多个目录作为 overlay 层挂载到根文件系统之上,使得在 overlay 层中对文件的修改能够覆盖原始根文件系统中的同名文件,同时保留原始根文件系统的完整性。

8.1.1 作用

  • 定制文件系统

    在嵌入式设备开发中,通常会有一个基础的根文件系统镜像,但不同的应用场景可能需要对其进行个性化定制,如添加特定的配置文件、应用程序、脚本等。rootfs - overlay 提供了一种方便的方式来实现这种定制,而无需重新构建整个根文件系统。

  • 系统升级与更新

    可以将更新的文件放置在 overlay 层中,当系统启动时,这些更新的文件会覆盖旧版本的文件,从而实现系统的部分升级。这样可以避免在每次更新时都重新烧录整个根文件系统,提高了更新的效率和灵活性。

  • 实验与调试

    开发人员可以在 overlay 层中进行各种实验性的修改和调试,而不会影响到原始的根文件系统。如果实验失败或需要恢复到原始状态,只需移除 overlay 层即可,不会对系统造成永久性的破坏。

8.1.2 实现原理

一般是基于联合文件系统(Union File System)的原理来实现的。联合文件系统允许将多个不同的文件系统层次结构联合挂载到一个统一的挂载点下,使得它们看起来就像一个单一的文件系统。在 rootfs - overlay 中,通常会有一个只读的底层根文件系统和一个可写的 overlay 层,当对文件进行访问时,联合文件系统会首先在 overlay 层中查找文件,如果找到则使用 overlay 层中的文件;如果未找到,则会在底层的根文件系统中查找。

8.2 如何使用rootfs-overlay

假设我们要在根文件系统的/etc/目录下添加文件overlay-test,可以按照以下步骤操作:

8.2.1 设置rootfs-overlay根目录

打开配置菜单 make menuconfig,通过设置 BR2_ROOTFS_OVERLAY 选项,添加用于覆盖的根目录。对于 RK3568,默认已添加了目录 board/rockchip/rk356x/fs-overlay/

8.2.2 添加文件到覆盖目录

cd buildroot/board/rockchip/rk356x/fs-overlay/
mkdir etc/
touch etc/overlay-test

8.2.3 编译

make

8.2.4 下载根文件系统

将编译好的根文件系统 output/rockchip_rk3568/images/rootfs.ext2 下载到设备。启动设备,可以看到已添加文件 /etc/overlay-test。

也可以通过查看 target/ 目录,验证是否添加成功:

ls buildroot/output/rockchip_rk3568/target/etc/overlay-test

9. Qt交叉编译环境支持

Firefly 提取了 Buildroot 的交叉编译工具链,支持 EGLFS、LinuxFB、Wayland 等插件,您可以直接使用该工具链开发 Buildroot 上的 Qt 应用程序,而无需下载编译 SDK 代码。

版本:Qt-5.15.2
主机:x86-64 / Ubuntu 18.04
设备:Firefly RK3568 RK3566  / Buildroot

下载地址:Buildroot Qt

环境部署:详见 Qt5.1x.x_Release.md 文件。

10. 定制模块开发

配置文件路径:/buildroot/configs/rockchip\*

该路径下存放了Rockchip平台各芯片的预置配置文件,开发者可根据实际需求:

  1. 直接使用现有配置(如base.config包含基础功能)

  2. 基于现有配置进行修改(如添加多媒体/npu等特性)

  3. 创建新的配置文件(针对特殊硬件定制)

buildroot$ tree -L 2 configs/rockchip/
configs/rockchip/
├── base # 通⽤基础包 ├── base.config
│ ├── common.config
│ ├── kernel.config
│ ├── recovery.config
│ └── tiny.config
├── benchmark.config # benchmark跑分测试⼯具
├── chips # 相关芯⽚配置 ├── rk3036_arm.config
│ ├── rk3036.config
│ ├── rk312x_arm.config
│ ├── rk312x.config
│ ├── rk3288_arm.config
│ ├── rk3288.config
│ ├── rk3308_aarch64.config
│ ├── rk3308_arm.config
│ ├── rk3308.config
│ ├── rk3326_aarch64.config
│ ├── rk3326_arm.config
│ ├── rk3326.config
│ ├── rk3399_aarch64.config
│ ├── rk3399_arm.config
│ ├── rk3399.config
│ ├── rk3399pro_aarch64.config
│ ├── rk3399pro_arm.config
│ ├── rk3399pro.config
│ ├── rk3399pro_npu_aarch64.config
│ ├── rk3399pro_npu_arm.config
│ ├── rk3399pro_npu.config
│ ├── rk3528_aarch64.config
│ ├── rk3528.config
│ ├── rk3562_aarch64.config
│ ├── rk3562_arm.config
│ ├── rk3562.config
│ ├── rk3566_rk3568_aarch64.config
│ ├── rk3566_rk3568_arm.config
│ ├── rk3566_rk3568.config
│ ├── rk3588_aarch64.config
│ ├── rk3588_arm.config
│ └── rk3588.config
├── chromium.config # chromium浏览器
├── debug.config # 调试⼯具配置
├── electric.config # 电⼒配置
├── font # 字体配置 ├── chinese.config
│ └── font.config
├── fs # ⽂件系统格式配置 ├── e2fs.config
│ ├── exfat.config
│ ├── ntfs.config
│ ├── ubifs.config
│ └── vfat.config
├── gdb.config # gdb调试
├── gpu # GPU配置 └── gpu.config
├── libcamera.config # libcamera配置
├── locale
│ ├── chinese.config
│ └── locale.config
├── multimedia # 多媒体配置 ├── audio.config
│ ├── camera.config
│ ├── gst
│ ├── mpp.config
│ └── rockit.config
├── npu2.config # npu配置
├── powermanager.config #电源管理配置
├── rknn_demo.conf
├── tee_aarch64_v2.config
├── test.config
├── toolchain # ⼯具链配置 ├── arm_10_aarch64.config
│ ├── arm_10_armhf.config
│ └── arm_8_armhf.config
├── weston.config # Weston配置
├── wifibt # RKWIFIBT⽹络配置 ├── bt.config
│ ├── network.config
│ └── wireless.config
└── x11.config # X
...

11. 桌⾯应⽤

Buildroot默认使⽤基于 wayland 协议的 weston drm 来作为显⽰后端。如下图:

这些 Weston 应⽤提供了⼀些状态栏和背景等基础功能配置,如Chromium浏览器、Terminal终端、Launchers配置,摄像头预览,多路视频,GPU,⿏标等demo。

如需更多 Demo 可以通过 /etc/xdg/weston/weston.ini.d/* 配置添加即可。

:::warning 注意 第三⽅UI框架在未经商业授权的情况下可能涉及侵权⻛险。

如果在Rockchip平台上使⽤ Buildroot QT / Enlightenment / Minigui / LVGL 等UI框架,用户需要自行获得第三⽅授权和技术⽀持,因为版权原因,Rockchip官⽅不提供相关技术⽀持和维护。 :::

11.1 Weston 应用

基于Wayland上使⽤的weston客⼾端相关应⽤:

/usr/bin/#
├── weston-calibrator       # 触屏校准工具
├── weston-clickdot         # 点击测试工具(显示点击位置)
├── weston-cliptest        # 剪贴板测试工具  
├── weston-confine         # 窗口限制测试工具
├── weston-content_protection # 内容保护演示工具
├── weston-debug           # Weston调试工具
├── weston-dnd             # 拖放操作测试工具
├── weston-editor          # 简易文本编辑器
├── weston-eventdemo       # 输入事件测试工具
├── weston-flower          # 动态花朵演示程序
├── weston-fullscreen      # 全屏模式测试工具
├── weston-image           # 图片查看器
├── weston-multi-resource  # 多资源管理测试工具
├── weston-presentation-shm # 共享内存演示工具
├── weston-resizor         # 窗口缩放测试工具
├── weston-scaler          # 图像缩放测试工具
├── weston-screenshooter   # 屏幕截图工具
├── weston-simple-damage   # 窗口损坏区域测试工具
├── weston-simple-dmabuf-egl # DMA-BUF EGL测试工具
├── weston-simple-dmabuf-v4l # DMA-BUF V4L2测试工具
├── weston-simple-egl      # EGL接口测试工具
├── weston-simple-shm      # 共享内存接口测试工具
├── weston-simple-touch    # 触摸事件测试工具
├── weston-smoke           # 3D烟雾效果演示
├── weston-stacking        # 窗口堆叠测试工具
├── weston-subsurfaces     # 子表面测试工具
├── weston-tablet          # 数位板输入测试工具
├── weston-terminal        # Weston终端模拟器
├── weston-touch-calibrator # 触摸屏校准工具
├── weston-transformed     # 图形变换测试工具

11.2 Enlightenment 桌⾯应⽤

make menuconfigvim .config配置相关选项即可:

BR2_PACKAGE_EFL=y
BR2_PACKAGE_LUAJIT=y
BR2_PACKAGE_EFL_GSTREAMER1=y
BR2_PACKAGE_ENLIGHTENMENT=y
BR2_PACKAGE_EFL_WAYLAND=y

:::info 开启配置的方法

方法一:使用make menuconfig打开图形化界面配置

方法二:直接修改 XXX_SDK/buildroot/ 目录下的 .config 文件

修改完成后,均需要执行save make savedefconfig,以保存修改到configs/rockchip_rk35XX_defconfig :::

11.3 LVGL 桌⾯应⽤

make menuconfigvim .config配置相关选项即可:

BR2_PACKAGE_LVGL=y
BR2_PACKAGE_LVGL_COLOR_DEPTH=32
BR2_PACKAGE_LV_DRIVERS=y
BR2_PACKAGE_LV_DRIVERS_USE_DRM=y
BR2_PACKAGE_LVGL_DEMO=y
BR2_PACKAGE_RK_DEMO=y
BR2_PACKAGE_LVGL_DEMO_USE_DRM=y
BR2_PACKAGE_FREETYPE=y

11.4 multivideoplayer

make menuconfigvim .config配置相关选项即可:

BR2_PACKAGE_MULTIVIDEOPLAYER=y

多路视频播放器用于测试设备的多路视频播放能力、显示能力以及硬件解码能力。

11.5 qfm

make menuconfigvim .config配置相关选项即可:

BR2_PACKAGE_QFM=y

qfm (QFileManager),一个基于 Qt 的文件管理器。

11.6 qplayer

make menuconfigvim .config配置相关选项即可:

BR2_PACKAGE_QPLAYER=y

qplayer 是一个多功能播放器,可以播放视频、音频和浏览图片。

11.7 qcamera

make menuconfigvim .config配置相关选项即可:

BR2_PACKAGE_QCAMERA=y

qcamera 是一款相机应用,可以进行拍摄和录像。

:::info 备注 设备连接摄像头的情况下启动 qcamera 将自动显示摄像头画面,右侧按钮:

Image Mode: 照相模式,点击可切换为 Video Mode 视频录制模式。

Capture: 捕捉图像,在 Video Mode 下会变为 Record 录制按钮。

Exit: 退出。 :::

11.8 qsetting

make menuconfigvim .config配置相关选项即可:

BR2_PACKAGE_QSETTING=y

qsetting 是系统设置工具,可以设置 WiFi ,蓝牙,恢复出厂以及固件升级。

12. 用户和密码

⽤⼾和密码

⽤⼾:root

密码:xniupi

:::tip 备注 不同产品线的密码可能不一致,一般情况下:

XNIUPI产品线默认密码为:xniupi

XNIUAI产品线默认密码为:xniuai

如果这两个密码都不对,请尝试rockchip,linaro,nnewn,如果还是不对请联系我司技术人员获取! :::

13. 网络配置

13.1 以太网配置

配置文件路径:/etc/network/interfaces

Buildroot 的网络配置需要使用到 /etc/network/interfaces 配置文件,配置完成之后,运行/etc/init.d/S40network restart即可重启网络。手动调试可以直接使用 ifdown -aifup -a 来重启网络。

13.1.1 常用配置

:::tip 举个例子 现在我们需要将eth0网卡设置为动态IP地址,将eth1设置为静态IP地址,那么可以参考以下内容配置:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto eth1
iface eth1 inet static
address 168.168.110.137
netmask 255.255.0.0
broadcast 168.168.1.255
gateway  168.168.0.1

如果遇到 Error: either "local" is duplicate, or "/24" is a garbage 这样子报错,请检查配置文件语法,因为 /etc/network/interfaces 对语法要求很严格,很有可能是配置文件中多了一个空格。 :::

:::info 说明

  1. inet static:定义静态IP地址。支持的选项有:

address address
        Address (dotted quad/netmask) required

netmask mask
        Netmask (dotted quad or number of bits) deprecated

broadcast broadcast_address
        Broadcast address (dotted quad, + or -) deprecated. Default value: "+"

metric metric
        Routing metric for default gateway (integer)

gateway address
        Default gateway (dotted quad)

pointopoint address
        Address of other end point (dotted quad). Note the spelling of "point-to".

hwaddress address
        Link local address or "random".

mtu size
        MTU size

scope  Address validity scope. Possible values: global, link, host
  1. inet dhcp:通过DHCP协议获取IP地址。支持的选项有:

hostname hostname
        Hostname to be requested (pump, dhcpcd, udhcpc)

metric metric
        Metric for added routes (dhclient)

leasehours leasehours
        Preferred lease time in hours (pump)

leasetime leasetime
        Preferred lease time in seconds (dhcpcd)

vendor vendor
        Vendor class identifier (dhcpcd)

client client
        Client identifier (dhcpcd)

hwaddress address
        Hardware address.
  1. inet manual:没有为接口定义IP地址。通常由作为桥接或聚合成员的接口,需要以混杂模式运行的接口( 例如,端口镜像或网络TAP )或在其上配置了VLAN设备的接口使用。这是保持接口不带IP地址的一种方法。支持的选项有:

hwaddress address
        Link local address or "random".

mtu size
        MTU size

:::

13.1.2 高级配置

/etc/network/interfaces 支持设置在网卡关闭/启动时,运行Linux命令行指令。由于 /etc/network/interfaces 支持的功能相对有限,这在配置静态路由、默认路由等网络配置时将会非常有帮助。

支持的可选选项有:pre-upuppost-uppre-downdownpost-down,在这些选项之后,加上命令行即可。

pre-up	  网卡启用前的动作
up	        启用时候的动作
post-up	  启用后的动作
pre-down	  关闭前的动作
down	     关闭时动作
post-down  关闭后动作

说明:$IFACE自适应对于相应的网卡节点

:::tip 举个例子

给eth1网卡配置一条静态路由

auto eth1
iface eth1 inet static
address 192.168.3.1
netmask 255.255.255.0
broadcast 192.168.3.255
post-up ip route add 192.168.4.0/24 via 192.168.3.2 dev $IFACE

:::

:::tip 再举个例子

创建一个网桥,将eth0,eth1绑定到网桥,将其作为LAN口

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual
pre-up ifconfig $IFACE up
post-down ifconfig $IFACE down

auto eth1
iface eth1 inet manual
pre-up ifconfig $IFACE up
post-down ifconfig $IFACE down

auto br0
iface br0 inet static
address 192.168.2.1
netmask 255.255.255.0
broadcast 192.168.2.255
pre-up brctl addbr $IFACE
pre-up brctl addif $IFACE eth0
pre-up brctl addif $IFACE eth1
bridge_ports eth0 eth1
post-down brctl delif $IFACE eth0
post-down brctl delif $IFACE eth1
post-down ifconfig $IFACE down
post-down brctl delbr $IFACE

:::

13.2 WiFi配置

13.2.1 修改配置文件

方式一:通过 qsetting QT应用进行配置

方式二:通过修改配置文件进行配置

  1. 修改如下文件:

vi /data/cfg/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
  1. 添加如下配置项:

network={
ssid="WiFi-AP"		// WiFi 名字
psk="12345678"		// WiFi 密码
key_mgmt=WPA-PSK	// 加密方式
# key_mgmt=NONE		// 不加密
}
  1. 启动wpa_supplicant进程

wpa_supplicant -B -i wlan0 -c /data/cfg/wpa_supplicant.conf

13.2.2 临时修改

修改如下文件:

vi /data/cfg/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1

启动wpa_supplicant进程:

wpa_supplicant -B -i wlan0 -c /data/cfg/wpa_supplicant.conf

13.2.3 通过wpa_cli配置WiFi

常用命令:

wpa_cli -i wlan0 scan             // 搜索附近wifi网络
wpa_cli -i wlan0 scan_result      // 打印搜索wifi网络
wpa_cli -i wlan0 add_network      // 添加一个网络连接

如果要连接加密方式是[WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][ESS] (wpa加密),wifi名称是name,wifi密码是:psk。操作如下:

wpa_cli -i wlan0 set_network 0 ssid '"name"'
wpa_cli -i wlan0 set_network 0 psk '"psk"'
wpa_cli -i wlan0 set_network 0 key_mgmt WPA-PSK
wpa_cli -i wlan0 enable_network 0    //使能WiFi

如果要连接加密方式是[WEP][ESS] (wep加密),wifi名称是name,wifi密码是psk。操作如下:

wpa_cli -i wlan0 set_network 0 ssid '"name"'
wpa_cli -i wlan0 set_network 0 key_mgmt NONE
wpa_cli -i wlan0 set_network 0 wep_key0 '"psk"'
wpa_cli -i wlan0 enable_network 0

如果要连接加密方式是[ESS] (无加密),wifi名称是name。操作如下:

wpa_cli -i wlan0 set_network 0 ssid '"name"'
wpa_cli -i wlan0 set_network 0 key_mgmt NONE
wpa_cli -i wlan0 enable_network 0

使能保存WIFI连接信息

wpa_cli -i wlan0 set update_config 1

保存WIFI连接信息

wpa_cli -i wlan0 save_config

连接已有的连接

wpa_cli -i wlan0 list_network        // 列举所有保存的连接
wpa_cli -i wlan0 select_network 0     // 连接第1个保存的连接
wpa_cli -i wlan0 enable_network 0      // 使能第1个保存的连接

关闭WiFi

ifconfig wlan0 down

14. 音/视频播放

# 播放 wav
aplay test.wav
gstwavplay.sh test.wav

# 播放 mp3
mp3play.sh test.mp3
gstmp3play.sh test.mp3

# 播放 mp4
gstmp4play.sh test.mp4
gstvideoplay.sh test.mp4

15. SSH

官方发布的 SDK 默认已开启 ssh,用户为”root”,密码为”xniupi”。

以下介绍修改了用户登录密码以后,如何操作;

  • 使能SSH相关选项

    BR2_PACKAGE_OPENSSH=y
    
  • 配置登录的账户root和密码

    BR2_TARGET_ENABLE_ROOT_LOGIN=y
    BR2_TARGET_GENERIC_ROOT_PASSWD="xniupi"
    
  • 修改配置文件 修改板卡里``/etc/ssh/sshd_config` 文件

    PermitRootLogin yes
    

16. 外部存储设备

Buildroot 支持自动挂载外部存储设备:

U 盘挂载路径:/udisk

TF 卡挂载路径:/sdcard

17. 恢复出厂设置

注意:此出厂设置表示恢复为设备最后一次升级固件之后的初始状态。

17.1 通过 qsetting 配置

通过 qsetting QT 应用进行配置,点击 “Factory Reset” 功能选项进行操作。

17.2 通过 update 命令

update
# 或者
update factory / update reset

18. 固件本地升级

Buildroot 支持从外部存储设备升级固件,以下是升级流程说明。

18.1 制作升级固件

按照正常的固件编译流程,制作用于升级的固件。

:::info 升级固件不一定要全分区升级,可修改 package-file 文件,将不要升级的分区注释掉,或者改为RESERVED

  1. 修改文件 tools/linux/Linux_Pack_Firmware/rockdev/package-file

例如,将 rootfs 的相对路径改为 RESERVED,这样就不会打包根文件系统,即不升级根文件系统分区。

# name          relative path
#
#hwdef          hwdef
package-file    package-file
bootloader      image/miniloaderall.bin
parameter       image/parameter.txt
trust           image/trust.img
uboot           image/uboot.img
misc            image/misc.img
boot            image/boot.img
recovery        image/recovery.img
rootfs          RESERVED
oem             image/oem.img
userdata:grow   image/userdata.img
backup          RESERVED
  1. 编译固件

./build.sh updateimg

:::

将制作好的升级固件拷贝到 U 盘、TF 卡或者设备的 /userdata/ 目录下,重命名为 update.img。

:::warning 注意 若将升级固件放至设备的 /userdata/ 目录,则不要打包 userdata.img,将 image/userdata.img 改为 RESERVED。 :::

18.2 升级过程

18.2.1 通过 qsetting

通过 qsetting QT应用进行配置。点击 “Update” 功能选项进行操作。

18.2.2 通过 update 指令

通过 update 指令,updata.img 放在不同的存储中,要使用不同的升级指令。

# U 盘
update ota /udisk/update.img
# TF 卡
update ota /sdcard/update.img
# /userdata/
update ota /userdata/update.img

等待升级完成,升级成功后,设备会重新启动进入系统。

19. Weston 开发

Weston 是 Wayland 开源显⽰协议的官⽅参考实现,我司提供的 Buildroot 的显⽰服务默认使⽤ Weston drm 后端。我们可以通过配置 Weston 对显示进行一些自定义设置,Buildroot 中 Weston 的配置方式有以下几种:

  1. 启动参数

    即启动 Weston 时命令所带参数,如 weston --tty=2,位于 /etc/init.d/S49weston,对应 SDK 代码中位置为: buildroot/package/weston/S49weston

  2. weston.ini 配置文件

    位于 /etc/xdg/weston/weston.ini/etc/xdg/weston/weston.ini.d/ 下的.ini 文件,对应 SDK 代码中位置如: buildroot/board/rockchip/common/base/etc/xdg/weston/weston.ini

    参考: https://fossies.org/linux/weston/man/weston.ini.man

  3. 特殊环境变量

    此类环境变量一般设置在 /etc/profile.d/weston.sh,对应 SDK 代码中位置为: buildroot/package/weston/weston.sh

  4. 动态配置文件

    对于 drm 后端显示功能,Buildroot SDK 中的 Weston 提供一些动态配置支持,默认路径为 /tmp/weston_drm.conf,可以通过环境变量 WESTON_DRM_CONFIG 指定。

  5. udev rules

    Weston 中输入设备的部分配置需要通过 udev rules

:::info 常见配置举例 以下为常见配置说明,可供参考! :::

19.1 屏幕区分

Weston使⽤output(head) name区分屏幕设备。具体信息获取可以通过Weston启动log:

:::tip 举个例子 例如,一台电脑连接了两个显示器,Weston 可能会将其中一个显示器的 output(head) name 设置为 HDMI-0,另一个设置为 DP-1。这样,用户或应用程序就可以根据这些名称来指定特定的操作或显示内容在相应的屏幕上进行。

# weston&

[02:11:29.746] DRM: head 'DSI-1' found ...

:::

19.2 ⿏标样式及⼤小

配置文件路径:/etc/xdg/weston/weston.ini

Weston⽀持在weston.ini配置⽂件的shell段设置⿏标样式和⼤小。

:::tip 举个例子

# /etc/xdg/weston/weston.ini

[shell]
cursor-theme=whiteglass # Buildroot SDK⽀持comix/obsidian/xcursor/xcursor_transparent⿏标主题包
cursor-size=24 #设置鼠标大小

:::

19.3 状态栏配置

配置文件路径:/etc/xdg/weston/weston.ini

【shell】:设置状态栏的背景⾊、位置、缩放

【launcher】:设置快捷启动程序

:::tip 举个例子

# /etc/xdg/weston/weston.ini

[shell]
panel-color=0x90ff0000
# 设置状态栏颜色,颜⾊格式为ARGB8888
panel-position=bottom
# 设置状态栏位置,top|bottom|left|right|none,none为禁⽌
panel-scale=4
# 设置状态栏大小,此处为缩放为4倍

[launcher]
icon=/usr/share/icons/gnome/24x24/apps/utilities-terminal.png
# 图标路径
path=/usr/bin/gnome-terminal
# 快捷启动命令

[launcher]
# 图标路径
icon=/usr/share/weston/icon_flower.png
# 快捷启动命令
path=/usr/bin/qsetting

说明:状态栏要防止几个快捷方式就创建几个[launcher],用户可以根据需要自行调整。

:::

19.4 桌面背景配置

配置文件路径:/etc/xdg/weston/weston.ini

【shell】:设置背景图案、颜⾊

【desktop-launcher】:设置快捷启动程序

:::tip 举个例子

# /etc/xdg/weston/weston.ini

[shell]
background-image=/usr/share/backgrounds/gnome/Aqua.jpg
# 背景图案(壁纸)绝对路径
background-type=tile
# scale|scale-crop|tile
background-color=0xff002244
# 颜⾊格式为ARGB8888,未设置背景图案时⽣效

[desktop-launcher]
icon=/usr/share/icons/hicolor/256x256/apps/chromium.png
# 图标路径
path=/usr/bin/chromium www.baidu.com
# 快捷启动命令
displayname=chromium
# 显⽰名称 

:::

19.5 待机及锁屏配置

配置文件路径:/etc/init.d/S50launcher 或者 /etc/xdg/weston/weston.ini

Weston的超时待机时⻓可以在启动参数中配置,也可以在weston.ini的core段配置。

:::tip 举个例子

启动参数配置

# /etc/init.d/S49weston

start_weston()
{
/usr/bin/weston --idle-time=0& # 0为禁⽌待机,单位为秒
}

weston.ini参数配置

# /etc/xdg/weston/weston.ini

[core]
idle-time=10
# 0 为禁止待机,此处为设置 10 秒未操作后进入待机状态

:::

Weston的锁屏可以在weston.ini的shell段配置。

:::tip 举个例子

# /etc/xdg/weston/weston.ini

[shell]
locking=false
# 禁⽌锁屏
lockscreen-icon=/usr/share/icons/gnome/256x256/actions/lock.png
# 解锁按钮图案
lockscreen=/usr/share/backgrounds/gnome/Garden.jpg
# 锁屏界⾯背景

:::

19.6 显⽰颜⾊格式配置

配置文件路径:/etc/xdg/weston/weston.ini

Buildroot SDK 内 Weston ⽬前默认显⽰格式为ARGB8888,对于某些低性能平台,可以在weston.ini的core段配置为RGB565

:::tip 举个例子

# /etc/xdg/weston/weston.ini

[core]
gbm-format=rgb565
# xrgb8888|argb8888|rgb565|xrgb2101010

也可以在weston.ini的output段单独配置每个屏幕的显⽰格式,如:

# /etc/xdg/weston/weston.ini
 
[output]
name=LVDS-1
gbm-format=rgb565
# xrgb8888|argb8888|rgb565|xrgb2101010

:::

19.7 屏幕⽅向配置

配置文件路径:/etc/xdg/weston/weston.ini

Weston的屏幕显⽰⽅向可以在weston.ini的output段配置。

:::tip 举个例子

# /etc/xdg/weston/weston.ini

[output]
name=LVDS-1
transform=rotate-90
# normal|rotate-90|rotate-180|rotate-270|flipped|flipped-90|flipped-180|flipped-270

:::

如果需要动态配置屏幕⽅向,可以通过动态配置⽂件。

:::tip 举个例子

echo "output:all:rotate90" > /tmp/.weston_drm.conf # 所有屏幕旋转90度
echo "output:eDP-1::rotate180" > /tmp/.weston_drm.conf # eDP-1旋转180度

:::

19.8 分辨率及缩放配置

配置文件路径:/etc/xdg/weston/weston.ini

Weston的屏幕分辨率及缩放可以在weston.ini的output段配置。

:::tip 举个例子

# /etc/xdg/weston/weston.ini

[output]
name=LVDS-1
mode=1280x800
# 需为屏幕⽀持的有效分辨率
scale=2
# 需为整数倍数,⽀持应⽤内部实现缩放

:::

如需要缩放到特定分辨率(物理分辨率不变),可以通过WESTON_DRM_VIRTUAL_SIZE环境变量配置所有屏幕的⼤小。 :::tip 举个例子

# /etc/profile.d/weston.sh
export WESTON_DRM_VIRTUAL_SIZE=1024x768

:::

如果需要动态配置分辨率及缩放,可以通过动态配置⽂件。 :::tip 举个例子

echo "output:HDMI-A-1:mode=800x600" > /tmp/.weston_drm.conf # 修改HDMI-A-1分辨
率为800x600
echo "output:eDP-1:rect=<10,20,410,620>" > /tmp/.weston_drm.conf # eDP-1显⽰到
(10,20)位置,⼤小缩放为400x600
echo "output:HDMI-A-1:size=1920x1080" > /tmp/.weston_drm.conf # 缩放HDMI-A-1到
1080p,物理分辨率不变

:::

:::warning 以上缩放时,如果硬件VOP显⽰模块不⽀持缩放,则需要依赖RGA处理。 :::

19.9 冻结屏幕

配置文件路径:/etc/init.d/S49weston

在启动Weston时,开机logo到UI显⽰之间存在短暂切换⿊屏。如需要防⽌⿊屏,可以通过以下⽅式短暂冻结Weston屏幕内容。使⽤定制--warm-up运⾏参数在UI启动后开始显⽰。

:::tip 举个例子

# /etc/init.d/S49weston

start_weston()
{
/usr/bin/weston --warm-up&
}

或者

# /etc/init.d/S49weston

start_weston()
{
export WESTON_FREEZE_DISPLAY=/tmp/.weston_freeze # 设置特殊配置⽂件路径
touch /tmp/.weston_freeze # 冻结显⽰
/usr/bin/weston&
sleep 1 && rm /tmp/.weston_freeze& # 1秒后解冻
}

⼜或者

# /etc/init.d/S49weston

start_weston()
{
echo "output:all:freeze" > /tmp/.weston_drm.conf # 冻结显⽰
/usr/bin/weston&
...
sleep 1 && \
echo "output:all:unfreeze" > /tmp/.weston_drm.conf& # 1秒后解冻
}

:::

19.10 屏幕状态配置

DRM框架⽀持强制配置屏幕状态。

:::tip 举个例子

echo on > /sys/class/drm/card0-HDMI-A-1/status 
# 强制HDMI-A-1为接⼊状态
# on|off|detect,detect为热拔插

:::

如果需要更具体的动态屏幕状态配置,可以通过动态配置⽂件。

:::tip 举个例子

echo "output:DSI-1:off" > /tmp/.weston_drm.conf #关闭DSI(⾮拔出)
echo "output:HDMI-A-1:freeze" > /tmp/.weston_drm.conf #冻结HDMI-A-1
echo "output:eDP-1:on" > /tmp/.weston_drm.conf #开启eDP
echo "compositor:state:off" > /tmp/.weston_drm.conf #显⽰休眠
echo "compositor:state:sleep" > /tmp/.weston_drm.conf #显⽰休眠,触屏唤醒
echo "compositor:state:freeze" > /tmp/.weston_drm.conf #冻结显⽰
echo "compositor:state:on" > /tmp/.weston_drm.conf #显⽰唤醒

:::

19.11 多屏管理

Buildroot SDK的Weston⽀持多屏镜像同显、多屏异显、屏幕位置配置及热拔插等功能。镜像模式缩放时,如果硬件VOP显⽰模块不⽀持缩放,则需要依赖RGA处理。

:::tip 举个例子

通过环境变量设置:

# /etc/profile.d/weston.sh

export WESTON_DRM_PRIMARY=HDMI-A-1 # 指定主显为HDMI-A-1
export WESTON_DRM_SINGLE_HEAD=1 # 强制单显
export WESTON_DRM_MIRROR=1 # 使⽤镜像模式(多屏同显),不设置此环境变量即为异显
export WESTON_DRM_KEEP_RATIO=1 # 镜像模式下缩放保持纵横⽐,不设置此变量即为强制全屏
export WESTON_DRM_HEAD_MODE=primary # 只使能主显
export WESTON_DRM_HEAD_MODE=internal # 只使能内置显⽰器
export WESTON_DRM_HEAD_MODE=external # 只使能外置显⽰器
export WESTON_DRM_HEAD_MODE=external-dual # 使能所有显⽰器,优先外置显⽰器
export WESTON_DRM_HEAD_FALLBACK=1 # 未匹配到显⽰器时,使能任意⼀个有效显⽰器
export WESTON_DRM_MASTER=1 # 允许关闭未使⽤的屏幕
export WESTON_OUTPUT_FLOW=horizontal # 默认⽔平排列
export WESTON_OUTPUT_FLOW=vertical # 默认垂直排列
export WESTON_OUTPUT_FLOW=same-as # 所有显⽰器默认位置(0,0)

通过在weston.ini的output段单独禁⽤指定屏幕:

# /etc/xdg/weston/weston.ini

[output]
name=LVDS-1
mode=off
# off|current|preferred|<WIDTHxHEIGHT@RATE>

还可以通过动态配置⽂件:

echo "output:HDMI-A-1:pos=100,200" > /tmp/.weston_drm.conf # 设置HDMI显⽰位置
echo "output:HDMI-A-1:prefer" > /tmp/.weston_drm.conf # 设置应⽤默认显⽰HDMI上
echo "output:HDMI-A-1:primary" > /tmp/.weston_drm.conf # 设置主显为HDMI

:::

19.12 输⼊设备配置

配置文件路径:/etc/xdg/weston/weston.ini

Weston服务默认需要⾄少⼀个输⼊设备,如⽆输⼊设备,则需要在weston.ini中的core段特殊设置。

:::tip 举个例子

# /etc/xdg/weston/weston.ini
[core]
require-input=false

:::

Weston中如存在多个屏幕,需求绑定把输⼊设备和屏幕,则可通过udev规则配置WL_OUTPUT。 :::tip 举个例子

# /lib/udev/rules.d/99-goodix-ts.rules
ATTRS{name}=="goodix-ts", ENV{WL_OUTPUT}="HDMI-A-1"

或者配置WL_SEAT:

# /lib/udev/rules.d/99-goodix-ts.rules
ATTRS{name}=="goodix-ts", ENV{WL_SEAT}="seat1"
# /etc/xdg/weston/weston.ini
[output]
name=LVDS-1
seat=seat1

或者通过动态配置⽂件,如:

echo "output:HDMI-A-1:input=*" > /tmp/.weston_drm.conf # 匹配所有设备
echo "output:HDMI-A-1:input=" > /tmp/.weston_drm.conf # 禁⽤输⼊
echo "output:HDMI-A-1:input=event6" > /tmp/.weston_drm.conf
echo "output:HDMI-A-1:input=goodix*" > /tmp/.weston_drm.conf
echo "output:HDMI-A-1:input=goodix-ts" > /tmp/.weston_drm.conf

输⼊设备的vendor id、product id及设备名可通过evtest⼯具查询,如:

# evtest /dev/input/event8 | head -3
Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0xdead product 0xbeef version 0x28bb
Input device name: "goodix-ts"

:::

19.13 触屏校准

配置文件路径:/etc/profile.d/weston.sh

Weston如果需要校准触屏,可以通过WESTON_TOUCH_CALIBRATION环境变量。

:::tip 举个例子

# /etc/profile.d/weston.sh
export WESTON_TOUCH_CALIBRATION="1.013788 0.0 -0.061495 0.0 1.332709
-0.276154"

:::

或者通过udev规则配置。

:::tip 举个例子

# /lib/udev/rules.d/99-goodix-ts.rules
ATTRS{name}=="goodix-ts", ENV{LIBINPUT_CALIBRATION_MATRIX}="1.013788 0.0
-0.061495 0.0 1.332709 -0.276154

:::

校准参数的获取可以使⽤Weston校准⼯具:

weston-calibrator,⼯具运⾏后会⽣成若⼲随机点,依次点击后输出校准参数,如:Final calibration values: 1.013788 0.0 -0.061495 0.0 1.332709 -0.276154

也可以直接使⽤Weston提供的另⼀个校准⼯具:weston-touch-calibrator 需要配置:

# /etc/xdg/weston/weston.ini
[libinput]
touchscreen_calibrator=true
calibration_helper=/bin/weston-calibration-helper.sh

19.14 ⽆ GPU 平台配置

SDK中的Weston默认使⽤GPU进⾏渲染合成加速,对于⽆GPU或GPU性能不⾜的平台,也可以选⽤RGA替代进⾏加速。

Buildroot SDK需要开启如下两项配置:

BR2_PACKAGE_LINUX_RGA = y
BR2_PACKAGE_WESTON_DEFAULT_PIXMAN = y

19.15 ARM AFBC modifier 配置

当芯⽚⽀持AFBC时,SDK中的Weston⽀持使⽤基于GPU的AFBC压缩格式进⾏显⽰。

:::tip 举个例子

# /etc/profile.d/weston.sh
# export WESTON_DISABLE_ATOMIC=1

export WESTON_ALLOW_GBM_MODIFIERS=1

:::

19.16 降低 UI 分辨率

当UI性能或DDR带宽不⾜时,可以降低UI的分辨率。

:::tip 举个例子

echo "output:HDMI-A-1:down-scale=0.5" >> /tmp/.weston_drm.conf # UI缩放0.5倍

:::

具体可参考Weston开发⽂档 <SDK>/docs/cn/Linux/Graphics/Rockchip_Developer_Guide_Buildroot_Weston_CN.pdf

20. 截屏功能

buildroot:/# killall weston
buildroot:/# weston --debug&
buildroot:/# weston-screenshooter
就可以截图当前画⾯

21. 中⽂显⽰的⽀持

weston如下配置:

$ cat /etc/xdg/weston/weston.ini
[terminal]
font=Source Han Sans CN Medium
font-size=14
term=xterm-256color

把buildroot的configs/rockchip/locale/chinese.config导⼊或者开启以下配置:

BR2_TOOLCHAIN_GLIBC_GCONV_LIBS_COPY=y
BR2_PACKAGE_BUSYBOX_UNICODE=y
# BR2_ENABLE_LOCALE_PURGE is not set
BR2_GENERATE_LOCALE="zh_CN.UTF-8

buildroot中环境变量的设定:

root@rk3588:/# cat /etc/profile.d/lang.sh
export LANG=zh_CN.utf8

buildroot中相关提交如下:

buildroot$ git log --oneline
c476944fee configs: locale.config: Disable BR2_ENABLE_LOCALE_PURGE
f9654d67c8 localedef: Sync with 2018 SDK
2cbb75a54c coreutils: Support bypassing Unicode when printing
15340338dc busybox: Support bypassing Unicode when printing
5e9b8ba00c configs: rockchip: Add locale.config
863eed048e busybox: Support enabling unicode
device/rockchip$ git log --oneline
5c42211 post-rootfs.sh: Support setting LANG environment

修订历史

修订时间 版本号 修订人 修订内容
2025年4月8号 V0.9 nnewn-kwf 首次创建