最新资讯

  • Rockchip RK3588 - Rockchip Linux SDK编译

Rockchip RK3588 - Rockchip Linux SDK编译

2025-06-04 20:01:03 5 阅读

----------------------------------------------------------------------------------------------------------------------------

开发板 :ArmSoM-Sige7开发板eMMC64GBLPDDR48GB
显示屏 :15.6英寸HDMI接口显示屏u-boot2017.09linux5.10
----------------------------------------------------------------------------------------------------------------------------

一、SDK软件架构

1.1 SDK工程目录介绍

一个通用Linux SDK工程目录包含有buildrootdebianappkernelu-bootdeviceexternal等目录;

  • app:存放上层应用APP,主要是一些应用Demo
  • buildroot:存放Buildroot开发的根文件系统;
  • debian:存放Debian开发的根文件系统;
  • device/rockchip:存放芯片板级配置以及一些编译和打包固件的脚本和文件;
  • docs:存放通用开发指导文档、Linux系统开发指南、芯片平台相关文档等;
  • external:存放第三方相关仓库,包括显示、音视频、摄像头、网络、安全等;
  • kernel:存放Kernel开发的代码;
  • output:存放每次生成的固件信息、编译信息、XML、主机环境等;
  • prebuilts:存放交叉编译工具链;
  • rkbin:存放Rockchip相关二进制和工具;
  • rockdev:存放编译输出固件,实际软链接到output/firmware
  • tools:存放LinuxWindow操作系统下常用工具;
  • u-boot:存放基于v2017.09版本进行开发的U-Boot代码;
  • yocto:存放Yocto开发的根文件系统;
1.2 SDK概述

通用Linux SDK目前已集成主流的几个Linux发行版(Distribution),发行版就是我们日常在Linux主机上使用的那些系统,为用户预先集成好的Linux操作系统及各种应用软件。Linux发行版的形式多种多样,有从功能齐全的桌面系统到服务器版本到小型系统。比如支持桌面版本的Debian系统,可定制化的Buildroot/Yocto轻量级系统。

1.2.1 Buildroot系统

Rockchip Linux SDKBuildroot系统,其包含了基于Linux系统开发用到的各种系统源码,驱动,工具,应用软件包。BuildrootLinux平台上一个开源的嵌入式Linux系统自动构建框架。整个Buildroot是由Makefile脚本和Kconfig配置文件构成的。可通过Buildroot配置,编译出一个完整的可以直接烧写到机器上运行的Linux系统软件。

Buildroot有以下几点优势:

  • 通过源码构建,有很大的灵活性;
  • 方便的交叉编译环境,可以进行快速构建,容易上手;
  • 提供系统各组件的配置,方便定制开发。

使用Buildrootproject最出名的就是Openwrt。可以看到,由它制作出的镜像可以跑在搭载16 Mb SPINOR的路由器上,系统基本没包含多余的东西。 这就是得益于Buildroot的简单化。整个Buildroot工程在一个git维护。

Buildroot使用kconfigmake,一个defconfig配置代表一种BSP支持。Buildroot 本身不具备扩展能力,用户需要自己通过脚本来完成工作。这些列出来的特点,都是和Yocto不同的地方。

注意:Buildroot实际上使用Busybox来制作根文件系统。

1.2.2 Yocto

YoctoBuildroot一样, 是一套构建嵌入式系统的工具,但是两者的风格完全不同。

Yocto工程是通过一个个单独的包(meta)来维护,比如有的包负责核心,有的包负责外围。有的包用于跑Rockchip的芯片,有的包用于安装上weston, 有的包是则是用于跑debian, 同样采用类似机制的nodejs,社区膨胀非常厉害,活跃度很高,每个人都可分享自己的成果到github上,这样的机制保证了我们可从互联网复用别人的工作成果,相当有价值。

相比Buildroot系统,Yocto有其更强的编译机制,比如第三方包的依赖和重编,都会自动处理。缺点相对复杂、需VPN网络。

Yocto是一个非常灵活的构建系统,允许用户使用shellPython来处理各种特殊情况。目前,该系统主要针对国外客户。如果您需要更多关于Yocto的信息,请查看以下参考资料:

  • Yocto
  • Rockchip Yocto
  • Yocto stable branch
1.2.3 Debian

Debian是一种完全自由开放并广泛用于各种设备的Linux操作系统,选择Debian原因如下:

  • Debian是自由软件:Debian是由自由和开放源代码的软件组成,并将始终保持100%自由,每个人都能自由使用、修改,以及发布,大家可以基Rockchip构建的Debian系统进行二次开发;
  • Debian是一个基于Linux稳定且安全的的操作系统:Debian是一个广泛用于各种设备的操作系统,其使用范围包括笔记本计算机,台式机和服务器。自1993年以来,它的稳定性和可靠性就深受用户的喜爱。我们为每个软件包提供合理的默认配置,Debian开发人员会尽可能在其生命周期内为所有软件包提供安全更新;
  • Debian具有广泛的硬件支持:大多数硬件已获得Linux内核的支持。当自由软件无法提供足够的支持时,也可使用专用的硬件驱动程序。目前Rockchip RK3588/RK3568/RK3566/RK3399/RK3288等芯片已经适配并支持;
  • Debian提供平滑的更新:Debian以在其发行周期内轻松流畅地进行更新而闻名,不仅如此,还包括轻松升级到下一个大版本。Rockchip目前已从Debian Stretch(9)升级到Debian Buster(10)Bullseye(11)版本;
  • Debian是许多其他发行版的种子和基础:许多非常受欢迎的Linux发行版,例如UbuntuKnoppixPureOSSteamOS以及 Tails,都选择了Debian作为它们的软件基础。Debian提供了所有工具,因此每个人都可以用能满足自己需求的软件包来扩展 Debian档案库中的软件包;
  • Debian项目是一个社区:Debian不只是一个Linux操作系统。该软件由来自世界各地的数百名志愿者共同制作。即使您不是一个程序员或系统管理员,也可以成为Debian社区的一员;

Rockchip定制版的Debian系统是通过Shell脚本来达到获取构建Linux Debian发行版源码,编译和安装适配Rockchip硬加速包的操作系统。

1.3 SDK软件框图

SDK软件框图如下图所示:

从下至上分为启动层、内核层、库、应用层四个层次。各层次内容如下:

  • 启动层主要提供系统启动,如BootROMU-BootATF等相关支持;
  • 内核层主要提供Linux Kernel的标准实现,Linux也是一个开放的操作系统,Rockchip平台的Linux核心为标准的Linux4.4/4.19/5.10内核,提供安全性,内存管理,进程管理,网络协议栈等基础支持;主要是通过Linux内核管理设备硬件资源,如CPU调度、缓存、内存、I/O等;
  • 库层对应一般嵌入式系统,相当于中间件层次。包含了各种系统基础库,及第三方开源程序库支持,对应用层提供API接口,系统定制者和应用开发者可以基于Libraries层的API开发新的应用;
  • 应用层主要是实现具体的产品功能及交互逻辑,需要一些系统基础库及第三方程序库支持,开发者可以开发实现自己的应用程序,提供系统各种能力给到最终用户。

SDK系统启动流程是指系统上电到系统启动完成的一个软件流程,下面是linux系统启动流程:

注意:

  • APMCU内部都有集成一个 BootROM,系统上电时先会运行BootROM代码,然后BootROM代码会探测外设存储器并加载Loader代码;
  • PreLoader 前有3个: miniloader(非开源), uboot tpluboot spl loader
1.4 SDK开发流程

Rockchip Linux系统是基于Buildroot/Yocto/Debian系统,,内核基于kernel 4.4/4.19/5.10开发,针对多种不同产品形态开发的SDK。可以基于本SDK,有效地实现系统定制和应用移植开发。

如图所示,开发者可以遵循上述开发流程,在本地快速构建Rockchip Linux系统的开发环境和编译代码。下面将简单介绍下该流程:

  • 检查系统需求:在下载代码和编译前,需确保本地的开发设备能够满足需求,包括机器的硬件能力,软件系统,工具链等。目前SDK支持Linux操作系统环境下编译,并仅提供Linux环境下的工具链支持,其他如MacOSWindows等系统暂不支持;
  • 搭建编译环境:介绍开发机器需要安装的各种软件包和工具,详见第二节SDK开发坏境搭建。
  • 选择设备:在开发过程中,需要开发者根据自己的需求,选择对应的硬件板型;
  • 下载源代码:选定设备类型后,需要安装repo工具用于批量下载源代码;
  • 系统定制:开发者可以根据使用的硬件板子、产品定义,定制u-bootkernelrootfs,详见第五节SDK开发;
  • 编译与打包:介绍具备源代码后,选择产品及初始化相关的编译环境,而后执行编译命令,包括整体或模块编译以及编译清理等工作,进一步内容详见第三节SDK编译说明。
  • 烧录并运行:继生成镜像文件后,将介绍如何烧录镜像并运行在硬件设备,进一步内容详见第四节SDK固件升级;

二、SDK开发环境搭建

2.1 概述

本节主要介绍了如何在本地搭建编译环境来编译Rockchip Linux SDK源代码,当前SDK只支持在Linux环境下编译和进行二次开发。

一个典型的嵌入式开发环境通常包括Linux服务器、PC和目标硬件版,典型开发环境如下图所示;

其中:

  • Linux服务器上建立交叉编译环境,为软件开发提供代码、更新下载和进行编译等服务;
  • PCLinux服务器共享程序,并安装PuttyMinicom,通过网络远程登陆到Linux服务器,进行交叉编译,及代码的开发调试;
  • PC通过串口和USB与目标硬件板连接,可将编译后的镜像文件烧写到目标硬件板,并调试系统或应用程序。
2.2 源码获取

在一个大型项目中,一般会拆成多个子系统来分开管理,每一个子系统都对应着一个git仓库。但在拉取整个项目的时候就需要一个一个去拉取仓库,或者要写一个shell脚本去拉取,这样做可以,但略显笨拙。于是repo来拯救了我们,它是一个建立在git上的工具,本质其实是一个Python脚本,所以需要安装Python,像Android这样的系统也是用repo来管理的。

Rockchip Linux SDK的代码和相关文档被划分为了若干git仓库分别进行版本管理,开发者可以使用repo对这些git仓库进行统一的下载、提交、切换分支等操作。

获取Rockchip Linux软件包,需要有一个帐户访问Rockchip提供的源代码仓库。客户向瑞芯微技术窗口申请SDK,同步提供SSH公钥进行服务器认证授权,获得授权后即可同步代码。

请根据《Rockchip_User_Guide_SDK_Application_And_Synchronization_CN》文档说明操作,生成SSH公钥,发邮件至fae@rock-chips.com,申请开通SDK代码。该文档会在申请开通权限流程中,释放给客户使用。

作为一个用户这里我们大概率是无法直接申请开通SDK代码的,所以这里直接使用armsom开发板厂商提供的SDK源码;

这里我们从https://github.com/ArmSoM/armsom-rk3588-bsp下载SDK源码,命令如下:

root@ubuntu:/work/sambashare/rk3588/armsom# git clone https://github.com/ArmSoM/armsom-rk3588-bsp.git
root@ubuntu:/work/sambashare/rk3588/armsom# cd armsom-rk3588-bsp
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# ll
drwxr-xr-x  5 zhengyang zhengyang 4096  6月 10 21:42 ../
drwxr-xr-x 10 root      root      4096  6月  9 12:58 app/
drwxr-xr-x 16 root      root      4096  6月  9 12:58 buildroot/
lrwxrwxrwx  1 root      root        39  6月  9 12:58 build.sh -> device/rockchip/common/scripts/build.sh*
drwxr-xr-x  9 root      root      4096  6月  9 12:58 debian/
drwxr-xr-x  3 root      root      4096  6月  9 12:58 device/
drwxr-xr-x  6 root      root      4096  6月  9 12:58 docs/
lrwxrwxrwx  1 root      root        27  6月  9 12:58 envsetup.sh -> buildroot/build/envsetup.sh*
drwxr-xr-x 26 root      root      4096  6月  9 12:59 external/
drwxr-xr-x  8 root      root      4096  6月  9 12:59 .git/
drwxr-xr-x 26 root      root      4096  6月  9 12:59 kernel/
lrwxrwxrwx  1 root      root        31  6月  9 12:58 Makefile -> device/rockchip/common/Makefile
drwxr-xr-x  3 root      root      4096  6月  9 12:59 prebuilts/
drwxr-xr-x  9 root      root      4096  6月  9 12:59 rkbin/
lrwxrwxrwx  1 root      root        41  6月  9 12:59 rkflash.sh -> device/rockchip/common/scripts/rkflash.sh*
drwxr-xr-x  5 root      root      4096  6月  9 12:59 tools/
drwxr-xr-x 24 root      root      4096  6月  9 12:59 u-boot/
drwxr-xr-x  5 root      root      4096  6月  9 12:59 uefi/
drwxr-xr-x  9 root      root      4096  6月  9 12:59 yocto/

注意:这里我直接从开发板厂商获取了最新的代码。

2.2.1 u-bootkernel编译工具链

鉴于Rockchip Linux SDK目前只在Linux PC环境下编译,SDK提供了Linux下的交叉编译工具链。prebuilt目录下的工具链是u-bootkernel使用;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# ls prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/
aarch64-none-linux-gnu-addr2line      aarch64-rockchip1031-linux-gnu-addr2line
aarch64-none-linux-gnu-ar             aarch64-rockchip1031-linux-gnu-ar
aarch64-none-linux-gnu-as             aarch64-rockchip1031-linux-gnu-as
aarch64-none-linux-gnu-c++            aarch64-rockchip1031-linux-gnu-c++
aarch64-none-linux-gnu-c++filt        aarch64-rockchip1031-linux-gnu-c++filt
aarch64-none-linux-gnu-cpp            aarch64-rockchip1031-linux-gnu-cpp
aarch64-none-linux-gnu-dwp            aarch64-rockchip1031-linux-gnu-dwp
aarch64-none-linux-gnu-elfedit        aarch64-rockchip1031-linux-gnu-elfedit
aarch64-none-linux-gnu-g++            aarch64-rockchip1031-linux-gnu-g++
aarch64-none-linux-gnu-gcc            aarch64-rockchip1031-linux-gnu-gcc
aarch64-none-linux-gnu-gcc-10.3.1     aarch64-rockchip1031-linux-gnu-gcc-10.3.1
aarch64-none-linux-gnu-gcc-ar         aarch64-rockchip1031-linux-gnu-gcc-ar
aarch64-none-linux-gnu-gcc-nm         aarch64-rockchip1031-linux-gnu-gcc-nm
aarch64-none-linux-gnu-gcc-ranlib     aarch64-rockchip1031-linux-gnu-gcc-ranlib
aarch64-none-linux-gnu-gcov           aarch64-rockchip1031-linux-gnu-gcov
aarch64-none-linux-gnu-gcov-dump      aarch64-rockchip1031-linux-gnu-gcov-dump
aarch64-none-linux-gnu-gcov-tool      aarch64-rockchip1031-linux-gnu-gcov-tool
aarch64-none-linux-gnu-gdb            aarch64-rockchip1031-linux-gnu-gdb
aarch64-none-linux-gnu-gdb-add-index  aarch64-rockchip1031-linux-gnu-gdb-add-index
aarch64-none-linux-gnu-gfortran       aarch64-rockchip1031-linux-gnu-gfortran
aarch64-none-linux-gnu-gprof          aarch64-rockchip1031-linux-gnu-gprof
aarch64-none-linux-gnu-ld             aarch64-rockchip1031-linux-gnu-ld
aarch64-none-linux-gnu-ld.bfd         aarch64-rockchip1031-linux-gnu-ld.bfd
aarch64-none-linux-gnu-ld.gold        aarch64-rockchip1031-linux-gnu-ld.gold
aarch64-none-linux-gnu-lto-dump       aarch64-rockchip1031-linux-gnu-lto-dump
aarch64-none-linux-gnu-nm             aarch64-rockchip1031-linux-gnu-nm
aarch64-none-linux-gnu-objcopy        aarch64-rockchip1031-linux-gnu-objcopy
aarch64-none-linux-gnu-objdump        aarch64-rockchip1031-linux-gnu-objdump
aarch64-none-linux-gnu-ranlib         aarch64-rockchip1031-linux-gnu-ranlib
aarch64-none-linux-gnu-readelf        aarch64-rockchip1031-linux-gnu-readelf
aarch64-none-linux-gnu-size           aarch64-rockchip1031-linux-gnu-size
aarch64-none-linux-gnu-strings        aarch64-rockchip1031-linux-gnu-strings
aarch64-none-linux-gnu-strip          aarch64-rockchip1031-linux-gnu-strip

对应版本:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc -v
......
gcc 版本 10.3.1 20210621 (GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29))
2.2.2 rootfs编译工具链

具体rootfs需要用各自对应的工具链,或者使用第三方工具链进行编译。

Buildroo为例,具体参考:

  • buildroot/docs/manual/using-buildroot-toolchain.txt
  • buildroot/docs/manual/adding-packages.txt
2.3 Linux服务器搭建
2.3.1 ubuntu 22.04

这里我们使用ubuntu 22.04来进行编译,因为只有该版本及以上版本glibc才支持GLIBC_2.33GLIBC_2.34版本;由于我之前在虚拟机搭建的ubuntu版本为20.04,因此这里需要对系统进行升级;

zhengyang@ubuntu:~/桌面$ sudo apt install update-manager-core

然后运行软件更新器:

主要:这里不要通过对glibc源码进行编译得到高版本的glibc,这种做法可能导致系统崩溃。

此外:硬盘空间大于40G,如果您进行多个构建,将需要更大的硬盘空间。

2.3.2 安装库和工具集

使用命令行进行设备开发时,可以通过以下步骤安装编译SDK需要的库和工具;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# sudo apt update
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# sudo apt install git ssh make gcc libssl-dev 
liblz4-tool expect expect-dev g++ patchelf chrpath gawk texinfo chrpath 
diffstat binfmt-support qemu-user-static live-build bison flex fakeroot 
cmake gcc-multilib g++-multilib unzip device-tree-compiler ncurses-dev 
libgucharmap-2-90-dev bzip2 expat gpgv2 cpp-aarch64-linux-gnu libgmp-dev 
libmpc-dev bc python-is-python3 python2
2.3.3 设置DNS支持kgithub.com

如果PC在编译Buildroot时无法访问Google网站,需设置DNS来支持使用国内镜像kgithub.com下载dl包。

sudo sed -i '$a 43.154.68.204	kgithub.com' /etc/hosts
sudo sed -i '$a 43.155.83.75traw.kgithub.com objects.githubusercontent.kgithub.com' /etc/hosts
2.3.4 检查和升级主机的python版本

python要求安装python 3.6及以上版本,检查主机python版本:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# python3 --version
Python 3.10.12

如果不满足python>=3.6版本的要求, 可通过如下方式升级:

PYTHON3_VER=3.6.15
echo "wget
https://www.python.org/ftp/python/${PYTHON3_VER}/Python-${PYTHON3_VER}.tgz"
echo "tar xf Python-${PYTHON3_VER}.tgz"
echo "cd Python-${PYTHON3_VER}"
echo "sudo apt-get install libsqlite3-dev"
echo "./configure --enable-optimizations"
echo "sudo make install -j8"
2.3.5 检查和升级主机的make版本

make要求安装make 4.0及以上版本,检查主机make版本;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# make -v
GNU Make 4.3
为 x86_64-pc-linux-gnu 编译
Copyright (C) 1988-2020 Free Software Foundation, Inc.
许可证:GPLv3+:GNU 通用公共许可证第 3 版或更新版本。
本软件是自由软件:您可以自由修改和重新发布它。
在法律允许的范围内没有其他保证。

如果不满足make>=4.0版本的要求, 可通过如下方式升级:

sudo apt update && sudo apt install -y autoconf autopoint
git clone https://gitee.com/mirrors/make.git
cd make
git checkout 4.2
git am $BUILDROOT_DIR/package/make/*.patch
autoreconf -f -i
./configure
make make -j8
sudo install -m 0755 make /usr/bin/make
2.3.6 检查和升级主机的lz4版本

lz4要求安装1.7.3及以上版本,检查主机lz4版本

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# lz4 -v
*** LZ4 command line interface 64-bits v1.9.3, by Yann Collet ***
refusing to read from a console

如果不满足LZ4>=1.7.3版本的要求, 可通过如下方式升级:

git clone https://gitee.com/mirrors/LZ4_old1.git
cd LZ4_old1
make
sudo make install
sudo install -m 0755 lz4 /usr/bin/lz4

三、SDK编译说明

3.1 SDK编译命令查看

首先通过help命令查看SDK编译命令:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# make help
  menuconfig             - interactive curses-based configurator
  oldconfig              - resolve any unresolved symbols in .config
  syncconfig             - Same as oldconfig, but quietly, additionally update deps
  olddefconfig           - Same as syncconfig but sets new symbols to their default value
  savedefconfig          - Save current config to RK_DEFCONFIG (minimal config)
  clean                  - Cleanup
  ......

make实际运行是./build.sh,即也可运行./build.sh 来编译相关功能,具体可通过./build.sh help查看具体编译命
令:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# ./build.sh help
Usage: build.sh [OPTIONS]
Available options:
chip[:[:]]                choose chip
defconfig[:]                    choose defconfig
 *_defconfig                            switch to specified defconfig
    available defconfigs:
        rockchip_defconfig
        rockchip_rk3588_evb1_lp4_v10_defconfig
        rockchip_rk3588_evb7_v11_defconfig
        rockchip_rk3588_sige7_defconfig
        rockchip_rk3588s_evb1_lp4x_v10_defconfig
 olddefconfig                           resolve any unresolved symbols in .config
 savedefconfig                          save current config to defconfig
 menuconfig                             interactive curses-based configurator
config                                  modify SDK defconfig
shell                                   setup a shell for developing
print-parts                             print partitions
mod-parts                               interactive partition table modify
edit-parts                              edit raw partitions
new-parts:::...     re-create partitions
insert-part::[:]       insert partition
del-part:(|)                 delete partition
move-part:(|):          move partition
rename-part:(|):       rename partition
resize-part:(|):       resize partition
kernel[:cmds]                           build kernel
modules[:cmds]                          build kernel modules
linux-headers[:cmds]                    build linux-headers
kernel-config[:cmds]                    modify kernel defconfig
kernel-make[::]             run kernel make (alias kmake)
wifibt[:[:]]             build Wifi/BT
rtos                                    build and pack RTOS
buildroot-config[:]             modify buildroot defconfig
buildroot-make[::]          run buildroot make (alias bmake)
rootfs[:]                  build default rootfs
buildroot                               build buildroot rootfs
yocto                                   build yocto rootfs
debian                                  build debian rootfs
recovery                                build recovery
pcba                                    build PCBA
security_check                          check contidions for security boot
createkeys                              build security boot keys
security_ramboot                        build security ramboot
security_uboot                          build uboot with security
security_boot                           build boot with security
security_recovery                       build recovery with security
security_rootfs                         build rootfs with security
loader[:cmds]                           build loader (uboot)
uboot[:cmds]                            build u-boot
uefi[:cmds]                             build uefi
firmware                                pack and check firmwares
edit-package-file                       edit package-file
edit-ota-package-file                   edit A/B OTA package-file
updateimg                               build update image
otapackage                              build A/B OTA update image
all                                     build all images
save                                    save images and build info
allsave                                 build all images and save them
cleanall                                cleanup
clean[:module[:module]]...              cleanup modules
    available modules:
        all
        config
        firmware
        kernel
        loader
        pcba
        recovery
        rootfs
        updateimg
post-rootfs                 trigger post-rootfs hook scripts
help                                    usage

Default option is 'allsave'.

我们定位到build.sh脚本入口,当我们执行./build.sh 时将会执行如下代码;

if [ "$0" != "$BASH_SOURCE" ]; then
        # Sourced, executing it directly
        "$BASH_SOURCE" ${@:-shell}
elif [ "$0" == "$BASH_SOURCE" ]; then
        # Executed directly
        main $@
fi

$0代表脚本名,而$BASH_SOURCE代表脚本文件的路径,因此当执行./build.sh 时,$0$BASH_SOURCE会相同。

因此执行main $@,将调用名为main的函数,并将所有传递给脚本的参数传递给main函数。

有关build.sh文件的分析参考最后一节内容。

3.2 SDK板级配置

具体板级配置说明如下,进入工程device/rockchip/rk3588目录

板级配置说明
rockchip_rk3588_evb1_lp4_v10_defconfig适用于RK3588 EVB1搭配LPDDR4开发板
rockchip_rk3588_evb3_lp5_v10_defconfig适用于RK3588 EVB3 搭配 LPDDR5开发板
rockchip_rk3588_evb7_lp4_v10_defconfig适用于RK3588 EVB7搭配LPDDR4开发板
rockchip_rk3588s_evb1_lp4x_v10_defconfig适用于RK3588S EVB1搭配LPDDR4开发板
rockchip_rk3562_evb1_lp4x_v10_defconfig适用于RK3562 EVB1搭配LPDDR4开发板
rockchip_rk3562_evb2_ddr4_v10_defconfig适用于 RK3566 EVB2 搭配DDR4开发板
rockchip_rk3588_sige7_defconfig适用于RK3355 Sige7开发板
............
rockchip_defconfig默认配置, 具体会软链接到默认一个板级配置

可通过make lunch或者./build.sh lunch进行配置,比如rk3588芯片;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# ./build.sh lunch
Log saved at /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/sessions/2024-06-10_22-25-38

Pick a defconfig:

1. rockchip_defconfig
2. rockchip_rk3588_evb1_lp4_v10_defconfig
3. rockchip_rk3588_evb7_v11_defconfig
4. rockchip_rk3588_sige7_defconfig
5. rockchip_rk3588s_evb1_lp4x_v10_defconfig
Which would you like? [1]:

比如这里我们选择4

Which would you like? [1]: 4
Switching to defconfig: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/.chip/rockchip_rk3588_sige7_defconfig
make: Entering directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/common'
#
# configuration written to /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/.config
#
make: Leaving directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/common'

这里生成了output/.config配置文件,内容如下:

#
# Automatically generated file; DO NOT EDIT.
# Rockchip Linux SDK Configuration
#
RK_DEFCONFIG="/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/.chips/rk3588/rockchip_rk3588_sige7_defconfig"
RK_CHIP_FAMILY="rk3588"
RK_CHIP="rk3588"

#
# Rootfs
#
RK_BUILDROOT_BASE_CFG="rk3588"
RK_BUILDROOT_CFG="rockchip_${RK_BUILDROOT_BASE_CFG}"
RK_YOCTO_CFG="rockchip-rk3588-evb"
RK_YOCTO_CHROMIUM=y
RK_YOCTO_DISPLAY_PLATFORM="wayland"
RK_YOCTO_DISPLAY_PLATFORM_WAYLAND=y
# RK_YOCTO_DISPLAY_PLATFORM_X11 is not set
RK_YOCTO_USBMOUNT=y
RK_DEBIAN_VERSION="bullseye"
RK_DEBIAN_ARCH="arm64"
RK_DEBIAN_ARM64=y
# RK_DEBIAN_ARMHF is not set
RK_ROOTFS_SYSTEM="buildroot"
RK_ROOTFS_SYSTEM_BUILDROOT=y
# RK_ROOTFS_SYSTEM_DEBIAN is not set
# RK_ROOTFS_SYSTEM_YOCTO is not set
RK_ROOTFS_TYPE="ext4"
# RK_ROOTFS_INITRD is not set

......
3.3 配置不同启动/内核/系统等组件

SDK可通过make menuconfig进行相关配置,目前可配组件主要如下:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# make menuconfig
(/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/.chips/rk3588/rockchip_rk
  Rootfs  --->
  Loader (u-boot)  --->
  RTOS  --->
  Kernel  --->
  Boot  --->
  Recovery (buildroot)  --->
  PCBA test (buildroot)  --->
  Security  --->
  Extra partitions  --->
  Firmware  --->
  Update (Update image, OTA and A/B)  --->
  Others configurations  --->

通过以上config,可选择不同rootfs/loader/kernel等配置,进行各种定制化编译。另外还带有强大命令行切换功能。

注意menuconfig配置之后,需要make savedefconfig保存配置;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# make savedefconfig

这里本质上就是修改output/.config文件。

3.4 全自动编译

进入工程根目录执行以下命令自动完成所有的编译,如果只编译模块代码(ubootkernelrootfsrecovery),运行:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# ./build.sh all

输出内容如下:

点击查看代码
Log saved at /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/sessions/2024-06-10_22-51-26

==========================================
          Final configs
==========================================
RK_BOOT_FIT_ITS=boot.its
RK_BOOT_IMG=boot.img
RK_BUILDROOT_CFG=rockchip_rk3588
RK_CHIP=rk3588
RK_CHIP_FAMILY=rk3588
RK_DEBIAN_ARCH=arm64
RK_DEBIAN_ARM64=y
RK_DEBIAN_VERSION=bullseye
RK_DEFCONFIG=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/.chips/rk3588/rockchip_rk3588_sige7_defconfig
RK_EXTRA_PARTITION_NUM=2
RK_EXTRA_PARTITION_STR=oem:oem:/oem:ext4:defaults:normal:auto:@userdata:userdata:/userdata:ext4:defaults:normal:auto:@@@
RK_KERNEL_ARCH=arm64
RK_KERNEL_ARM64=y
RK_KERNEL_CFG=rockchip_linux_defconfig
RK_KERNEL_CFG_FRAGMENTS=rk3588_linux.config
RK_KERNEL_DTB=kernel/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dtb
RK_KERNEL_DTS=kernel/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
RK_KERNEL_IMG=kernel/arch/arm64/boot/Image
RK_KERNEL_KBUILD_ARCH=host
RK_KERNEL_KBUILD_HOST=y
RK_KERNEL_VERSION=5.10
RK_KERNEL_VERSION_REAL=5.10
RK_MISC=y
RK_MISC_BLANK=y
RK_PARAMETER=parameter.txt
RK_PCBA_CFG=rockchip_rk3588_pcba
RK_RECOVERY_CFG=rockchip_rk3588_recovery
RK_RECOVERY_FIT_ITS=boot4recovery.its
RK_ROOTFS_IRQBALANCE=y
RK_ROOTFS_OVERLAY_DIRS=y
RK_ROOTFS_SYSTEM=buildroot
RK_ROOTFS_SYSTEM_BUILDROOT=y
RK_ROOTFS_TYPE=ext4
RK_ROOTFS_UDEV_RULES=y
RK_SAVE_TRACKED=y
RK_SESSION=2024-06-11_22-45-04
RK_UBOOT_ARCH=arm64
RK_UBOOT_ARM64=y
RK_UBOOT_CFG=rk3588
RK_UPDATE=y
RK_USB_ADBD=y
RK_USB_ADBD_BASH=y
RK_USB_ADBD_TCP_PORT=5555
RK_USE_FIT_IMG=y
RK_WIFIBT_CHIP=ALL_AP
RK_YOCTO_CFG=rockchip-rk3588-evb
RK_YOCTO_CHROMIUM=y
RK_YOCTO_DISPLAY_PLATFORM=wayland
RK_YOCTO_DISPLAY_PLATFORM_WAYLAND=y
RK_YOCTO_USBMOUNT=y

==========================================
          Start building all images
==========================================
Using kernel version(5.10) from environment
Toolchain for kernel:
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-

==========================================
          Start building kernel
==========================================
+ make -C /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/kernel/ -j7 CROSS_COMPILE=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- ARCH=arm64 rockchip_linux_defconfig rk3588_linux.config
make: Entering directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/kernel'
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/confdata.o
  HOSTCC  scripts/kconfig/expr.o
  LEX     scripts/kconfig/lexer.lex.c
  YACC    scripts/kconfig/parser.tab.[ch]
  HOSTCC  scripts/kconfig/preprocess.o
  HOSTCC  scripts/kconfig/symbol.o
  HOSTCC  scripts/kconfig/util.o
  HOSTCC  scripts/kconfig/lexer.lex.o
  HOSTCC  scripts/kconfig/parser.tab.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#

......
  LD [M]  drivers/leds/trigger/ledtrig-camera.ko
  Image:  resource.img (with rk3588-armsom-sige7.dtb logo.bmp logo_kernel.bmp) is ready
  Image:  boot.img (with Image  resource.img) is ready
  Image:  zboot.img (with Image.lz4  resource.img) is ready
make: Leaving directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/kernel'
+ /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/common/scripts/mk-fitimage.sh kernel/boot.img boot.its kernel/arch/arm64/boot/Image
FIT description: U-Boot FIT source file for arm
Created:         Tue Jun 11 22:52:08 2024
 Image 0 (fdt)
  Description:  unavailable
  Created:      Tue Jun 11 22:52:08 2024
  Type:         Flat Device Tree
  Compression:  uncompressed
  Data Size:    276878 Bytes = 270.39 KiB = 0.26 MiB
  Architecture: AArch64
  Load Address: 0xffffff00
  Hash algo:    sha256
  Hash value:   2e1efecb7de8f6d6f6dc99aceac3316169528dbe2343075acbc97c676863a54a
 Image 1 (kernel)
  Description:  unavailable
  Created:      Tue Jun 11 22:52:08 2024
  Type:         Kernel Image
  Compression:  uncompressed
  Data Size:    35650048 Bytes = 34814.50 KiB = 34.00 MiB
  Architecture: AArch64
  OS:           Linux
  Load Address: 0xffffff01
  Entry Point:  0xffffff01
  Hash algo:    sha256
  Hash value:   2de5ee7d2ebdda89a527236a37b485ec9a695366fee730a72d5c887f76026682
 Image 2 (resource)
  Description:  unavailable
  Created:      Tue Jun 11 22:52:08 2024
  Type:         Multi-File Image
  Compression:  uncompressed
  Data Size:    1692160 Bytes = 1652.50 KiB = 1.61 MiB
  Hash algo:    sha256
  Hash value:   16b3aea0b954a45350b6569f67cd6aa082d112a288a4d22331a41b1dee58699d
 Default Configuration: 'conf'
 Configuration 0 (conf)
  Description:  unavailable
  Kernel:       kernel
  FDT:          fdt
Not Found io-domains in kernel/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
==========================================
          Start building rootfs(buildroot)
==========================================
==========================================
          Start building buildroot(2021.11)
==========================================
make: Entering directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot'
  GEN     /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588/Makefile
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/build/parse_defconfig.sh /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/configs/rockchip_rk3588_defconfig /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588/.config.in
Parsing defconfig: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/configs/rockchip_rk3588_defconfig
.......
Log saved on /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/sessions/2024-06-11_22-45-04/br-rockchip_rk3588_2024-06-11_22-52-17.log
Generated images:
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/rootfs/rootfs.cpio
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/rootfs/rootfs.cpio.gz
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/rootfs/rootfs.ext2
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/rootfs/rootfs.ext4
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/rootfs/rootfs.squashfs
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/rootfs/rootfs.tar
you take 7:31.54 to build buildroot
# 2024-06-11 22:53:12
# run hook: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588/target rockchip_rk3588_defconfig"

Running 00-wifibt.sh for /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588/target (buildroot init=busybox)...
Building Wifi/BT module and firmwares...
==========================================
          Start building wifi/BT (ALL_AP)
==========================================
kernel config: CONFIG_USB=y CONFIG_MMC=y CONFIG_RFKILL=y
building bcmdhd sdio
make[1]: Entering directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/kernel'
  CC [M]  /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/external/rkwifibt/drivers/bcmdhd/aiutils.o
  CC [M]  /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/external/rkwifibt/drivers/bcmdhd/siutils.o
  CC [M]  /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/external/rkwifibt/drivers/bcmdhd/sbutils.o
......


sent 1,143,224 bytes  received 71 bytes  2,286,590.00 bytes/sec
total size is 1,143,678  speedup is 1.00
Handling overlay: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/common/overlays/rootfs/frecon)...
Installing overlay: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/common/overlays/rootfs/common-tools to /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588/target...
sending incremental file list
copying unsafe symlink "usr/bin/vendor_storage" -> "../../../../../tools/armhf/vendor_storage"
copying unsafe symlink "usr/bin/modetest" -> "../../../../../tools/armhf/modetest"
copying unsafe symlink "usr/bin/updateEngine" -> "../../../../../tools/armhf/updateEngine"
copying unsafe symlink "usr/bin/update" -> "../../../../../tools/armhf/update"
copying unsafe symlink "usr/bin/io" -> "../../../../../tools/armhf/io"
usr/bin/io
usr/bin/update
usr/bin/updateEngine
usr/bin/vendor_storage

sent 4,384,849 bytes  received 94 bytes  8,769,886.00 bytes/sec
total size is 4,999,800  speedup is 1.14
Running 95-partitions.sh for /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588/target (buildroot init=busybox)...
Preparing extra partitions...
Running 99-owner.sh for /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588/target (buildroot init=busybox)...
Running mk-rootfs.sh - build_buildroot /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/rootfs succeeded.
Running mk-rootfs.sh - build_rootfs succeeded.
==========================================
          Start building recovery(buildroot)
==========================================
make: Entering directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot'
  GEN     /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/Makefile
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/build/parse_defconfig.sh /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/configs/rockchip_rk35
......
2024-06-11T23:00:03 >>>   Generating root filesystems common tables
2024-06-11T23:00:03 >>>   Generating filesystem image rootfs.cpio
2024-06-11T23:00:06 >>>   Generating filesystem image rootfs.ext2
2024-06-11T23:00:06 >>>   Generating filesystem image rootfs.squashfs
2024-06-11T23:00:07 >>>   Generating filesystem image rootfs.tar
Done in 21s
Log saved on /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/sessions/2024-06-11_22-45-04/br-rockchip_rk3588_recovery_2024-06-11_22-59-47.log
Generated images:
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.cpio
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.cpio.gz
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.ext2
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.ext4
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.squashfs
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.tar
you take 0:27.69 to build recovery(buildroot)
Packing /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.cpio.gz to /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/recovery.img
FIT description: U-Boot FIT source file for arm
Created:         Tue Jun 11 23:00:08 2024
 Image 0 (fdt)
  Description:  unavailable
  Created:      Tue Jun 11 23:00:08 2024
  Type:         Flat Device Tree
  Compression:  uncompressed
  Data Size:    276878 Bytes = 270.39 KiB = 0.26 MiB
  Architecture: AArch64
  Load Address: 0xffffff00
  Hash algo:    sha256
  Hash value:   2e1efecb7de8f6d6f6dc99aceac3316169528dbe2343075acbc97c676863a54a
 Image 1 (kernel)
  Description:  unavailable
  Created:      Tue Jun 11 23:00:08 2024
  Type:         Kernel Image
  Compression:  uncompressed
  Data Size:    35650048 Bytes = 34814.50 KiB = 34.00 MiB
  Architecture: AArch64
  OS:           Linux
  Load Address: 0xffffff01
  Entry Point:  0xffffff01
  Hash algo:    sha256
  Hash value:   2de5ee7d2ebdda89a527236a37b485ec9a695366fee730a72d5c887f76026682
 Image 2 (ramdisk)
  Description:  unavailable
  Created:      Tue Jun 11 23:00:08 2024
  Type:         RAMDisk Image
  Compression:  uncompressed
  Data Size:    6673958 Bytes = 6517.54 KiB = 6.36 MiB
  Architecture: AArch64
  OS:           Linux
  Load Address: 0xffffff02
  Entry Point:  unavailable
  Hash algo:    sha256
  Hash value:   61124fb71f146a757ce43bb199e5fa39be4c6adb56ba80251cd3b184c3aca900
 Image 3 (resource)
  Description:  unavailable
  Created:      Tue Jun 11 23:00:08 2024
  Type:         Multi-File Image
  Compression:  uncompressed
  Data Size:    1692160 Bytes = 1652.50 KiB = 1.61 MiB
  Hash algo:    sha256
  Hash value:   16b3aea0b954a45350b6569f67cd6aa082d112a288a4d22331a41b1dee58699d
 Default Configuration: 'conf'
 Configuration 0 (conf)
  Description:  unavailable
  Kernel:       kernel
  Init Ramdisk: ramdisk
  FDT:          fdt
you take 0:00.51 to pack recovery image
Running mk-recovery.sh - build_recovery succeeded.
Toolchain for loader (u-boot):
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-

==========================================
          Start building loader
==========================================
+ cd u-boot
+ ./make.sh CROSS_COMPILE=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- rk3588
## make rk3588_defconfig -j12
#
# configuration written to .config
#
scripts/kconfig/conf  --silentoldconfig Kconfig
  CHK     include/config.h
  CFG     u-boot.cfg
  GEN     include/autoconf.mk.dep
  CFG     spl/u-boot.cfg
  CFG     tpl/u-boot.cfg
  GEN     include/autoconf.mk
......
  CAT     spl/u-boot-spl-dtb.bin
  COPY    spl/u-boot-spl.bin
  CFGCHK  u-boot.cfg
SEC=1
pack u-boot.itb okay! Input: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/rkbin/RKTRUST/RK3588TRUST.ini

FIT description: FIT Image with ATF/OP-TEE/U-Boot/MCU
Created:         Tue Jun 11 23:00:17 2024
 Image 0 (uboot)
  Description:  U-Boot
  Created:      Tue Jun 11 23:00:17 2024
  Type:         Standalone Program
  Compression:  uncompressed
  Data Size:    1317128 Bytes = 1286.26 KiB = 1.26 MiB
  Architecture: AArch64
  Load Address: 0x00200000
  Entry Point:  unavailable
  Hash algo:    sha256
  Hash value:   7fd2ffe37130ca48d6f18001add4039373925d4d0619cc31de411ef3e187f02d
 Image 1 (atf-1)
  Description:  ARM Trusted Firmware
  Created:      Tue Jun 11 23:00:17 2024
  Type:         Firmware
  Compression:  uncompressed
  Data Size:    200008 Bytes = 195.32 KiB = 0.19 MiB
  Architecture: AArch64
  Load Address: 0x00040000
  Hash algo:    sha256
  Hash value:   c902200be1343fe569e54778c286005b1c6163606664c463a24d787be4376966
 Image 2 (atf-2)
  Description:  ARM Trusted Firmware
  Created:      Tue Jun 11 23:00:17 2024
  Type:         Firmware
  Compression:  uncompressed
  Data Size:    24576 Bytes = 24.00 KiB = 0.02 MiB
  Architecture: AArch64
  Load Address: 0x000f0000
  Hash algo:    sha256
  Hash value:   aa71013e72d7ab4be264c1093b155ef06e65d0a263d552be25b13c8ddf285586
 Image 3 (atf-3)
  Description:  ARM Trusted Firmware
  Created:      Tue Jun 11 23:00:17 2024
  Type:         Firmware
  Compression:  uncompressed
  Data Size:    24576 Bytes = 24.00 KiB = 0.02 MiB
  Architecture: AArch64
  Load Address: 0xff100000
  Hash algo:    sha256
  Hash value:   225d6bf0712f850648223365ba06a73ba5f6315fb8a9580f23ab48ece795f91e
 Image 4 (optee)
  Description:  OP-TEE
  Created:      Tue Jun 11 23:00:17 2024
  Type:         Firmware
  Compression:  uncompressed
  Data Size:    465304 Bytes = 454.40 KiB = 0.44 MiB
  Architecture: AArch64
  Load Address: 0x08400000
  Hash algo:    sha256
  Hash value:   66e30bf9e879405a49797aaa6c08ca1c41aa325443e910af42e3df309e65909b
 Image 5 (fdt)
  Description:  U-Boot dtb
  Created:      Tue Jun 11 23:00:17 2024
  Type:         Flat Device Tree
  Compression:  uncompressed
  Data Size:    8141 Bytes = 7.95 KiB = 0.01 MiB
  Architecture: AArch64
  Hash algo:    sha256
  Hash value:   8ecccd16d2f12c4f5639c386e51f206eb679638495283d9297497ddfb0aae01a
 Default Configuration: 'conf'
 Configuration 0 (conf)
  Description:  rk3588-evb
  Kernel:       unavailable
  Firmware:     atf-1
  FDT:          fdt
  Loadables:    uboot
                atf-2
                atf-3
                optee
********boot_merger ver 1.31********
Info:Pack loader ok.
pack loader okay! Input: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/rkbin/RKBOOT/RK3588MINIALL.ini
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/u-boot

Image(no-signed, version=0): uboot.img (FIT with uboot, trust...) is ready
Image(no-signed): rk3588_spl_loader_v1.13.112.bin (with spl, ddr...) is ready
pack uboot.img okay! Input: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/rkbin/RKTRUST/RK3588TRUST.ini

Platform RK3588 is build OK, with new .config(make rk3588_defconfig -j12)
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-
Tue Jun 11 23:00:17 CST 2024
+ cd ..
Running mk-loader.sh - build_loader succeeded.
==========================================
          Start packing firmwares
==========================================
Linking /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware/parameter.txt from /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/.chip/parameter.txt...
Generating blank misc...
Generated blank misc image:
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware/misc.img
Preparing partiton oem
Merging /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/common/images/oem/normal into /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/oem
Packing /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware/oem.img from /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/oem.fs
Using host tools in /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588/host
Making /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware/oem.img from /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/oem (auto sized)
Making /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware/oem.img from /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/oem with size(17048KB)
mke2fs 1.46.5 (30-Dec-2021)
Creating regular file /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware/oem.img
Creating filesystem with 17048 1k blocks and 4272 inodes
Filesystem UUID: b3ce6911-8296-4559-b1bc-df021c5476d0
Superblock backups stored on blocks:
        8193

Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Copying files into the device: done
Writing superblocks and filesystem accounting information: done

tune2fs 1.46.5 (30-Dec-2021)
Setting maximal mount count to -1
Setting interval between checks to 0 seconds
Done packing /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware/oem.img
Preparing partiton userdata
Merging /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/common/images/userdata/normal into /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/userdata
Packing /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware/userdata.img from /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/userdata.fs
Using host tools in /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588/host
Making /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware/userdata.img from /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/userdata (auto sized)
Making /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware/userdata.img from /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/userdata with size(4368KB)
mke2fs 1.46.5 (30-Dec-2021)
Creating regular file /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware/userdata.img
Creating filesystem with 4368 1k blocks and 1088 inodes

Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Copying files into the device: done
Writing superblocks and filesystem accounting information: done

tune2fs 1.46.5 (30-Dec-2021)
Setting maximal mount count to -1
Setting interval between checks to 0 seconds
Done packing /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware/userdata.img
Packed files:
MiniLoaderAll.bin(/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/u-boot/rk3588_spl_loader_v1.13.112.bin): 461K
boot.img(/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/kernel/boot.img): 36M
misc.img: 48K
oem.img: 17M
parameter.txt(/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/.chips/rk3588/parameter.txt): 539
recovery.img(/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/images/recovery.img): 43M
rootfs.img(/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588/images/rootfs.ext2): 728M
uboot.img(/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/u-boot/uboot.img): 4.0M
userdata.img: 4.3M
Images in /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/firmware are ready!
Running mk-firmware.sh - build_firmware succeeded.
==========================================
          Start packing  update image
==========================================
Generating package-file for update:
# NAME  PATH
package-file    package-file
parameter       parameter.txt
bootloader      MiniLoaderAll.bin
uboot   uboot.img
misc    misc.img
boot    boot.img
recovery        recovery.img
backup  RESERVED
rootfs  rootfs.img
oem     oem.img
userdata        userdata.img
Packing /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/rockdev/update.img for update...
Android Firmware Package Tool v2.2
------ PACKAGE ------
Add file: ./package-file
package-file,Add file: ./package-file done,offset=0x800,size=0xe1,userspace=0x1
Add file: ./parameter.txt
parameter,Add file: ./parameter.txt done,offset=0x1000,size=0x227,userspace=0x1,flash_address=0x00000000
Add file: ./MiniLoaderAll.bin
bootloader,Add file: ./MiniLoaderAll.bin done,offset=0x1800,size=0x731c0,userspace=0xe7
Add file: ./uboot.img
uboot,Add file: ./uboot.img done,offset=0x75000,size=0x400000,userspace=0x800,flash_address=0x00004000
Add file: ./misc.img
misc,Add file: ./misc.img done,offset=0x475000,size=0xc000,userspace=0x18,flash_address=0x00006000
Add file: ./boot.img
boot,Add file: ./boot.img done,offset=0x481000,size=0x23e1200,userspace=0x47c3,flash_address=0x00008000
Add file: ./recovery.img
recovery,Add file: ./recovery.img done,offset=0x2862800,size=0x2a3ea00,userspace=0x547e,flash_address=0x00028000
Add file: ./rootfs.img
rootfs,Add file: ./rootfs.img done,offset=0x52a1800,size=0x2d800000,userspace=0x5b000,flash_address=0x00078000
Add file: ./oem.img
oem,Add file: ./oem.img done,offset=0x32aa1800,size=0x10a6000,userspace=0x214c,flash_address=0x01c78000
Add file: ./userdata.img
userdata,Add file: ./userdata.img done,offset=0x33b47800,size=0x444000,userspace=0x888,flash_address=0x01cb8000
Add CRC...
Make firmware OK!
------ OK ------
********rkImageMaker ver 2.23********
Generating new image, please wait...
Writing head info...
Writing boot file...
Writing firmware...
Generating MD5 data...
MD5 data generated successfully!
New image generated successfully!
Running mk-updateimg.sh - build_updateimg succeeded.
Running 99-all.sh - build_all succeeded.

从输出日志可以看出编译顺序,我们接下来依次介绍。

3.4.1 编译kernel

通过mk-fitimage.sh脚本生成boot.img位于kernel目录下;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll kernel/boot.img
-rw-r--r-- 1 root root 37622272  6月 11 22:52 kernel/boot.img
3.4.2 编译rootfs

编译输出根文件系统rootfs.ext4位于output/rootfs目录下;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll output/rootfs
lrwxrwxrwx 1 root root 42  6月 11 22:52 output/rootfs -> ../buildroot/output/rockchip_rk3588/images/
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll output/rootfs/
-rw-r--r-- 1 root root 615713280  6月 11 22:58 rootfs.cpio
-rw-r--r-- 1 root root 273882955  6月 11 22:59 rootfs.cpio.gz
-rw-r--r-- 1 root root 763363328  6月 11 22:59 rootfs.ext2
lrwxrwxrwx 1 root root        11  6月 11 22:59 rootfs.ext4 -> rootfs.ext2
-rw-r--r-- 1 root root 275013632  6月 11 22:59 rootfs.squashfs
-rw-r--r-- 1 root root 624517120  6月 11 22:59 rootfs.tar

系统默认是Buildroot,可以通过设置坏境变量RK_ROOTFS_SYSTEM指定不同rootfsRK_ROOTFS_SYSTEM目前可设定三种系统:buildrootdebianyocto

比如需要debain可以通过以下命令进行生成:

RK_ROOTFS_SYSTEM=debian ./build.sh all
3.4.3 编译wifi/BT模块

编译wifi/BT模块,并打包到根文件系统。

3.4.4 编译recovery

通过mk-recovery.sh脚本编译完成输出recovery.img,位于output/recovery目录下;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll output/recovery
lrwxrwxrwx 1 root root 51  6月 11 22:59 output/recovery -> ../buildroot/output/rockchip_rk3588_recovery/images/
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll output/recovery/
-rw-r--r-- 1 root root 44296704  6月 11 23:00 recovery.img
-rw-r--r-- 1 root root 15763968  6月 11 23:00 rootfs.cpio
-rw-r--r-- 1 root root  6673958  6月 11 23:00 rootfs.cpio.gz
-rw-r--r-- 1 root root 43187200  6月 11 23:00 rootfs.ext2
lrwxrwxrwx 1 root root       11  6月 11 23:00 rootfs.ext4 -> rootfs.ext2
-rw-r--r-- 1 root root  6635520  6月 11 23:00 rootfs.squashfs
-rw-r--r-- 1 root root 16844800  6月 11 23:00 rootfs.tar

注意:recovery.img是由kernel+dtb+ramdisk组成的根文件系统,主要用于升级操作。

3.4.5 编译u-boot

通过mk-loader.sh脚本编译loader,编译完成生成uboot.imgrk3588_spl_loader_v1.13.112.bin位于u-boot目录下;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll u-boot/uboot.img
-rw-r--r-- 1 root root 4194304  6月 11 23:00 u-boot/uboot.img
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll u-boot/rk3588_spl_loader_v1.13.112.bin
-rw-r--r-- 1 root root 471488  6月 11 23:00 u-boot/rk3588_spl_loader_v1.13.112.bin
3.4.6 打包分区镜像

通过mk-firmware.sh 脚本生成存放各个分区镜像的目录,位于output/firmware/目录下;

  • 创建 parameter.txt链接文件,指向device/rockchip/.chips/rk3588/parameter.txt
  • 创建misc 分区镜像文件: misc.img
  • 创建oem分区镜像文件: oem.img
  • 创建userdata分区镜像文件: userdata.img
  • 创建MiniLoaderAll.bin链接文件,指向u-boot/rk3588_spl_loader_v1.13.112.bin
  • 创建uboot.img链接文件,指向u-boot/uboot.img
  • 创建boot.img链接文件,指向kernel/boot.img
  • 创建recovery.img链接文件,指向buildroot/output/rockchip_rk3588_recovery/images/recovery.img
  • 创建rootfs.img链接文件,指向buildroot/output/rockchip_rk3588/images/rootfs.img

查看目录:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll output/firmware/
lrwxrwxrwx 1 root root       21  6月 11 22:52 boot.img -> ../../kernel/boot.img
lrwxrwxrwx 1 root root       44  6月 11 23:00 MiniLoaderAll.bin -> ../../u-boot/rk3588_spl_loader_v1.13.112.bin
-rw-r--r-- 1 root root    49152  6月 11 23:00 misc.img
-rw-r--r-- 1 root root 17457152  6月 11 23:00 oem.img
lrwxrwxrwx 1 root root       49  6月 11 23:00 parameter.txt -> ../../device/rockchip/.chips/rk3588/parameter.txt
lrwxrwxrwx 1 root root       67  6月 11 23:00 recovery.img -> ../../buildroot/output/rockchip_rk3588_recovery/images/recovery.img
lrwxrwxrwx 1 root root       57  6月 11 22:59 rootfs.img -> ../../buildroot/output/rockchip_rk3588/images/rootfs.ext2
lrwxrwxrwx 1 root root       22  6月 11 23:00 uboot.img -> ../../u-boot/uboot.img
lrwxrwxrwx 1 root root       26  6月 11 23:00 update.img -> ../update/Image/update.img
-rw-r--r-- 1 root root  4472832  6月 11 23:00 userdata.img

此外,我们在rockdev 目录下也可看到这些分区镜像;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll rockdev/
lrwxrwxrwx 1 root root       21  6月 11 22:52 boot.img -> ../../kernel/boot.img

lrwxrwxrwx 1 root root       44  6月 11 23:00 MiniLoaderAll.bin -> ../../u-boot/rk3588_spl_loader_v1.13.112.bin
-rw-r--r-- 1 root root    49152  6月 11 23:00 misc.img
-rw-r--r-- 1 root root 17457152  6月 11 23:00 oem.img
lrwxrwxrwx 1 root root       49  6月 11 23:00 parameter.txt -> ../../device/rockchip/.chips/rk3588/parameter.txt
lrwxrwxrwx 1 root root       67  6月 11 23:00 recovery.img -> ../../buildroot/output/rockchip_rk3588_recovery/images/recovery.img
lrwxrwxrwx 1 root root       57  6月 11 22:59 rootfs.img -> ../../buildroot/output/rockchip_rk3588/images/rootfs.ext2
lrwxrwxrwx 1 root root       22  6月 11 23:00 uboot.img -> ../../u-boot/uboot.img
lrwxrwxrwx 1 root root       26  6月 11 23:00 update.img -> ../update/Image/update.img
-rw-r--r-- 1 root root  4472832  6月 11 23:00 userdata.img
3.4.7 打包统一固件

打包各个分区镜像生成update.img

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll output/update/
drwxr-xr-x 2 root root 4096  6月 11 23:00 Image/
lrwxrwxrwx 1 root root   18  6月 11 23:00 package-file -> Image/package-file
lrwxrwxrwx 1 root root   16  6月 11 23:00 update.img -> Image/update.img

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll output/update/Image/
lrwxrwxrwx 1 root root        24  6月 11 23:00 boot.img -> ../../../kernel/boot.img
lrwxrwxrwx 1 root root        47  6月 11 23:00 MiniLoaderAll.bin -> ../../../u-boot/rk3588_spl_loader_v1.13.112.bin
lrwxrwxrwx 1 root root        23  6月 11 23:00 misc.img -> ../../firmware/misc.img
lrwxrwxrwx 1 root root        22  6月 11 23:00 oem.img -> ../../firmware/oem.img
-rw-r--r-- 1 root root       225  6月 11 23:00 package-file
lrwxrwxrwx 1 root root        52  6月 11 23:00 parameter.txt -> ../../../device/rockchip/.chips/rk3588/parameter.txt
lrwxrwxrwx 1 root root        70  6月 11 23:00 recovery.img -> ../../../buildroot/output/rockchip_rk3588_recovery/images/recovery.img
lrwxrwxrwx 1 root root        60  6月 11 23:00 rootfs.img -> ../../../buildroot/output/rockchip_rk3588/images/rootfs.ext2
lrwxrwxrwx 1 root root        25  6月 11 23:00 uboot.img -> ../../../u-boot/uboot.img
-rw-r--r-- 1 root root 872409674  6月 11 23:00 update.img
-rw-r--r-- 1 root root 871938052  6月 11 23:00 update.raw.img
lrwxrwxrwx 1 root root        27  6月 11 23:00 userdata.img -> ../../firmware/userdata.img
3.4.8 清理磁盘

因此我们将根文件系统移动到/work/tftproot文件;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ cp buildroot/output/rockchip_rk3588/images/rootfs.ext2 /work/tftpboot/

该次编译会占用大量磁盘空间(我这里占用了40G+),导致剩余磁盘空间不充足,因此必要时候可以删除buildroot/output目录。

3.5 模块编译
3.5.1 U-Boot编译

编译命令如下:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# ./build.sh uboot

输出详情如下:

点击查看代码
Log saved at /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/sessions/2024-06-16_19-21-59


==========================================
          Final configs
==========================================
RK_BOOT_FIT_ITS=boot.its
RK_BOOT_IMG=boot.img
RK_BUILDROOT_CFG=rockchip_rk3588
RK_CHIP=rk3588
RK_CHIP_FAMILY=rk3588
RK_DEBIAN_ARCH=arm64
......
Toolchain for loader (u-boot):
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-

==========================================
          Start building uboot
==========================================
+ cd u-boot
+ ./make.sh CROSS_COMPILE=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- rk3588
## make rk3588_defconfig -j12
#
# configuration written to .config
#
scripts/kconfig/conf  --silentoldconfig Kconfig
  CHK     include/config.h
  CFG     u-boot.cfg
......
  CAT     spl/u-boot-spl-dtb.bin
  COPY    spl/u-boot-spl.bin
  CFGCHK  u-boot.cfg
SEC=1
pack u-boot.itb okay! Input: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/rkbin/RKTRUST/RK3588TRUST.ini

FIT description: FIT Image with ATF/OP-TEE/U-Boot/MCU
Created:         Sun Jun 16 19:23:11 2024
 Image 0 (uboot)
  Description:  U-Boot
  Created:      Sun Jun 16 19:23:11 2024
  Type:         Standalone Program
  Compression:  uncompressed
  Data Size:    1317128 Bytes = 1286.26 KiB = 1.26 MiB
  Architecture: AArch64
  Load Address: 0x00200000
  Entry Point:  unavailable
  Hash algo:    sha256
  Hash value:   de3ce33f68a9408cbcdfd582c4455ea803ca5fbc5a4c96d07f7a519c4d110340
 Image 1 (atf-1)
  Description:  ARM Trusted Firmware
  Created:      Sun Jun 16 19:23:11 2024
  Type:         Firmware
  Compression:  uncompressed
  Data Size:    200008 Bytes = 195.32 KiB = 0.19 MiB
  Architecture: AArch64
  Load Address: 0x00040000
  Hash algo:    sha256
  Hash value:   c902200be1343fe569e54778c286005b1c6163606664c463a24d787be4376966
 Image 2 (atf-2)
  Description:  ARM Trusted Firmware
  Created:      Sun Jun 16 19:23:11 2024
  Type:         Firmware
  Compression:  uncompressed
  Data Size:    24576 Bytes = 24.00 KiB = 0.02 MiB
  Architecture: AArch64
  Load Address: 0x000f0000
  Hash algo:    sha256
  Hash value:   aa71013e72d7ab4be264c1093b155ef06e65d0a263d552be25b13c8ddf285586
 Image 3 (atf-3)
  Description:  ARM Trusted Firmware
  Created:      Sun Jun 16 19:23:11 2024
  Type:         Firmware
  Compression:  uncompressed
  Data Size:    24576 Bytes = 24.00 KiB = 0.02 MiB
  Architecture: AArch64
  Load Address: 0xff100000
  Hash algo:    sha256
  Hash value:   225d6bf0712f850648223365ba06a73ba5f6315fb8a9580f23ab48ece795f91e
 Image 4 (optee)
  Description:  OP-TEE
  Created:      Sun Jun 16 19:23:11 2024
  Type:         Firmware
  Compression:  uncompressed
  Data Size:    465304 Bytes = 454.40 KiB = 0.44 MiB
  Architecture: AArch64
  Load Address: 0x08400000
  Hash algo:    sha256
  Hash value:   66e30bf9e879405a49797aaa6c08ca1c41aa325443e910af42e3df309e65909b
 Image 5 (fdt)
  Description:  U-Boot dtb
  Created:      Sun Jun 16 19:23:11 2024
  Type:         Flat Device Tree
  Compression:  uncompressed
  Data Size:    8141 Bytes = 7.95 KiB = 0.01 MiB
  Architecture: AArch64
  Hash algo:    sha256
  Hash value:   8ecccd16d2f12c4f5639c386e51f206eb679638495283d9297497ddfb0aae01a
 Default Configuration: 'conf'
 Configuration 0 (conf)
  Description:  rk3588-evb
  Kernel:       unavailable
  Firmware:     atf-1
  FDT:          fdt
  Loadables:    uboot
                atf-2
                atf-3
                optee
********boot_merger ver 1.31********
Info:Pack loader ok.
pack loader okay! Input: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/rkbin/RKBOOT/RK3588MINIALL.ini
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/u-boot

Image(no-signed, version=0): uboot.img (FIT with uboot, trust...) is ready
Image(no-signed): rk3588_spl_loader_v1.13.112.bin (with spl, ddr...) is ready
pack uboot.img okay! Input: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/rkbin/RKTRUST/RK3588TRUST.ini

Platform RK3588 is build OK, with new .config(make rk3588_defconfig -j12)
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-
Sun Jun 16 19:23:11 CST 2024
+ cd ..
Running 70-loader.sh - build_uboot succeeded.

编译生成uboot.imgMiniLoaderAll.bin,同时更新rockdev目录下uboot.imgMiniLoaderAll.bin

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll u-boot/uboot.img
-rw-r--r-- 1 root root 4194304  6月 16 19:23 u-boot/uboot.img
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$  ll u-boot/rk3588_spl_loader_v1.13.112.bin
-rw-r--r-- 1 root root 471488  6月 16 19:23 u-boot/rk3588_spl_loader_v1.13.112.bin

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll rockdev/
lrwxrwxrwx 1 root root       21  6月 11 22:52 boot.img -> ../../kernel/boot.img
lrwxrwxrwx 1 root root       44  6月 16 19:23 MiniLoaderAll.bin -> ../../u-boot/rk3588_spl_loader_v1.13.112.bin
-rw-r--r-- 1 root root    49152  6月 11 23:00 misc.img
-rw-r--r-- 1 root root 17457152  6月 11 23:00 oem.img
lrwxrwxrwx 1 root root       49  6月 11 23:00 parameter.txt -> ../../device/rockchip/.chips/rk3588/parameter.txt
lrwxrwxrwx 1 root root       67  6月 11 23:00 recovery.img -> ../../buildroot/output/rockchip_rk3588_recovery/images/recovery.img
lrwxrwxrwx 1 root root       57  6月 11 22:59 rootfs.img -> ../../buildroot/output/rockchip_rk3588/images/rootfs.ext2
lrwxrwxrwx 1 root root       22  6月 16 19:23 uboot.img -> ../../u-boot/uboot.img
lrwxrwxrwx 1 root root       26  6月 11 23:00 update.img -> ../update/Image/update.img
-rw-r--r-- 1 root root  4472832  6月 11 23:00 userdata.img
3.5.2 Kernel编译

编译命令如下:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp#./build.sh kernel

输出详情如下:

点击查看代码
Log saved at /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/sessions/2024-06-16_19-27-50


==========================================
          Final configs
==========================================
RK_BOOT_FIT_ITS=boot.its
RK_BOOT_IMG=boot.img
RK_BUILDROOT_CFG=rockchip_rk3588
RK_CHIP=rk3588
RK_CHIP_FAMILY=rk3588
RK_DEBIAN_ARCH=arm64
RK_DEBIAN_ARM64=y
......
==========================================
          Start building kernel
==========================================
+ make -C /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/kernel/ -j7 CROSS_COMPILE=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- ARCH=arm64 rockchip_linux_defconfig rk3588_linux.config
make: Entering directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/kernel'
#
# No change to .config
#
Using .config as base
Merging ./arch/arm64/configs/rk3588_linux.config
#
# merged configuration written to .config (needs make)
#
#
# configuration written to .config
#
make: Leaving directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/kernel'
+ make -C /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/kernel/ -j7 CROSS_COMPILE=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- ARCH=arm64 rk3588-armsom-sige7.img
......
  Image:  zboot.img (with Image.lz4  resource.img) is ready
make: Leaving directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/kernel'
+ /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/common/scripts/mk-fitimage.sh kernel/boot.img boot.its kernel/arch/arm64/boot/Image
FIT description: U-Boot FIT source file for arm
Created:         Sun Jun 16 19:28:28 2024
 Image 0 (fdt)
  Description:  unavailable
  Created:      Sun Jun 16 19:28:28 2024
  Type:         Flat Device Tree
  Compression:  uncompressed
  Data Size:    276878 Bytes = 270.39 KiB = 0.26 MiB
  Architecture: AArch64
  Load Address: 0xffffff00
  Hash algo:    sha256
  Hash value:   2e1efecb7de8f6d6f6dc99aceac3316169528dbe2343075acbc97c676863a54a
 Image 1 (kernel)
  Description:  unavailable
  Created:      Sun Jun 16 19:28:28 2024
  Type:         Kernel Image
  Compression:  uncompressed
  Data Size:    35650048 Bytes = 34814.50 KiB = 34.00 MiB
  Architecture: AArch64
  OS:           Linux
  Load Address: 0xffffff01
  Entry Point:  0xffffff01
  Hash algo:    sha256
  Hash value:   75156ece8874de3e407e006dc1cc4b471fccbb3d192a7f57b9aeb85419d34445
 Image 2 (resource)
  Description:  unavailable
  Created:      Sun Jun 16 19:28:28 2024
  Type:         Multi-File Image
  Compression:  uncompressed
  Data Size:    1692160 Bytes = 1652.50 KiB = 1.61 MiB
  Hash algo:    sha256
  Hash value:   35f3f91ac5fc2bbcfc9e9922ead7f9df34d9a5b31be32cb144a9366852fc514c
 Default Configuration: 'conf'
 Configuration 0 (conf)
  Description:  unavailable
  Kernel:       kernel
  FDT:          fdt
Not Found io-domains in kernel/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
Running 10-kernel.sh - build_kernel succeeded.

编译生成boot.img,同时更新rockdev目录下boot.img

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll kernel/boot.img
-rw-r--r-- 1 root root 37622272  6月 16 19:28 kernel/boot.img

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll rockdev/
lrwxrwxrwx 1 root root       21  6月 16 19:28 boot.img -> ../../kernel/boot.img
lrwxrwxrwx 1 root root       44  6月 16 19:23 MiniLoaderAll.bin -> ../../u-boot/rk3588_spl_loader_v1.13.112.bin
-rw-r--r-- 1 root root    49152  6月 11 23:00 misc.img
-rw-r--r-- 1 root root 17457152  6月 11 23:00 oem.img
lrwxrwxrwx 1 root root       49  6月 11 23:00 parameter.txt -> ../../device/rockchip/.chips/rk3588/parameter.txt
lrwxrwxrwx 1 root root       67  6月 11 23:00 recovery.img -> ../../buildroot/output/rockchip_rk3588_recovery/images/recovery.img
lrwxrwxrwx 1 root root       57  6月 11 22:59 rootfs.img -> ../../buildroot/output/rockchip_rk3588/images/rootfs.ext2
lrwxrwxrwx 1 root root       22  6月 16 19:23 uboot.img -> ../../u-boot/uboot.img
lrwxrwxrwx 1 root root       26  6月 11 23:00 update.img -> ../update/Image/update.img
-rw-r--r-- 1 root root  4472832  6月 11 23:00 userdata.img
3.5.3 Recovery编译

编译命令如下:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp#./build.sh recovery

输出详情如下:

点击查看代码
Log saved at /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/sessions/2024-06-16_19-45-21


==========================================
          Final configs
==========================================
RK_BOOT_FIT_ITS=boot.its
RK_BOOT_IMG=boot.img
RK_BUILDROOT_CFG=rockchip_rk3588
RK_CHIP=rk3588
RK_CHIP_FAMILY=rk3588
RK_DEBIAN_ARCH=arm64
RK_DEBIAN_ARM64=y
......
RK_YOCTO_USBMOUNT=y

==========================================
          Start building recovery(buildroot)
==========================================
make: Entering directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot'
  GEN     /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/Makefile
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/build/parse_defconfig.sh /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/configs/rockchip_rk3588_recovery_defconfig /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/.config.in
Parsing defconfig: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/configs/rockchip_rk3588_recovery_defconfig
Using configs/rockchip/base/kernel.config as base
Merging configs/rockchip/fs/e2fs.config
Merging configs/rockchip/base/common.config
Merging configs/rockchip/base/base.config
Merging configs/rockchip/base/kernel.config
Merging configs/rockchip/fs/e2fs.config
Merging configs/rockchip/base/common.config
Merging configs/rockchip/fs/vfat.config
Merging configs/rockchip/base/recovery.config
Merging configs/rockchip/chips/rk3588.config
Value of BR2_ROOTFS_OVERLAY is redefined by configs/rockchip/chips/rk3588.config:
Previous value: BR2_ROOTFS_OVERLAY="board/rockchip/common/base"
Modify value:   BR2_ROOTFS_OVERLAY+="board/rockchip/rk3588/fs-overlay/"
New value:      BR2_ROOTFS_OVERLAY="board/rockchip/common/base board/rockchip/rk3588/fs-overlay/"

Merging configs/rockchip/chips/rk3588_aarch64.config
Merging /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/configs/rockchip_rk3588_recovery_defconfig
#
# merged configuration written to /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/.config.in (needs make)
#
BR2_DEFCONFIG='' KCONFIG_AUTOCONFIG=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/buildroot-config/auto.conf KCONFIG_AUTOHEADER=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/buildroot-config/autoconf.h KCONFIG_TRISTATE=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/buildroot-config/tristate.config BR2_CONFIG=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/.config HOST_GCC_VERSION="9" BASE_DIR=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery SKIP_LEGACY= CUSTOM_KERNEL_VERSION="5.10" BR2_DEFCONFIG=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/configs/rockchip_rk3588_recovery_defconfig /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/build/buildroot-config/conf --defconfig=/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/.config.in Config.in
#
# configuration written to /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery/.config
#
make: Leaving directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot'
3c3
< # Buildroot -g28f720bc5-dirty Configuration
---
> # Buildroot -g2d3236bd2-dirty Configuration

Buildroot config changed!
You might need to clean it before building:
rm -rf /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/buildroot/output/rockchip_rk3588_recovery


2024-06-16T19:45:36 >>>   Finalizing host directory
2024-06-16T19:45:36 >>>   Finalizing target directory
2024-06-16T19:45:38 >>>   Sanitizing RPATH in target tree
2024-06-16T19:45:39 >>>   Sanity check in overlay board/rockchip/common/base
2024-06-16T19:45:39 >>>   Sanity check in overlay board/rockchip/rk3588/fs-overlay/
2024-06-16T19:45:39 >>>   Copying overlay board/rockchip/common/base
2024-06-16T19:45:39 >>>   Copying overlay board/rockchip/rk3588/fs-overlay/
2024-06-16T19:45:40 >>>   Executing post-build script board/rockchip/common/post-build.sh
2024-06-16T19:45:41 >>>   Generating root filesystems common tables
2024-06-16T19:45:41 >>>   Generating filesystem image rootfs.cpio
2024-06-16T19:45:44 >>>   Generating filesystem image rootfs.ext2
2024-06-16T19:45:45 >>>   Generating filesystem image rootfs.squashfs
2024-06-16T19:45:45 >>>   Generating filesystem image rootfs.tar
Done in 20s
Log saved on /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/sessions/2024-06-16_19-45-21/br-rockchip_rk3588_recovery_2024-06-16_19-45-26.log
Generated images:
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.cpio
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.cpio.gz
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.ext2
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.ext4
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.squashfs
/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.tar
you take 0:23.86 to build recovery(buildroot)
Packing /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/rootfs.cpio.gz to /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/recovery/recovery.img
FIT description: U-Boot FIT source file for arm
Created:         Sun Jun 16 19:45:46 2024
 Image 0 (fdt)
  Description:  unavailable
  Created:      Sun Jun 16 19:45:46 2024
  Type:         Flat Device Tree
  Compression:  uncompressed
  Data Size:    276878 Bytes = 270.39 KiB = 0.26 MiB
  Architecture: AArch64
  Load Address: 0xffffff00
  Hash algo:    sha256
  Hash value:   2e1efecb7de8f6d6f6dc99aceac3316169528dbe2343075acbc97c676863a54a
 Image 1 (kernel)
  Description:  unavailable
  Created:      Sun Jun 16 19:45:46 2024
  Type:         Kernel Image
  Compression:  uncompressed
  Data Size:    35650048 Bytes = 34814.50 KiB = 34.00 MiB
  Architecture: AArch64
  OS:           Linux
  Load Address: 0xffffff01
  Entry Point:  0xffffff01
  Hash algo:    sha256
  Hash value:   75156ece8874de3e407e006dc1cc4b471fccbb3d192a7f57b9aeb85419d34445
 Image 2 (ramdisk)
  Description:  unavailable
  Created:      Sun Jun 16 19:45:46 2024
  Type:         RAMDisk Image
  Compression:  uncompressed
  Data Size:    6673191 Bytes = 6516.79 KiB = 6.36 MiB
  Architecture: AArch64
  OS:           Linux
  Load Address: 0xffffff02
  Entry Point:  unavailable
  Hash algo:    sha256
  Hash value:   efbbfccf3445edd16363ee75449e13cabf19c48910354004f788878afb628d25
 Image 3 (resource)
  Description:  unavailable
  Created:      Sun Jun 16 19:45:46 2024
  Type:         Multi-File Image
  Compression:  uncompressed
  Data Size:    1692160 Bytes = 1652.50 KiB = 1.61 MiB
  Hash algo:    sha256
  Hash value:   35f3f91ac5fc2bbcfc9e9922ead7f9df34d9a5b31be32cb144a9366852fc514c
 Default Configuration: 'conf'
 Configuration 0 (conf)
  Description:  unavailable
  Kernel:       kernel
  Init Ramdisk: ramdisk
  FDT:          fdt
you take 0:00.60 to pack recovery image
Running 40-recovery.sh - build_recovery succeeded.

编译后在buildroot/output/rockchip_rk3588_recovery/images/生成recovery.img,同时更新rockdev目录下recovery.img

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll buildroot/output/rockchip_rk3588_recovery/images/
-rw-r--r-- 1 root root 44295680  6月 16 19:45 recovery.img
-rw-r--r-- 1 root root 15763968  6月 16 19:45 rootfs.cpio
-rw-r--r-- 1 root root  6673191  6月 16 19:45 rootfs.cpio.gz
-rw-r--r-- 1 root root 43187200  6月 16 19:45 rootfs.ext2
lrwxrwxrwx 1 root root       11  6月 16 19:45 rootfs.ext4 -> rootfs.ext2
-rw-r--r-- 1 root root  6635520  6月 16 19:45 rootfs.squashfs
-rw-r--r-- 1 root root 16844800  6月 16 19:45 rootfs.tar

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll rockdev/
lrwxrwxrwx 1 root root       21  6月 16 19:28 boot.img -> ../../kernel/boot.img
lrwxrwxrwx 1 root root       44  6月 16 19:23 MiniLoaderAll.bin -> ../../u-boot/rk3588_spl_loader_v1.13.112.bin
-rw-r--r-- 1 root root    49152  6月 11 23:00 misc.img
-rw-r--r-- 1 root root 17457152  6月 11 23:00 oem.img
lrwxrwxrwx 1 root root       49  6月 11 23:00 parameter.txt -> ../../device/rockchip/.chips/rk3588/parameter.txt
lrwxrwxrwx 1 root root       67  6月 16 19:45 recovery.img -> ../../buildroot/output/rockchip_rk3588_recovery/images/recovery.img
lrwxrwxrwx 1 root root       57  6月 11 22:59 rootfs.img -> ../../buildroot/output/rockchip_rk3588/images/rootfs.ext2
lrwxrwxrwx 1 root root       22  6月 16 19:23 uboot.img -> ../../u-boot/uboot.img
lrwxrwxrwx 1 root root       26  6月 11 23:00 update.img -> ../update/Image/update.img
-rw-r--r-- 1 root root  4472832  6月 11 23:00 userdata.img

注意:recovery.img是由kernel+dtb+ramdisk组成的根文件系统,主要用于升级操作。因此所以每次kernel更改,recovery.img是需要重新打包生成。

recovery重新打包的方法如下:

source buildroot/envsetup.sh
cd buildroot
make recovery-reconfigure
cd -
./build.sh recovery

注意:recovery是非必需的功能。

3.5.4 Buildroot编译

执行以下命令自动完成Buildroot的编译及打包:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# ./build.sh buildroot

编译后在buildroot/output/rockchip_rk3588/images下生成不同格式的镜像, 默认使用rootfs.ext4格式。

由于全自动编译默认系统就是Buildroot,这里我就不重新编译了;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll buildroot/output/rockchip_rk3588/images/
-rw-r--r-- 1 root root 615713280  6月 11 22:58 rootfs.cpio
-rw-r--r-- 1 root root 273882955  6月 11 22:59 rootfs.cpio.gz
-rw-r--r-- 1 root root 763363328  6月 11 22:59 rootfs.ext2
lrwxrwxrwx 1 root root        11  6月 11 22:59 rootfs.ext4 -> rootfs.ext2
-rw-r--r-- 1 root root 275013632  6月 11 22:59 rootfs.squashfs
-rw-r--r-- 1 root root 624517120  6月 11 22:59 rootfs.tar

其中:rockdev/目录下的rootfs.img指向了buildroot/output/rockchip_rk3588/images/rootfs.ext2

3.5.5 Debian编译

需要预先安装以下相关依赖包:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# cd debian
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# sudo apt install binfmt-support qemu-user-static live-build
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# sudo dpkg -i ubuntu-build-service/packages/*
root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# sudo apt install -f

执行以下命令自动完成Debian的编译及打包:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# ./build.sh debian

输出详情如下:

点击查看代码
Log saved at /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/sessions/2024-06-16_19-48-51

WARN: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/defconfig not exists
Pick a defconfig:

1. rockchip_defconfig
2. rockchip_rk3588_evb1_lp4_v10_defconfig
3. rockchip_rk3588_evb7_v11_defconfig
4. rockchip_rk3588_sige7_defconfig
5. rockchip_rk3588s_evb1_lp4x_v10_defconfig
Which would you like? [1]: 4
Switching to defconfig: /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/.chip/rockchip_rk3588_sige7_defconfig
make: Entering directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/common'
......
make: Leaving directory '/work/sambashare/rk3588/armsom/armsom-rk3588-bsp/device/rockchip/common'
Using rootfs system(debian) from cmdline


==========================================
          Final configs
==========================================
RK_BOOT_FIT_ITS=boot.its
RK_BOOT_IMG=boot.img
RK_BUILDROOT_CFG=rockchip_rk3588
RK_CHIP=rk3588
RK_CHIP_FAMILY=rk3588
RK_DEBIAN_ARCH=arm64
RK_DEBIAN_ARM64=y
RK_DEBIAN_VERSION=bullseye
......

==========================================
          Start building rootfs(debian)
==========================================
==========================================
          Start building bullseye(arm64)
==========================================
 Staring Download......
sudo lb clean --purge
[2024-06-16 19:49:07] lb clean --purge
P: Cleaning chroot
rm -f linaro-bullseye-alip-*
rm -rf config
I: create configuration
.......

Fixing up owner for /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/debian/binary...
Fixing up /home/armsom for uid=1000(armsom)...
Running build.sh - post-rootfs succeeded.
mke2fs 1.46.5 (30-Dec-2021)
Creating regular file linaro-rootfs.img
Creating filesystem with 808960 4k blocks and 202400 inodes
Filesystem UUID: c93a2c93-553d-44d8-aa57-dddb8c8a33e8
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912

Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Copying files into the device: done
Writing superblocks and filesystem accounting information: done

Rootfs Image: linaro-rootfs.img
Running 30-rootfs.sh - build_debian /work/sambashare/rk3588/armsom/armsom-rk3588-bsp/output/rootfs succeeded.
Running 30-rootfs.sh - build_rootfs debian succeeded.

该次编译会重新编译内核和根文件系统。耐心等待1个小时,与buildroot编译类似,编译完成我们在rockdev 目录下可以看到各个分区镜像;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll rockdev/
lrwxrwxrwx 1 root root       21  6月 16 19:28 boot.img -> ../../kernel/boot.img
lrwxrwxrwx 1 root root       44  6月 16 19:35 MiniLoaderAll.bin -> ../../u-boot/rk3588_spl_loader_v1.13.112.bin
-rw-r--r-- 1 root root    49152  6月 11 23:00 misc.img
-rw-r--r-- 1 root root 17457152  6月 11 23:00 oem.img
lrwxrwxrwx 1 root root       49  6月 11 23:00 parameter.txt -> ../../device/rockchip/.chips/rk3588/parameter.txt
lrwxrwxrwx 1 root root       67  6月 16 19:45 recovery.img -> ../../buildroot/output/rockchip_rk3588_recovery/images/recovery.img
lrwxrwxrwx 1 root root       30  6月 16 19:59 rootfs.img -> ../../debian/linaro-rootfs.img
lrwxrwxrwx 1 root root       22  6月 16 19:35 uboot.img -> ../../u-boot/uboot.img
lrwxrwxrwx 1 root root       26  6月 11 23:00 update.img -> ../update/Image/update.img
-rw-r--r-- 1 root root  4472832  6月 11 23:00 userdata.img

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll debian/
drwxr-xr-x 22 root root       4096  6月  9 12:58 binary/
-rw-rw-rw-  1 root root  579714760  6月 16 13:24 linaro-bullseye-alip-20240616-1.tar.gz
lrwxrwxrwx  1 root root         38  6月 16 13:26 linaro-bullseye-arm64.tar.gz -> linaro-bullseye-alip-20240616-1.tar.gz
-rw-r--r--  1 root root 3362783232  6月 16 19:59 linaro-rootfs.img
-rwxr-xr-x  1 root root        955  6月  9 12:58 mk-base-debian.sh*
-rwxr-xr-x  1 root root        526  6月  9 12:58 mk-image.sh*
-rwxr-xr-x  1 root root       4554  6月  9 12:58 mk-iso-debian.sh*
-rwxr-xr-x  1 root root       7358  6月 11 22:36 mk-rootfs-bullseye.sh*
-rwxr-xr-x  1 root root         87  6月  9 12:58 mk-rootfs.sh*
drwxr-xr-x  4 root root       4096  6月  9 12:58 overlay/
drwxr-xr-x  5 root root       4096  6月  9 12:58 overlay-debug/
drwxr-xr-x  3 root root       4096  6月  9 12:58 overlay-firmware/
drwxr-xr-x  4 root root       4096  6月  9 12:58 packages/
drwxr-xr-x  7 root root       4096  6月  9 12:58 packages-patches/
-rwxr-xr-x  1 root root       2483  6月  9 12:58 post-build.sh*
-rw-r--r--  1 root root       2373  6月  9 12:58 readme.md
drwxr-xr-x  4 root root       4096  6月  9 12:58 scripts/
drwxr-xr-x 11 root root       4096  6月  9 12:58 ubuntu-build-service/

可以看到该次编译重新生成了boot.imgrootfs.img。此外由于我们执行了./build.sh debian,此时output/.config中默认系统已经设置为了debian

编译完成会在debian目录下生成:linaro-buster-alip-xxxxx-1.tar.gz(xxxxx 表示生成时间戳)。

因此我们将debian根文件系统移动到/work/tftproot文件;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ mv debian/linaro-rootfs.img /work/tftpboot/
3.5.6 Yocto编译

执行以下命令自动完成Yocto的编译及打包:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp# ./build.sh yocto

编译后在yocto目录build/lastest下生成rootfs.img

3.5.7 打包分区镜像

执行以下命令更新output/firmware/下各个分区镜像;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ./build.sh firmware

查看目录:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll rockdev/
lrwxrwxrwx 1 root root       21  6月 16 19:28 boot.img -> ../../kernel/boot.img
lrwxrwxrwx 1 root root       44  6月 16 19:35 MiniLoaderAll.bin -> ../../u-boot/rk3588_spl_loader_v1.13.112.bin
-rw-r--r--  1 root root    49152  6月 16 21:13 misc.img
-rw-r--r--  1 root root 21651456  6月 16 21:13 oem.img
lrwxrwxrwx  1 root root       49  6月 16 21:13 parameter.txt -> ../../device/rockchip/.chips/rk3588/parameter.txt
lrwxrwxrwx 1 root root       67  6月 16 19:45 recovery.img -> ../../buildroot/output/rockchip_rk3588_recovery/images/recovery.img
lrwxrwxrwx 1 root root       30  6月 16 19:59 rootfs.img -> ../../debian/linaro-rootfs.img
lrwxrwxrwx 1 root root       22  6月 16 19:35 uboot.img -> ../../u-boot/uboot.img
lrwxrwxrwx 1 root root       26  6月 11 23:00 update.img -> ../update/Image/update.img
-rw-r--r--  1 root root  4472832  6月 16 21:13 userdata.img

可以看到该次编译重新生成了: parameter.txt misc.img oem.img userdata.img

3.5.8 打包统一固件

执行如下命令重新生成统一固件;

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ./build.sh updateimg

查看目录:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll rockdev/
lrwxrwxrwx 1 root root       21  6月 16 19:28 boot.img -> ../../kernel/boot.img
lrwxrwxrwx 1 root root       44  6月 16 19:35 MiniLoaderAll.bin -> ../../u-boot/rk3588_spl_loader_v1.13.112.bin
-rw-r--r--  1 root root    49152  6月 16 21:13 misc.img
-rw-r--r--  1 root root 21651456  6月 16 21:13 oem.img
lrwxrwxrwx  1 root root       49  6月 16 21:13 parameter.txt -> ../../device/rockchip/.chips/rk3588/parameter.txt
lrwxrwxrwx 1 root root       67  6月 16 19:45 recovery.img -> ../../buildroot/output/rockchip_rk3588_recovery/images/recovery.img
lrwxrwxrwx 1 root root       30  6月 16 19:59 rootfs.img -> ../../debian/linaro-rootfs.img
lrwxrwxrwx 1 root root       22  6月 16 19:35 uboot.img -> ../../u-boot/uboot.img
lrwxrwxrwx  1 root root       26  6月 16 21:20 update.img -> ../update/Image/update.img
-rw-r--r--  1 root root  4472832  6月 16 21:13 userdata.img

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ls -l  output/update/
drwxr-xr-x 2 root root 4096  6月 16 21:19 Image
lrwxrwxrwx 1 root root   18  6月 16 21:20 package-file -> Image/package-file
lrwxrwxrwx 1 root root   16  6月 16 21:20 update.img -> Image/update.img

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll output/update/Image/
lrwxrwxrwx 1 root root         24  6月 16 21:18 boot.img -> ../../../kernel/boot.img
lrwxrwxrwx 1 root root         47  6月 16 21:18 MiniLoaderAll.bin -> ../../../u-boot/rk3588_spl_loader_v1.13.112.bin
lrwxrwxrwx 1 root root         23  6月 16 21:18 misc.img -> ../../firmware/misc.img
lrwxrwxrwx 1 root root         22  6月 16 21:18 oem.img -> ../../firmware/oem.img
-rw-r--r-- 1 root root        225  6月 16 21:18 package-file
lrwxrwxrwx 1 root root         52  6月 16 21:18 parameter.txt -> ../../../device/rockchip/.chips/rk3588/parameter.txt
lrwxrwxrwx 1 root root         70  6月 16 21:18 recovery.img -> ../../../buildroot/output/rockchip_rk3588_recovery/images/recovery.img
lrwxrwxrwx 1 root root         33  6月 16 21:18 rootfs.img -> ../../../debian/linaro-rootfs.img
lrwxrwxrwx 1 root root         25  6月 16 21:18 uboot.img -> ../../../u-boot/uboot.img
-rw-r--r-- 1 root root 3480216138  6月 16 21:20 update.img
-rw-r--r-- 1 root root 3479744516  6月 16 21:19 update.raw.img
lrwxrwxrwx 1 root root         27  6月 16 21:18 userdata.img -> ../../firmware/userdata.img

可以看到该次编译重新生成了: update.img

四、SDK固件升级

RK3588有两种工作模式,

工作模式Normal 模式升级模式
启动介质eMMC 接口/SDMMC 接口
描述Normal 模式就是正常的启动过程, 各个组件依次加载,正常进入系统。目前支持3种升级模式,各有优缺点:
1. Maskrom升级模式
2. Loader 升级模式
3. SD 升级模式

一般情况下,开机直接进入Normal模式正常启动系统。

其中升级模式中,不同升级模式之间的对比:

升级模式Maskrom升级模式Loader 升级模式SD 升级模式
简单描述1. 使用USB线将主板连接到电脑上;
2. 硬件操作使板子进入升级模式;
3. 在PC上使用USB升级单板固件。
1. 使用USB线将主板连接到电脑上;
2. 软件或按键操作使板子进入升级模式;
3. 在PC上使用USB升级单板固件。
1. 通过升级卡制作工具,将MicroSD卡制作为升级卡;
2. 将升级卡插入主板,上电开机,机器自动执行升级。
连接方式USBUSBTF卡(少数为SD卡槽)
升级工具 Windows PC Linux PCWindows 上升级固件 Linux 上升级固件Windows 上升级固件Linux 上升级固件Windows 上制作升级卡
不支持
进入方法需要硬件操作按键或软件进入(在串口或 ADB 命令行模式下,输入 reboot loader 命令)上电直接进入
使用条件硬件操作进入能正常使用uboot
使用场景推荐1. 当板子无法正常启动时候;
2. 在切换烧写Linux和Android固件的情况下。
1. 有完整uboot或能正常进入系统;
2. 需要单独烧写分区(uboot或boot分区等)。
1. 工人操作方便,适合产品批量生产时候;
2. 产品定型后升级,方便最终客户操作。
优点1. 最基本的烧写方式;
2. 非固件和硬件问题,一般都能成功烧写;
3. 不需要uboot支持,拯救变砖的单板;
4. 支持跨系统升级(Linux和安卓等)。
1. 烧写效果Maskrom升级模式差不多;
2. 能单独烧写分区;
3. 进入Loader模式方便。
1. 操作方便,只需插卡启动;
2.集合了Maskrom升级模式的优点。
缺点1. 进入方式麻烦,不适难拆除外壳的产品;
2. 烧写分区表麻烦,较难单独烧写分区;
3. 需要完全擦除设备再烧写。
1. 需要完整的Loader(通常指uboot);
2. 跨系统升级需要完全擦除设备再烧写。
1. 需要合成完整固件。
4.1 Windows刷机

Winodws刷机我们有两种方式:

  • 采用SD升级模式:
  • RKDevTool烧写固件到eMMC
4.1.1 SD卡升级模式

这里我们就采用SD升级模式来将我们全自动编译的镜像文件烧录到eMMC,具体可以参考《若固件大于4GSD升级卡制作教程》。

(1) 准备工作:

  • 烧写工具下载:将tools/windows目录下的SDDiskTool_v1.76.zip工具上传到Windows系统,并进行解压;
  • 下载需要升级的统一固件:将buildroot系统统一镜像rockdev/update.img上传到Windows系统;
  • MicroSD通过读卡器插入PC
  • 将开发板连接到HDMI显示屏;

(2) 以管理员身份运行SD_Firmware_Tool.exe,勾选固件升级框,选择正确的可移动磁盘设备和升级固件;

(3) 点击开始创建之后,等待创建结束;烧录完成后,可以查看MicroSD的内容:

(4) 取出MicroSD卡,插入开发板的MicroSD卡插槽,对主板上电开机,主板自动开始升级。

注意:由于我们无法可视化查看升级进度,因此此处需要耐心等待3分钟。

(5) 升级完成后,取出MicroSD卡,开发板自动重启,显示屏显示如下;

关于buildroot系统简单测试可以参考后续《Rockchip RK3588 - Rockchip Linux SDK Buildroot文件系统构建》。

4.1.2 RKDevTool烧写固件到eMMC

SDK提供Windows烧写工具(RKDevTool工具版本需要V3.15或以上),工具位于工程根目录:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll tools/windows/
-rwxr-xr-x 1 root root  7080412  6月  9 12:59 boot_merger_v1.32.zip*
-rwxr-xr-x 1 root root 27440555  6月  9 12:59 DDR_UserTool_v1.41.zip*
-rwxr-xr-x 1 root root  9814896  6月  9 12:59 DriverAssitant_v5.12.zip*
-rwxr-xr-x 1 root root   731921  6月  9 12:59 EfuseTool_v1.42.zip*
-rw-r--r-- 1 root root  1793777  6月  9 12:59 FactoryTool_v1.81.zip
-rwxr-xr-x 1 root root 19443215  6月  9 12:59 ParameterTool_v1.2.zip*
-rw-r--r-- 1 root root 50668825  6月  9 12:59 pin_debug_tool_v1.12_20230310_win.zip
-rw-r--r-- 1 root root   380719  6月  9 12:59 programmer_image_tool_v1.26.zip
-rwxr-xr-x 1 root root 59731296  6月  9 12:59 rk_ddrbin_tool_V1.01.7z*
drwxr-xr-x 2 root root     4096  6月  9 12:59 RKDevInfoWriteTool/
-rwxr-xr-x 1 root root  3140313  6月  9 12:59 RKDevInfoWriteTool-1.3.0.7z*
drwxr-xr-x 4 root root     4096  6月  9 12:59 RKDevTool/
-rw-r--r-- 1 root root  2433639  6月  9 12:59 RKDevTool_Release_v3.19.zip
-rwxr-xr-x 1 root root  4181454  6月  9 12:59 RKImageMaker_20230109.zip*
-rwxr-xr-x 1 root root  4164049  6月  9 12:59 RKPCBATool_V1.0.9.zip*
-rwxr-xr-x 1 root root 26104417  6月  9 12:59 rk_sign_tool_v1.42.zip*
-rwxr-xr-x 1 root root  4334042  6月  9 12:59 Rockchip_HdcpKey_Writer_V1.0.5.7z*
drwxr-xr-x 2 root root     4096  6月  9 12:59 Rockchip_USB_SQ_Tool/
-rwxr-xr-x 1 root root 17253972  6月  9 12:59 Rockchip_USB_SQ_Tool_V1.5.7z*
-rw-r--r-- 1 root root   331802  6月  9 12:59 SDDiskTool_v1.76.zip
-rwxr-xr-x 1 root root  3011296  6月  9 12:59 SecureBootTool_v2.2.zip*
-rwxr-xr-x 1 root root     1089  6月  9 12:59 ToolsRelease.txt*
-rw-r--r-- 1 root root   676148  6月  9 12:59 upgrade_tool_v2.23.zip

该方式我们在前面的文章中已经介绍了,具体可以参考《Rockchip RK3588 - NanoPC-T6开发板介绍》第2.3节。

4.2 Linux刷机

Linux下的烧写工具位于tools/linux目录下(Linux_Upgrade_Tool工具版本需要V2.17或以上),请确认你
的板子连接到Maskrom/Loader rockusb

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll tools/linux/
drwxr-xr-x  2 root root     4096  6月  9 12:59 boot_merger/
drwxr-xr-x  2 root root     4096  6月  9 12:59 Firmware_Merger/
drwxr-xr-x  2 root root     4096  6月  9 12:59 Linux_DDR_Bandwidth_Tool/
drwxr-xr-x  2 root root     4096  6月  9 12:59 Linux_Diff_Firmware/
drwxr-xr-x  3 root root     4096  6月  9 12:59 Linux_Pack_Firmware/
drwxr-xr-x  2 root root     4096  6月  9 12:59 Linux_SecureBoot/
drwxr-xr-x  4 root root     4096  6月  9 12:59 Linux_SecurityAVB/
-rw-r--r--  1 root root  5393885  6月  9 12:59 Linux_SecurityDM_v1_01.tar.gz
drwxr-xr-x  3 root root     4096  6月  9 12:59 Linux_Upgrade_Tool/
drwxr-xr-x  2 root root     4096  6月  9 12:59 PinDebug/
drwxr-xr-x  2 root root     4096  6月  9 12:59 programming_image_tool/
-rw-r--r--  1 root root 81801567  6月  9 12:59 rk_ddrbin_tool_V1.01.7z
drwxr-xr-x  3 root root     4096  6月  9 12:59 rk_sign_tool/
-rwxr-xr-x  1 root root 22457713  6月  9 12:59 rk_sign_tool_v1.42_linux.zip*
-rwxr-xr-x  1 root root      794  6月  9 12:59 ToolsRelease.txt*

比如buildroot系统编译生成的固件在rockdev目录下:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ll rockdev/
lrwxrwxrwx 1 root root       21  6月 11 22:52 boot.img -> ../../kernel/boot.img
lrwxrwxrwx 1 root root       44  6月 11 23:00 MiniLoaderAll.bin -> ../../u-boot/rk3588_spl_loader_v1.13.112.bin
-rw-r--r-- 1 root root    49152  6月 11 23:00 misc.img
-rw-r--r-- 1 root root 17457152  6月 11 23:00 oem.img
lrwxrwxrwx 1 root root       49  6月 11 23:00 parameter.txt -> ../../device/rockchip/.chips/rk3588/parameter.txt
lrwxrwxrwx 1 root root       67  6月 11 23:00 recovery.img -> ../../buildroot/output/rockchip_rk3588_recovery/images/recovery.img
lrwxrwxrwx 1 root root       57  6月 11 22:59 rootfs.img -> ../../buildroot/output/rockchip_rk3588/images/rootfs.ext2
lrwxrwxrwx 1 root root       22  6月 11 23:00 uboot.img -> ../../u-boot/uboot.img
lrwxrwxrwx 1 root root       26  6月 11 23:00 update.img -> ../update/Image/update.img
-rw-r--r-- 1 root root  4472832  6月 11 23:00 userdata.img

升级命令如下:

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ ./rkflash.sh

这里rkflash.sh脚本实际上就是使用upgrade_tool命令烧写各个分区,比如核心脚本:

if [ ! -n "$1" ];then
echo "flash all images as default"
FLASH_TYPE=all
else
FLASH_TYPE="$1"
fi

if [ $FLASH_TYPE = all ]
then
        $UPGRADETOOL ul -noreset $LOADER
        $UPGRADETOOL di -p $PARAMETER
        $UPGRADETOOL di -uboot $UBOOT
        $UPGRADETOOL di -trust $TRUST
        $UPGRADETOOL di -b $BOOT
        $UPGRADETOOL di -r $RECOVERY
        $UPGRADETOOL di -m $MISC
        $UPGRADETOOL di -oem $OEM
        $UPGRADETOOL di -userdata $USERDATA
        $UPGRADETOOL di -rootfs $ROOTFS
        $UPGRADETOOL rd
fi

当然也可以直接使用upgrade_tool命令一一烧写各个分区镜像或者打包后完整的固件,具体操作可以参考:《Linux下烧录固件》。

4.3 系统分区介绍

parameter.txt保存着分区信息:

FIRMWARE_VER: 1.0
MACHINE_MODEL: RK3588
MACHINE_ID: 007
MANUFACTURER: RK3588
MAGIC: 0x5041524B
ATAG: 0x00200800
MACHINE: 0xffffffff
CHECK_MASK: 0x80
PWR_HLD: 0,0,A,0,1
TYPE: GPT
GROW_ALIGN: 0
CMDLINE: mtdparts=:0x00002000@0x00004000(uboot),0x00002000@0x00006000(misc),0x00020000@0x00008000(boot),0x00040000@0x00028000(recovery),0x00010000@0x00068000(backup),0x01c00000@0x00078000(rootfs),0x00040000@0x01c78000(oem),-@0x01cb8000(userdata:grow)
uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9
uuid:boot=7A3F0000-0000-446A-8000-702F00006273

解析信息如下:

NumberStart (sector)Start (sector) End (sector)SizeName
10x4000(16384)0x5FFF(24575)4Muboot
20x6000(24576)0x7FFF(32767)4Mmisc
30x8000(32768)0x27FFF(163839)64Mboot
40x28000(163840)0x67FFF(425983)128Mrecovery
50x68000(425984)0x77FFF(491519)32Mbackup
60x78000(491520)0x1C77FFF(29851647)14GBrootfs
70x1C78000(29851648)0x01CB7FFF(30113791)128Moem
80x01CB8000(30113792)-userdata

其中:

  • uboot 分区:供uboot编译出来的uboot.img
  • misc分区:引导参数分区,供misc.img,给recovery使用;
  • boot分区:供kernel编译出来的boot.img(kernel+dtb);
  • recovery分区:供recovery编译出的recovery.img(kernel+dtb+ramdisk组成的根文件系统);
  • backup分区:预留,暂时没有用;
  • rootfs分区:供buildrootdebianyocto编出来的rootfs.img
  • oem分区:给厂家使用,存放厂家的APP或数据。挂载在/oem目录;
  • userdata分区:供APP临时生成文件或给最终用户使用,挂载在/userdata目录下。
4.4 dd烧录分区

我们也可以通过dd命令烧写各个分区镜像;

dd if=uboot.img of=/dev/mmcblk0p1 bs=1M
dd if=boot.img of=/dev/mmcblk0p3 bs=1M
dd if=rootfs.img of=/dev/mmcblk0p6 bs=1M
dd if=oem.img of=/dev/mmcblk0p7 bs=1M
dd if=userdata.img of=/dev/mmcblk0p8 bs=1M
4.4.1 烧录userdata.img

如果要更新userdata.img,具体流程如下。

(1) 首先将userdata.img拷贝到tftp根目录下(/work/tftpboot/):

root@ubuntu:/work/sambashare/rk3588/armsom/armsom-rk3588-bsp$ cp rockdev/userdata.img /work/tftpboot/

busybox内置tftp,可以直接从ubuntu宿主机tftp服务器下载文件:

root@rk3588-buildroot:/opt# tftp -g -l userdata.img 192.168.0.200

ubuntu中的tftp根目录下(/work/tftpboot/),下载文件userdata.img

root@rk3588-buildroot:/opt# ls -l
drwxr-xr-x 6 root root 4096 Jun 11 14:52 unixbench
-rw-r--r-- 1 root root 4472832 Jun 16 04:51 userdata.img

(2) 接着我们在/userdata目录下创建一个test.txt文件;

root@rk3588-buildroot:/opt# touch /userdata/test.txt
root@rk3588-buildroot:/opt# ls -l /userdata/
total 279
-rw-r--r-- 1 root root  87402 Jun  9 04:58 200frames_count.h264
-rw-r--r-- 1 root root  81582 Jun  9 04:58 belle-nuit-testchart-1080p.png
drwx------ 2 root root  12288 Jun 11 15:00 lost+found
-rw-r--r-- 1 root root 101760 Jun  9 04:58 piano2-CoolEdit.mp3
-rw-r--r-- 1 root root      0 Jun 16 04:31 test.txt

(3) 重新烧写userdata分区:

root@rk3588-buildroot:/opt# dd if=userdata.img of=/dev/mmcblk0p8 bs=1M
4+1 records in
4+1 records out
4472832 bytes (4.5 MB, 4.3 MiB) copied, 0.00915314 s, 489 MB/s

再次查看/userdata

root@rk3588-buildroot:/opt# ls -l /userdata/
total 278
-rw-r--r-- 1 root root  87402 Jun  9 04:58 200frames_count.h264
-rw-r--r-- 1 root root  81582 Jun  9 04:58 belle-nuit-testchart-1080p.png
drwx------ 2 root root  12288 Jun 11 15:00 lost+found
-rw-r--r-- 1 root root 101760 Jun  9 04:58 piano2-CoolEdit.mp3

可以看到该目录下已经不存在test.txt文件了,说明分区烧录成功了。

4.4.2 烧录debian根文件系统

ubuntu中的tftp根目录下(/work/tftpboot/),下载文件linaro-rootfs.img

# 耐心等待50分钟
root@rk3588-buildroot:/opt# tftp -g -l linaro-rootfs.img 192.168.0.200
root@rk3588-buildroot:/opt# ls -l
-rw-r--r-- 1 root root 3313500160 Jun 16 15:40 linaro-rootfs.img
drwxr-xr-x 6 root root       4096 Jun 11 14:52 unixbench
-rw-r--r-- 1 root root    4472832 Jun 16 04:51 userdata.img

重新烧写rootfs分区:

root@rk3588-buildroot:/opt# dd if=linaro-rootfs.img of=/dev/mmcblk0p6 bs=1M
3160+0 records in
3160+0 records out
3313500160 bytes (3.3 GB, 3.1 GiB) copied, 13.3972 s, 247 MB/s
4.5 debain系统测试
4.5.1 查看系统

重启开发板,查看系统信息;

root@armsom-sige7:/# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 11 (bullseye)
Release:        11
Codename:       bullseye
4.5.2 设置DNS服务器

设置DNS服务器:

root@armsom-sige7:/# sudo vi /etc/resolv.conf
# 追加
nameserver 114.114.114.114

root@armsom-sige7:/# sudo /etc/init.d/networking restart
4.5.3 查看磁盘空间

这里我们可以通过df -hT查看磁盘空间信息;

root@armsom-sige7:/# df -hT
文件系统       类型      容量  已用  可用 已用% 挂载点
/dev/root      ext4      3.0G  3.0G     0  100% /
devtmpfs       devtmpfs  3.9G     0  3.9G    0% /dev
tmpfs          tmpfs     3.9G     0  3.9G    0% /dev/shm
tmpfs          tmpfs     1.6G  2.1M  1.6G    1% /run
tmpfs          tmpfs     5.0M  4.0K  5.0M    1% /run/lock
/dev/mmcblk0p7 ext4      121M   12M  103M   11% /oem
/dev/mmcblk0p8 ext4       43G  288K   42G    1% /userdata
tmpfs          tmpfs     793M   28K  793M    1% /run/user/1000
tmpfs          tmpfs     793M   28K  793M    1% /run/user/110

这里我们可以看到根目录挂载在/dev/root设备节点上,文件系统格式是ext4/dev/root其实就是/dev/mmcblk0p6,也就是eMMC设备的rootfs分区。

但是为什么这里看到的/dev/root大小只有3.0G呢?rootfs分区我们不是指定了14G么?这主要是因为我们的根文件系统镜像制作的就是那么大,剩余的分区空间并未使用。

4.5.4 resize2fs扩容

文件系统能通过扩充容量来利用其分区后的空闲空间。通常情况下,这甚至可以在文件系统被挂载时进行。

这里我们可以通过resize2fs指令进行扩容:

root@armsom-sige7:/# resize2fs /dev/mmcblk0p6
resize2fs 1.46.2 (28-Feb-2021)
Filesystem at /dev/mmcblk0p6 is mounted on /; on-line resizing required
[ 1881.827893] EXT4-fs warning (device mmcblk0p6): ext4_resize_begin:82: There are errors in the filesystem, so online resizing is not allowed
old_desc_blocks = 1, new_desc_blocks = 2
resize2fs: Permission denied to resize filesystem

很明显扩容失败了,主要是因为该设备被挂载到/,内核不支持在线调整已挂载文件系统的大小。

为此我们制作一个SD卡启动盘,使开发板从SD启动,此时eMMC设备节点为/dev/mmcblk0

这里我们可以通过resize2fs指令进行扩容:

zhengyang@armsom-sige7:~$ sudo e2fsck -f /dev/mmcblk0p6
e2fsck 1.46.5 (30-Dec-2021)
/dev/mmcblk0p6: recovering journal
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 3A: Optimizing directories
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Free blocks count wrong (32132, counted=9666).
Fix? yes
Free inodes count wrong (130235, counted=129568).
Fix? yes

/dev/mmcblk0p6: ***** FILE SYSTEM WAS MODIFIED *****
/dev/mmcblk0p6: 72832/202400 files (0.2% non-contiguous), 799294/808960 blocks
zhengyang@armsom-sige7:~$ sudo resize2fs /dev/mmcblk0p6
resize2fs 1.46.5 (30-Dec-2021)
Resizing the filesystem on /dev/mmcblk0p6 to 3670016 (4k) blocks.
The filesystem on /dev/mmcblk0p6 is now 3670016 (4k) blocks long.

开发板拔掉SD卡,重启启动开发板,稍等一会,显示器上会进入debain桌面系统(如果不扩容的话,由于/目录没有磁盘空间了,也就进不了debain桌面环境的);

注意:此时需要进行应用程序 --> 设置 --> 显示进行配置,关闭调用DSI-1

再次查看磁盘空间:

root@armsom-sige7:/# df -hT
文件系统       类型      容量  已用  可用 已用% 挂载点
/dev/root      ext4       14G  3.0G   11G   23% /
devtmpfs       devtmpfs  3.9G  8.0K  3.9G    1% /dev
tmpfs          tmpfs     3.9G     0  3.9G    0% /dev/shm
tmpfs          tmpfs     1.6G  2.2M  1.6G    1% /run
tmpfs          tmpfs     5.0M  4.0K  5.0M    1% /run/lock
/dev/mmcblk0p7 ext4      121M   12M  103M   11% /oem
/dev/mmcblk0p8 ext4       43G  288K   42G    1% /userdata
tmpfs          tmpfs     793M   40K  793M    1% /run/user/1000

五、SDK开发

六、build.sh分析

6.1 main函数

由于main函数代码内容较长,我们只对重点内容进行分析:

点击查看代码
main()
{
        [ -z "$DEBUG" ] || set -x

        trap 'err_handler' ERR
        set -eE

        # Save intial envionments
        unset INITIAL_SESSION
        INITIAL_ENV=$(mktemp -u)
        if [ -z "$RK_SESSION" ]; then
                INITIAL_SESSION=1
                env > "$INITIAL_ENV"
        fi

        export LC_ALL=C

        export SCRIPTS_DIR="$(dirname "$(realpath "$BASH_SOURCE")")"
        export COMMON_DIR="$(realpath "$SCRIPTS_DIR/..")"
        export SDK_DIR="$(realpath "$COMMON_DIR/../../..")"
        export DEVICE_DIR="$SDK_DIR/device/rockchip"
        export CHIPS_DIR="$DEVICE_DIR/.chips"
        export CHIP_DIR="$DEVICE_DIR/.chip"

        export RK_DATA_DIR="$COMMON_DIR/data"
        export RK_TOOL_DIR="$COMMON_DIR/tools"
        export RK_IMAGE_DIR="$COMMON_DIR/images"
        export RK_KBUILD_DIR="$COMMON_DIR/linux-kbuild"
        export RK_CONFIG_IN="$COMMON_DIR/configs/Config.in"

        export RK_BUILD_HOOK_DIR="$COMMON_DIR/build-hooks"
        export BUILD_HELPER="$RK_BUILD_HOOK_DIR/build-helper"
        export RK_POST_HOOK_DIR="$COMMON_DIR/post-hooks"
        export POST_HELPER="$RK_POST_HOOK_DIR/post-helper"

        export PARTITION_HELPER="$SCRIPTS_DIR/partition-helper"

        export RK_SESSION="${RK_SESSION:-$(date +%F_%H-%M-%S)}"

        export RK_OUTDIR="$SDK_DIR/output"
        export RK_SESSION_DIR="$RK_OUTDIR/sessions"
        export RK_LOG_BASE_DIR="$RK_OUTDIR/log"
        export RK_LOG_DIR="$RK_SESSION_DIR/$RK_SESSION"
        export RK_INITIAL_ENV="$RK_LOG_DIR/initial.env"
        export RK_CUSTOM_ENV="$RK_LOG_DIR/custom.env"
        export RK_FINAL_ENV="$RK_LOG_DIR/final.env"
        export RK_ROCKDEV_DIR="$SDK_DIR/rockdev"
        export RK_FIRMWARE_DIR="$RK_OUTDIR/firmware"
        export RK_SECURITY_FIRMWARE_DIR="$RK_OUTDIR/security-firmware"
        export RK_CONFIG="$RK_OUTDIR/.config"
        export RK_DEFCONFIG_LINK="$RK_OUTDIR/defconfig"

        # For Makefile
        case "$@" in
                make-targets)
                        # Chip targets
                        ls "$CHIPS_DIR"
                        ;&
                make-usage)
                        run_build_hooks "$@"
                        rm -f "$INITIAL_ENV"
                        exit 0 ;;
        esac


        # Log SDK information
        MANIFEST="$SDK_DIR/.repo/manifest.xml"
        if [ -e "$MANIFEST" ]; then
                if [ ! -L "$MANIFEST" ]; then
                        MANIFEST="$SDK_DIR/.repo/manifests/$(grep -o "[^"]*.xml" "$MANIFEST")"
                fi
                TAG="$(grep -o "linux-.*-gen-rkr[^."]*" "$MANIFEST" | 
                        head -n 1 || true)"
                MANIFEST="$(basename "$(realpath "$MANIFEST")")"
                echo
                echo -e "e[35m############### Rockchip Linux SDK ###############e[0m"
                echo
                echo -e "e[35mManifest: $MANIFESTe[0m"
                if [ "$TAG" ]; then
                        echo -e "e[35mVersion: $TAGe[0m"
                fi
                echo
        fi

        # Prepare firmware dirs
        mkdir -p "$RK_FIRMWARE_DIR" "$RK_SECURITY_FIRMWARE_DIR"

        cd "$SDK_DIR"
        [ -f README.md ] || ln -rsf "$COMMON_DIR/README.md" .
        [ -d common ] || ln -rsf "$COMMON_DIR" .

        # TODO: Remove it in the repo manifest.xml
        rm -f envsetup.sh

        OPTIONS=${@:-allsave}

        # Special handle for chip and defconfig
        # e.g. ./build.sh rk3588:rockchip_defconfig
        for opt in $OPTIONS; do
                if [ -d "$CHIPS_DIR/${opt%%:*}" ]; then
                        OPTIONS=$(echo "$OPTIONS" | xargs -n 1 | 
                                sed "s/^$opt$/chip:$opt/" | xargs)
                elif echo "$opt" | grep -q "^[0-9a-z_]*_defconfig$"; then
                        OPTIONS=$(echo "$OPTIONS" | xargs -n 1 | 
                                sed "s/^$opt$/defconfig:$opt/" | xargs)
                fi
        done

        # Options checking
        CMDS="$(run_build_hooks support-cmds all | xargs)"
        for opt in $OPTIONS; do
                case "$opt" in
                        help | h | -h | --help | usage | ?) usage ;;
                        clean:*)
                                # Check cleanup modules
                                for m in $(echo ${opt#clean:} | tr ':' ' '); do
                                        grep -wq clean_hook 
                                                "$SCRIPTS_DIR/mk-$m.sh" 
                                                2>/dev/null || usage
                                done
                                ;&
                        shell | cleanall)
                                # Check single options
                                if [ "$opt" = "$OPTIONS" ]; then
                                        break
                                fi

                                echo "ERROR: $opt cannot combine with other options!"
                                ;;
                        post-rootfs)
                                if [ "$opt" = "$1" -a -d "$2" ]; then
                                        # Hide other args from build stages
                                        OPTIONS=$opt
                                        break
                                fi

                                echo "ERROR: $opt should be the first option followed by rootfs dir!"
                                ;;
                        *)
                                # Make sure that all options are handled
                                if option_check "$CMDS" $opt; then
                                        continue
                                fi

                                echo "ERROR: Unhandled option: $opt"
                                ;;
                esac

                usage
        done

        # Prepare log dirs
        if [ ! -d "$RK_LOG_DIR" ]; then
                rm -rf "$RK_LOG_BASE_DIR" "$RK_LOG_DIR" "$RK_SESSION_DIR/latest"
                mkdir -p "$RK_LOG_DIR"
                ln -rsf "$RK_SESSION_DIR" "$RK_LOG_BASE_DIR"
                ln -rsf "$RK_LOG_DIR" "$RK_SESSION_DIR/latest"
                echo -e "e[33mLog saved at $RK_LOG_DIRe[0m"
                echo
        fi

        # Drop old logs
        cd "$RK_LOG_BASE_DIR"
        rm -rf $(ls -t | sed '1,10d')
        cd "$SDK_DIR"

        # Save initial envionments
        if [ "$INITIAL_SESSION" ]; then
                rm -f "$RK_INITIAL_ENV"
                mv "$INITIAL_ENV" "$RK_INITIAL_ENV"
                ln -rsf "$RK_INITIAL_ENV" "$RK_OUTDIR/"
        fi

        # Init stage (preparing SDK configs, etc.)
        run_build_hooks init $OPTIONS
        rm -f "$RK_OUTDIR/.tmpconfig*"

        # No need to go further
        CMDS="$(run_build_hooks support-cmds pre-build build 
                post-build | xargs) cleanall clean post-rootfs"
        option_check "$CMDS" $OPTIONS || return 0

        # Force exporting config environments
        set -a

        # Load config environments
        source "$RK_CONFIG"
        cp "$RK_CONFIG" "$RK_LOG_DIR"

        if [ -z "$INITIAL_SESSION" ]; then
                # Inherit session environments
                sed -n 's/^(RK_.*=)(.*)/""/p' "$RK_FINAL_ENV" > 
                        "$INITIAL_ENV"
                source "$INITIAL_ENV"
                rm -f "$INITIAL_ENV"
        else
                # Detect and save custom environments

                # Find custom environments
                rm -f "$RK_CUSTOM_ENV"
                for cfg in $(grep "^RK_" "$RK_INITIAL_ENV" || true); do
                        env | grep -q "^${cfg//"/}$" || 
                                echo "$cfg" >> "$RK_CUSTOM_ENV"
                done

                # Allow custom environments overriding
                if [ -e "$RK_CUSTOM_ENV" ]; then
                        ln -rsf "$RK_CUSTOM_ENV" "$RK_OUTDIR/"

                        echo -e "e[31mWARN: Found custom environments: e[0m"
                        cat "$RK_CUSTOM_ENV"

                        echo -e "e[31mAssuming that is expected, please clear them if otherwise.e[0m"
                        read -t 10 -p "Press enter to continue."
                        source "$RK_CUSTOM_ENV"

                        if grep -q "^RK_KERNEL_VERSION=" "$RK_CUSTOM_ENV"; then
                                echo -e "e[31mCustom RK_KERNEL_VERSION ignored!e[0m"
                                load_config RK_KERNEL_VERSION
                        fi

                        if grep -q "^RK_ROOTFS_SYSTEM=" "$RK_CUSTOM_ENV"; then
                                echo -e "e[31mCustom RK_ROOTFS_SYSTEM ignored!e[0m"
                                load_config RK_ROOTFS_SYSTEM
                        fi
                fi
        fi

        source "$PARTITION_HELPER"
        rk_partition_init

        set +a

        export PYTHON3=/usr/bin/python3
        export RK_KERNEL_VERSION_REAL=$(kernel_version_real)

        # Handle special commands
        case "$OPTIONS" in
                cleanall)
                        run_build_hooks clean
                        rm -rf "$RK_OUTDIR" "$SDK_DIR/rockdev"
                        finish_build cleanall
                        exit 0 ;;
                clean:*)
                        MODULES="$(echo ${OPTIONS#clean:} | tr ':' ' ')"
                        for m in $MODULES; do
                                "$SCRIPTS_DIR/mk-$m.sh" clean
                        done
                        finish_build clean - $MODULES
                        exit 0 ;;
                post-rootfs)
                        shift
                        run_post_hooks $@
                        finish_build post-rootfs
                        exit 0 ;;
        esac

        # Save final environments
        rm -f "$RK_FINAL_ENV"
        env > "$RK_FINAL_ENV"
        ln -rsf "$RK_FINAL_ENV" "$RK_OUTDIR/"

        # Log configs
        echo
        echo "=========================================="
        echo "          Final configs"
        echo "=========================================="
        env | grep -E "^RK_.*=.+" | grep -vE "PARTITION_[0-9]" | 
                grep -vE "=""$|_DEFAULT=y" | 
                grep -vE "^RK_CONFIG|_BASE_CFG=|_LINK=|DIR=|_ENV=|_NAME=" | sort
        echo

        # Pre-build stage (submodule configuring, etc.)
        run_build_hooks pre-build $OPTIONS

        # No need to go further
        CMDS="$(run_build_hooks support-cmds build post-build | xargs)"
        option_check "$CMDS" $OPTIONS || return 0

        # Build stage (building, etc.)
        run_build_hooks build $OPTIONS

        # No need to go further
        CMDS="$(run_build_hooks support-cmds post-build | xargs)"
        option_check "$CMDS" $OPTIONS || return 0

        # Post-build stage (firmware packing, etc.)
        run_build_hooks post-build $OPTIONS
}
6.1.1 提示模式和错误处理

调试模式设置:首先通过判断是否设置了环境变量DEBUG,决定是否启用调试模式。如果 DEBUG 被设置为非空值,则运行 set -x 开启调试模式,这样脚本执行时会显示每一行命令的执行情况。

错误处理:使用 trapERR 捕获脚本中的错误。一旦发生错误,将调用 err_handler 函数;同时,set -eE 确保如果任何命令失败,脚本会立即退出,并且支持 ERR 跟踪。

保存初始环境变量:接着尝试保存当前的环境变量到一个临时文件中。首先,它解除定义了 INITIAL_SESSION 变量(如果存在),然后使用 mktemp -u 生成一个唯一的临时文件路径。如果 RK_SESSION 变量未设置,则认为这是一个新的会话,并将所有当前环境变量保存到生成的临时文件中。

6.1.2 设置环境变量

接着是设置一系列环境变,这些变量定义了一些重要的目录路径,通常在脚本执行过程中会用到这些路径。

export LC_ALL=C

export SCRIPTS_DIR="$(dirname "$(realpath "$BASH_SOURCE")")"
export COMMON_DIR="$(realpath "$SCRIPTS_DIR/..")"
......

realpath "$BASH_SOURCE" 获取当前脚本的绝对路径,由于build.sh指向了device/rockchip/common/scripts/build.sh;所以:

SCRIPTS_DIR = /device/rockchip/common/scripts
COMMON_DIR = /device/rockchip/common
SDK_DIR = 
DEVICE_DIR = /device/rockchip
CHIPS_DIR = /device/rockchip/.chips
CHIP_DIR = /device/rockchip/.chip
......
6.1.3 选项make-targets/make-usage

接着就是对选项make-targetsmake-usage的支持,实际上也是输出帮助信息。

6.1.4 选项chip/defconfig

接着就是对如下选项的支持:

  • chip[:[:]] 可选,表示SoC,比如rk3588可选,表示板级配置,比如rockchip_defconfig
  • defconfig[:]:可选,表示板级配置,比如rockchip_defconfig

(1) 如果有参数传递给脚本,则OPTIONS被设置为这些参数的组合;如果没有参数传递,则OPTIONS被设置为 allsave

(2) 接着对$OPTIONS变量进行特殊处理,用于处理 chipdefconfig的情况。它会检查每个参数,并根据特定的条件对其进行转换。

首先:

if [ -d "$CHIPS_DIR/${opt%%:*}" ]; then
    OPTIONS=$(echo "$OPTIONS" | xargs -n 1 | 
    sed "s/^$opt$/chip:$opt/" | xargs)

检查是否存在以$CHIPS_DIR开头、后面跟着$opt变量:分隔之前的字符串作为目录名, 如果满足;修改 $OPTIONS 变量,替换内容$optchip:$opt

  • 比如./builsh rk3588:rockchip_defconfigopt=rk3588:rockchip_defconfig,处理后OPTIONS=chip:rk3588:rockchip_defconfig

接着:

elif echo "$opt" | grep -q "^[0-9a-z_]*_defconfig$"; then
    OPTIONS=$(echo "$OPTIONS" | xargs -n 1 | 
        sed "s/^$opt$/defconfig:$opt/" | xargs)
fi

如果是以_defconfig结尾命名,修改 $OPTIONS 变量,替换内容$optdefconfig:$opt

  • 比如./builsh rockchip_defconfigopt=rockchip_defconfig,处理后OPTIONS=defconfig:rockchip_defconfig
6.1.5 选项检查

首先:

CMDS="$(run_build_hooks support-cmds all | xargs)"

执行run_build_hooks support-cmds all,并将输出结果经过xargs处理后赋值给CMDS变量;

  • xargs 是一个常用的命令行工具,用于将输入转换为命令行参数;
  • 在这种情况下,没有指定任何选项,意味着xargs将把输入中的所有元素合并成一行,以空格分隔;

接着是一段选项检查的代码;

for opt in $OPTIONS; do
		case "$opt" in
				help | h | -h | --help | usage | ?) usage ;;
				clean:*)
						# Check cleanup modules
						for m in $(echo ${opt#clean:} | tr ':' ' '); do
								grep -wq clean_hook 
										"$SCRIPTS_DIR/mk-$m.sh" 
										2>/dev/null || usage
						done
						;&
				shell | cleanall)
						# Check single options
						if [ "$opt" = "$OPTIONS" ]; then
								break
						fi

						echo "ERROR: $opt cannot combine with other options!"
						;;
				post-rootfs)
						if [ "$opt" = "$1" -a -d "$2" ]; then
								# Hide other args from build stages
								OPTIONS=$opt
								break
						fi

						echo "ERROR: $opt should be the first option followed by rootfs dir!"
						;;
				*)
						# Make sure that all options are handled
						if option_check "$CMDS" $opt; then
								continue
						fi

						echo "ERROR: Unhandled option: $opt"
						;;
		esac

		usage
done

根据传入的选项($OPTIONS)进行判断和处理;

  • 当选项满足help | h | -h | --help | usage | ?,执行usage函数。比如我们前文执行 ./build.sh help,就是则调用usage函数来显示帮助信息;
  • 如果选项以 clean: 开头,则验证验证相应的清理模块是否存在,比如./build.sh clean:kernel,则判断"device/rockchip/common/scripts/mk-kernel.sh/mk-kernel.sh中是否包含clean_hook方法;后续会调用mk-kernel.sh clean执行清理工作;
  • 如果选项是shellcleanall,执行函数run_build_hooks clean,该函数则会遍历device/rockchip/common/scriptsshell脚本文件,并传入clean参数函数依次执行;
  • 如果选项是post-rootfs,则后续会调用run_post_hooks $@trigger post-rootfs hook scripts

参考文章

[1] Rockchip_Developer_Guide_Linux_Software_CN.pdf

[2] repo介绍与使用

[3] Rockchip_Developer_Guide_Linux_Upgrade_CN.pdf

[4] Rockchip RK3588 - NanoPC-T6开发板介绍

[5] Rockchip RK3399 - NanoPC-T4开发板介绍

[6] Buildroot根文件系统构建

[7] Debian根文件系统构建

本文地址:https://www.vps345.com/13564.html

搜索文章

Tags

docker 容器 运维 java-rabbitmq java PV计算 带宽计算 流量带宽 服务器带宽 上行带宽 上行速率 什么是上行带宽? CC攻击 攻击怎么办 流量攻击 DDOS攻击 服务器被攻击怎么办 源IP centos python linux 机器学习 服务器 深度学习 人工智能 ubuntu 无人机 机器人 ai nlp pytorch tensorflow macos MacMini Mac 迷你主机 mini Apple 服务器安全 网络安全策略 防御服务器攻击 安全威胁和解决方案 程序员博客保护 数据保护 安全最佳实践 ROS 自动驾驶 自动化 ssh漏洞 ssh9.9p2 CVE-2025-23419 开发语言 云原生 iventoy VmWare OpenEuler 数据库 oracle 关系型 安全 分布式 AI Dify 大模型应用 javascript 前端 chrome edge Deepseek Deepseek-R1 大模型 私有化部署 推理模型 具身智能 强化学习 网络工程师 网络管理 软考 2024 2024年上半年 下午真题 答案 DeepSeek Linux opencv webpack ssh https windows MCP llama CH340 单片机 嵌入式硬件 串口驱动 CH341 uart 485 ddos android 网络安全 web安全 操作系统 UEFI Legacy MBR GPT U盘安装操作系统 jvm 虚拟机 游戏 pycharm Python教程 Python pycharm安装 音视频 harmonyos 华为 云计算 flutter Google pay Apple pay 面试 职场和发展 c++ conda 程序 编程 内存 性能分析 物联网 图形化界面 vite vue3 部署 FTP服务器 stm32 http word图片自动上传 word一键转存 复制word图片 复制word图文 复制word公式 粘贴word图文 粘贴word公式 数据分析 计算机视觉 经验分享 网络 tcp/ip 网络协议 神经网络 卷积神经网络 微服务 eureka 负载均衡 嵌入式 redis YOLO 目标检测 udp 语言模型 deepseek DeepSeek-R1 API接口 远程连接 vscode kubernetes 学习方法 程序人生 vue.js spring boot nginx p2p 华为云 华为od gnu 学习 笔记 Linux 维护模式 appium 软件测试 自动化测试 功能测试 Ubuntu DeepSeek DeepSeek Ubuntu DeepSeek 本地部署 DeepSeek 知识库 DeepSeek 私有化知识库 本地部署 DeepSeek DeepSeek 私有化部署 AIGC 人工智能生成内容 jupyter DNS prometheus grafana react.js 前端面试题 node.js 持续部署 springsecurity6 oauth2 授权服务器 前后端分离 yolov5 qt linuxdeployqt 打包部署程序 appimagetool 搜索引擎 程序员 prompt LLM git 远程桌面 chatgpt oneapi 服务器无法访问 ip地址无法访问 无法访问宝塔面板 宝塔面板打不开 excel 在线预览 xlsx xls文件 在浏览器直接打开解析xls表格 前端实现vue3打开excel 文件地址url或接口文档流二进 cursor mcu c语言 kafka ssl django 自然语言处理 Cursor linux环境变量 hadoop 计算机外设 bug notepad 缓存 鸿蒙 arkUI arkTs 鸿蒙系统 1024程序员节 intellij-idea ide visualstudio 性能优化 架构 权限 bash gitee 开源 游戏引擎 ansible nvm jdk 后端 智能体开发 ollama 压力测试 大模型压力测试 EvalScope ipython github Ollama 模型联网 API CherryStudio 数据库系统 系统安全 uni-app rag ragflow 大模型部署 list 数据结构 命令 maxkb ARG svn ArkUI ArkTS 移动端开发 计算机网络 debian 大数据 nohup 异步执行 Ubuntu20.04 GLIBC 2.35 postgresql 图文教程 VMware虚拟机 macOS系统安装教程 macOS最新版 虚拟机安装macOS Sequoia WSL2 IP 地址 策略模式 智能驾驶 BEVFusion Ubuntu spring cloud ffmpeg 视频编解码 pip ui opengl ubuntu20.04 ros ros1 Noetic 20.04 apt 安装 cron crontab日志 工具分享 apache k8s arm 镜像源 gitlab unity 京东云 阿里云 rocketmq Apache Flume 数据采集 安装部署 配置优化 高级功能 大数据工具集成 信息与通信 RTSP xop RTP RTSPServer 推流 视频 交换机 硬件 设备 GPU PCI-Express 回显服务器 UDP的API使用 大模型微调 雨云 NPS 智能路由器 dell服务器 gpu算力 audio vue音乐播放器 vue播放音频文件 Audio音频播放器自定义样式 播放暂停进度条音量调节快进快退 自定义audio覆盖默认样式 远程工作 YOLOv8 NPU Atlas800 A300I pro asi_bench 安全威胁分析 实时音视频 gitea npm rsyslog RAID RAID技术 磁盘 存储 rust腐蚀 tomcat kylin 上传视频文件到服务器 uniApp本地上传视频并预览 uniapp移动端h5网页 uniapp微信小程序上传视频 uniapp app端视频上传 uniapp uview组件库 deepseek-r1 大模型本地部署 电脑 NVML nvidia-smi C 环境变量 进程地址空间 进程 chrome devtools selenium chromedriver mac arm开发 算法 python2 ubuntu24.04 编辑器 vim AI编程 程序员创富 VMware Tools vmware tools安装 vmwaretools安装步骤 vmwaretools安装失败 vmware tool安装步骤 vm tools安装步骤 vm tools安装后不能拖 vmware tools安装步骤 智能手机 burpsuite 安全工具 mac安全工具 burp安装教程 渗透工具 mysql adb elasticsearch 图像处理 grep python3.11 MobaXterm 文件传输 Bug解决 Qt platform OpenCV ragflow 源码启动 pygame php 爬虫 网络爬虫 openssl iftop 网络流量监控 ip协议 框架搭建 gcc centos 7 单例模式 计算生物学 生物信息学 生物信息 基因组 axure 富文本编辑器 golang Alexnet DevOps 软件交付 数据驱动 应用场景 数据安全 devops dash json 正则表达式 qps 高并发 VMware k8s部署 MySQL8.0 高可用集群(1主2从) 腾讯云 vue 防火墙 端口号 开放端口 访问列表 tcpdump 测试工具 go rpa ACL 流量控制 基本ACL 规则配置 IPMI FTP 服务器 升级 CVE-2024-7347 漏洞 mount挂载磁盘 wrong fs type LVM挂载磁盘 Centos7.9 IIS .net core Hosting Bundle .NET Framework vs2022 AutoDL flask xrdp Flask FastAPI Waitress Gunicorn uWSGI Uvicorn 反向代理 IIS服务器 IIS性能 日志监控 typescript IM即时通讯 QQ 微信 企业微信 剪切板对通 HTML FORMAT websocket oracle fusion oracle中间件 虚拟化 ftp服务 文件上传 es6 qt6.3 g726 硬件工程 web microsoft chatbox Agent big data gpt transformer 进程控制 mysql离线安装 ubuntu22.04 mysql8.0 wsl USB转串口 网络结构图 ios 虚拟显示器 远程控制 开机黑屏 vmware 卡死 mysql安装报错 windows拒绝安装 xcode 运维开发 隐藏文件 kotlin android studio iphone 打不开xxx软件 无法检查其是否包含恶意软件 Linux find grep Ubuntu 22.04 MySql 算家云 算力租赁 安装教程 zip unzip openjdk cuda maven Maxkb RAG技术 本地知识库 数据集 visual studio code agi rpc unix C++ CrewAI n8n dity make eclipse 集成学习 集成测试 jenkins vnc 7z dify 知识库 本地化部署 kernel remote-ssh 命名管道 客户端与服务端通信 powerpoint WSL2 上安装 Ubuntu 卸载 软件 列表 milvus Docker Docker Compose Kubernetes DrissionPage llm SRS 流媒体 直播 c# 科技 个人开发 自定义客户端 SAS 课程设计 华为认证 react next.js 部署next.js live555 rtsp rtp 服务器配置 银河麒麟 环境迁移 filezilla 无法连接服务器 连接被服务器拒绝 vsftpd 331/530 file server http server web server WebRTC html5 firefox 毕昇JDK jar 大文件分片上传断点续传及进度条 如何批量上传超大文件并显示进度 axios大文件切片上传详细教 node服务器合并切片 vue3大文件上传报错提示错误 vu大文件秒传跨域报错cors 镜像下载 freebsd Chatbox Qualcomm WoS QNN AppBuilder 安全漏洞 信息安全 华为OD 华为OD机试真题 可以组成网络的服务器 css css3 shell mcp 云计算面试题 私有化 本地部署 安卓 ip mamba Vmamba java-ee 重启 排查 系统重启 日志 原因 Qwen2.5-coder 离线部署 开发环境 jmeter 本地环回 bind 智慧农业 开源鸿蒙 团队开发 .net shell脚本免交互 expect linux免交互 其他 桌面环境 open webui 驱动开发 linux驱动开发 virtualenv iTerm2 diskgenius export env 变量 终端工具 远程工具 IP配置 netplan ollama api ollama外网访问 软件需求 车载系统 设备树 毕设 小程序 进程间通信 冯诺依曼体系 快捷键 旋转屏幕 自动操作 mac设置host 虚拟现实 向量数据库 milvus安装 腾讯云大模型知识引擎 AI-native Docker Desktop 实时互动 大模型面经 大模型学习 目标跟踪 OpenVINO 推理应用 网络药理学 生信 gromacs 分子动力学模拟 MD 动力学模拟 ip命令 新增网卡 新增IP 启动网卡 群晖 低代码 flash-attention 报错 国产数据库 瀚高数据库 数据迁移 下载安装 spring Doris搭建 docker搭建Doris Doris搭建过程 linux搭建Doris Doris搭建详细步骤 Doris部署 compose CPU 使用率 系统监控工具 linux 命令 JDK Java LInux Windows tar ci/cd Claude Desktop Claude MCP Windows Cli MCP pdf xml 计算机学习路线 编程语言选择 系统架构 gru RagFlow RAG 网络攻击模型 Trae IDE AI 原生集成开发环境 Trae AI C语言 SSE fastapi Kylin-Server 国产操作系统 服务器安装 webrtc 阻塞队列 生产者消费者模型 服务器崩坏原因 微信小程序域名配置 微信小程序服务器域名 微信小程序合法域名 小程序配置业务域名 微信小程序需要域名吗 微信小程序添加域名 NAT转发 NAT Server aws UDP ping++ 云电竞 云电脑 todesk AI大模型 大模型入门 大模型教程 LDAP VM搭建win2012 win2012应急响应靶机搭建 攻击者获取服务器权限 上传wakaung病毒 应急响应并溯源 挖矿病毒处置 应急响应综合性靶场 MQTT 消息队列 数据挖掘 知识图谱 opcua opcda KEPServer安装 做raid 装系统 BMC oceanbase rc.local 开机自启 systemd 麒麟 孤岛惊魂4 统信 虚拟机安装 IMM 大模型推理 NAS Termux Samba web3.py 监控 自动化运维 adobe 源码剖析 rtsp实现步骤 流媒体开发 string模拟实现 深拷贝 浅拷贝 经典的string类问题 三个swap 外网访问 内网穿透 端口映射 opensearch helm r语言 数据可视化 游戏程序 三级等保 服务器审计日志备份 triton 模型分析 gaussdb asm 数据库架构 数据管理 数据治理 数据编织 数据虚拟化 串口服务器 Windsurf 像素流送api 像素流送UE4 像素流送卡顿 像素流送并发支持 微信小程序 rustdesk lighttpd安装 Ubuntu配置 Windows安装 性能测试 服务器优化 postman outlook 错误代码2603 无网络连接 2603 numpy 锁屏不生效 昇腾 大模型训练/推理 推理问题 mindie servlet c/s 区块链 密码学 #STC8 #STM32 框架 商用密码产品体系 localhost 交互 匿名FTP 邮件传输代理 SSL支持 chroot监狱技术 GPU状态 远程 harmonyOS面试题 混合开发 环境安装 灵办AI HarmonyOS Next DevEco Studio 软件工程 稳定性 看门狗 设计模式 产品经理 版本 安装 Mac内存不够用怎么办 并查集 leetcode PX4 MAVROS 四旋翼无人机 英语 CosyVoice jellyfin nas perl iot Isaac Sim 虚拟仿真 vmamba wps chromium dpi GPU训练 node 材料工程 vm langchain docker run 数据卷挂载 交互模式 ruoyi 产测工具框架 IMX6ULL 管理框架 perf glibc 政务 分布式系统 监控运维 Prometheus Grafana 虚拟局域网 ue4 着色器 ue5 虚幻 webdav Portainer搭建 Portainer使用 Portainer使用详解 Portainer详解 Portainer portainer sql 指令 dubbo 多线程 kali 共享文件夹 burp suite 抓包 html centos-root /dev/mapper yum clean all df -h / du -sh Linux Vim 安装MySQL 显卡驱动持久化 GPU持久化 docker desktop 镜像 Kali 渗透 RDP risc-v mcp-proxy mcp-inspector fastapi-mcp agent sse 传统数据库升级 银行 多线程服务器 Linux网络编程 王者荣耀 Cline stm32项目 嵌入式实习 华为机试 MS Materials v10 硬件架构 zotero WebDAV 同步失败 代理模式 Invalid Host allowedHosts pillow RustDesk自建服务器 rustdesk服务器 docker rustdesk armbian u-boot 常用命令 文本命令 目录命令 宝塔面板访问不了 宝塔面板网站访问不了 宝塔面板怎么配置网站能访问 宝塔面板配置ip访问 宝塔面板配置域名访问教程 宝塔面板配置教程 intellij idea cpu 实时 使用 springboot ssrf 失效的访问控制 单一职责原则 DeepSeek行业应用 Heroku 网站部署 ecmascript nextjs reactjs unity3d 宝塔面板 同步 备份 建站 Hyper-V WinRM TrustedHosts 大语言模型 LLMs PVE kamailio sip VoIP 直播推流 googlecloud 银河麒麟操作系统 国产化 express 大文件秒传跨域报错cors 测试用例 项目部署到linux服务器 项目部署过程 Dell R750XS 大大通 第三代半导体 碳化硅 高效日志打印 串口通信日志 服务器日志 系统状态监控日志 异常记录日志 弹性计算 云服务器 裸金属服务器 弹性裸金属服务器 grub 版本升级 扩容 rtsp服务器 rtsp server android rtsp服务 安卓rtsp服务器 移动端rtsp服务 大牛直播SDK sqlserver CDN rust llama.cpp 视频平台 录像 视频转发 视频流 录音麦克风权限判断检测 录音功能 录音文件mp3播放 小程序实现录音及播放功能 RecorderManager 解决录音报错播放没声音问题 蓝桥杯 spark hive 信号处理 EtherCAT转Modbus EtherCAT转485网关 ECT转485串口服务器 ECT转Modbus485协议 ECT转Modbus串口网关 ECT转Modbus串口服务器 智能电视 PyQt PySide6 行情服务器 股票交易 速度慢 切换 股票量化接口 股票API接口 智能合约 哈希算法 matlab zabbix mariadb word nvidia HTTP状态码 客户端错误 服务器端错误 API设计 Java进程管理 DevOps自动化 脚本执行 跨平台开发 远程运维 Apache Exec JSch 宠物 毕业设计 免费学习 宠物领养 宠物平台 mongodb deekseek AI写作 MacOS录屏软件 RAGFLOW 检索增强生成 文档解析 大模型垂直应用 sdkman ArcTS 登录 ArcUI GridItem 微信分享 Image wxopensdk GaN HEMT 氮化镓 单粒子烧毁 辐射损伤 辐照效应 Redis Desktop VMware安装mocOS macOS系统安装 ESXi cocoapods protobuf 序列化和反序列化 匿名管道 高级IO epoll openvpn server openvpn配置教程 centos安装openvpn linux内核 matplotlib fonts-noto-cjk QT 5.12.12 QT开发环境 Ubuntu18.04 nohup后台启动 链表 WSL resolv.conf 进程信号 termux 环境搭建 SecureCRT 火绒安全 mybase 创业创新 csrf firewall Github加速 Mac上Github加速 Chrome浏览器插件 js 图论 鲲鹏 npu 开发 onlyoffice 运维监控 Reactor k8s集群资源管理 云原生开发 GPU环境配置 Ubuntu22 CUDA PyTorch Anaconda安装 KVM efficientVIT YOLOv8替换主干网络 TOLOv8 telnet 远程登录 ai小智 语音助手 ai小智配网 ai小智教程 智能硬件 esp32语音助手 diy语音助手 etcd RBAC springcloud seleium 聚类 mq rabbitmq 读写锁 ubuntu 18.04 nftables 大模型技术 本地部署大模型 Ubuntu22.04 开发人员主页 make命令 makefile文件 fstab 宝塔面板无法访问 fiddler rdp 远程服务 全文检索 图搜索算法 工作流 rtc 隐藏目录 文件系统 管理器 通配符 linux子系统 忘记密码 AI提示词优化 企业风控系统 互联网反欺诈 DDoS攻击 SQL注入攻击 恶意软件和病毒攻击 dns MCP server C/S HistoryServer Spark YARN jobhistory 网卡的名称修改 eth0 ens33 EMQX 通信协议 SSH Xterminal VSCode Kylin OS 云服务 vscode1.86 1.86版本 ssh远程连接 ocr HTML audio 控件组件 vue3 audio音乐播放器 Audio标签自定义样式默认 vue3播放音频文件音效音乐 自定义audio播放器样式 播放暂停调整声音大小下载文件 odoo 服务器动作 Server action HCIE 数通 ESP32 服务器繁忙 多个客户端访问 IO多路复用 TCP相关API vSphere vCenter 软件定义数据中心 sddc windwos防火墙 defender防火墙 win防火墙白名单 防火墙白名单效果 防火墙只允许指定应用上网 防火墙允许指定上网其它禁止 Kali Linux 黑客 渗透测试 信息收集 磁盘监控 EtherNet/IP串口网关 EIP转RS485 EIP转Modbus EtherNet/IP网关协议 EIP转RS485网关 EIP串口服务器 nuxt3 中间件 iis 网络编程 聊天服务器 套接字 TCP 客户端 Socket Netty 即时通信 NIO DigitalOcean GPU服务器购买 GPU服务器哪里有 GPU服务器 Unity Dedicated Server Host Client 无头主机 文件分享 银河麒麟高级服务器 外接硬盘 Kylin 雨云服务器 创意 社区 IPMITOOL 硬件管理 算力 游戏服务器 Minecraft 执法记录仪 智能安全帽 smarteye 状态管理的 UDP 服务器 Arduino RTOS mybatis 前端框架 playbook 剧本 VMware创建虚拟机 CPU 主板 电源 网卡 媒体 ECT转Modbus协议 EtherCAT转485协议 ECT转Modbus网关 C# MQTTS 双向认证 emqx docker-compose 笔灵AI AI工具 CNNs 图像分类 HP Anyware asp.net大文件上传 asp.net大文件上传下载 asp.net大文件上传源码 ASP.NET断点续传 gunicorn 跨域请求 券商 股票交易接口api 类型 特点 海康 samba 飞腾处理器 minio 文件存储服务器组件 支持向量机 rsync openEuler finebi 源代码管理 gitee go slave 医疗APP开发 app开发 neo4j 数据仓库 数据库开发 database linux安装配置 捆绑 链接 谷歌浏览器 youtube google gmail 单元测试 系统 黑苹果 飞牛NAS 飞牛OS MacBook Pro 换源 国内源 Debian 中兴光猫 换光猫 网络桥接 自己换光猫 在线office bcompare Beyond Compare fpga开发 多层架构 解耦 cnn threejs 3D Linux的基础指令 SenseVoice conda配置 conda镜像源 safari CentOS Stream CentOS Linux PID Ubuntu共享文件夹 共享目录 Linux共享文件夹 键盘 本地部署AI大模型 c/c++ 串口 系统开发 binder framework 源码环境 okhttp 开机自启动 top Linux top top命令详解 top命令重点 top常用参数 沙盒 iperf3 带宽测试 yum docker compose 进程优先级 调度队列 进程切换 curl wget sublime text 安卓模拟器 MVS 海康威视相机 iNode Macos deep learning 教程 Maven frp 电脑桌面出现linux图标 电脑桌面linux图标删除不了 电脑桌面Liunx图标删不掉 linux图标删不掉 yolov8 动静态库 视觉检测 实时内核 Ardupilot sublime text3 Ubuntu 24 常用命令 Ubuntu 24 Ubuntu vi 异常处理 CUPS 打印机 Qt5 systemctl composer photoshop 接口返回 ranger MySQL8.0 流程图 mermaid PostgreSQL15数据库 SPI 切换root 蓝耘科技 元生代平台工作流 ComfyUI YOLOv12 离线部署dify fd 文件描述符 JAVA 热榜 workflow 环境配置 边缘计算 可信计算技术 安全架构 elk Logstash 日志采集 AnythingLLM AnythingLLM安装 Docker引擎已经停止 Docker无法使用 WSL进度一直是0 镜像加速地址 怎么卸载MySQL MySQL怎么卸载干净 MySQL卸载重新安装教程 MySQL5.7卸载 Linux卸载MySQL8.0 如何卸载MySQL教程 MySQL卸载与安装 minicom 串口调试工具 firewalld 网络用户购物行为分析可视化平台 大数据毕业设计 DenseNet cudnn anaconda docker搭建nacos详解 docker部署nacos docker安装nacos 腾讯云搭建nacos centos7搭建nacos Docker Hub docker pull daemon.json Linux的权限 多进程 虚幻引擎 vr 监控k8s集群 集群内prometheus WebUI DeepSeek V3 miniapp 真机调试 调试 debug 断点 网络API请求调试方法 设置代理 实用教程 监控k8s 监控kubernetes WLAN 文心一言 DBeaver NLP模型 NLP rancher Linux无人智慧超市 LInux多线程服务器 QT项目 LInux项目 单片机项目 思科 tcp ebpf uprobe scikit-learn ROS2 ubuntu安装 linux入门小白 esp32 蓝牙 5G 免密 公钥 私钥 网易邮箱大师 大屏端 分子对接 autodock mgltools PDB PubChem 一切皆文件 健康医疗 trae ICMP LVM 磁盘分区 lvresize 磁盘扩容 pvcreate 论文阅读 物理地址 页表 虚拟地址 磁盘挂载 新盘添加 partedUtil Alist rclone mount 挂载 网盘 命令模式 软考设计师 中级设计师 SQL 软件设计师 智能体 autogen openai coze Qwen3 qwen3 32b vllm Crawlee Playwright 桥接模式 windows虚拟机 虚拟机联网 dns是什么 如何设置电脑dns dns应该如何设置 实验 c AD域 H3C 物联网开发 kind ftp webstorm 个人博客 技术 win11 无法解析服务器的名称或地址 SVN Server tortoise svn vasp安装 LLM Web APP Streamlit kylin v10 麒麟 v10 EasyConnect 微信公众平台 RTMP 应用层 junit echarts 信息可视化 网页设计 ecm bpm 豆瓣 追剧助手 迅雷 HAProxy hibernate 游戏机 pyqt 我的世界 我的世界联机 数码 UOS 统信操作系统 edge浏览器 查询数据库服务IP地址 SQL Server 银河麒麟服务器操作系统 系统激活 VPS ukui 麒麟kylinos openeuler 网工 服务器数据恢复 数据恢复 存储数据恢复 raid5数据恢复 磁盘阵列数据恢复 ux llama3 Chatglm 开源大模型 java-rocketmq 远程看看 远程协助 计算虚拟化 弹性裸金属 联想开天P90Z装win10 崖山数据库 YashanDB 显示管理器 lightdm gdm Java Applet URL操作 服务器建立 Socket编程 网络文件读取 mosquitto DOIT 四博智联 统信UOS bonding 链路聚合 asp.net上传文件夹 asp.net上传大文件 .net core断点续传 gateway Clion Nova ResharperC++引擎 Centos7 远程开发 网络穿透 SWAT 配置文件 服务管理 网络共享 uni-file-picker 拍摄从相册选择 uni.uploadFile H5上传图片 微信小程序上传图片 micropython mqtt 博客 代码调试 ipdb skynet Dell HPE 联想 浪潮 半虚拟化 硬件虚拟化 Hypervisor .netcore 矩阵 GCC aarch64 编译安装 HPC 微信开放平台 微信公众号配置 db KylinV10 麒麟操作系统 Vmware iBMC UltraISO 服务器管理 配置教程 网站管理 上传视频至服务器代码 vue3批量上传多个视频并预览 如何实现将本地视频上传到网页 element plu视频上传 ant design vue vue3本地上传视频及预览移除 Qwen2.5-VL 安防软件 云桌面 微软 AD域控 证书服务器 浏览器自动化 WebServer windows 服务器安装 浪潮信息 AI服务器 蓝桥杯C++组 arcgis 视频监控 网站 内网渗透 靶机渗透 小智 web3 区块链项目 element-ui 上传视频并预览视频 vue上传本地视频及进度条功能 vue2选择视频上传到服务器 upload上传视频组件插件 批量上传视频 限制单个上传视频 pyside6 界面 规格说明书 设计规范 NFS Qt QModbus RK3568 qwen2vl pythonai PlaywrightMCP shard 教育电商 ECS服务器 OpenGL 图形渲染 SoC Claude sse_starlette Starlette Server-Sent Eve 服务器推送事件 wsl2 路径解析 小游戏 五子棋 僵尸进程 执行 sshpass 操作 VMware安装Ubuntu Ubuntu安装k8s 3d 小艺 Pura X alias unalias 别名 命令行 基础入门 模拟器 chrome 浏览器下载 chrome 下载安装 谷歌浏览器下载 kvm Linux24.04 deepin embedding Hive环境搭建 hive3环境 Hive远程模式 xshell termius iterm2 源码 keepalived 分析解读 cmos Ark-TS语言 trea idea AList fnOS 模拟实现 redhat 强制清理 强制删除 mac废纸篓 HiCar CarLife+ CarPlay QT RK3588 基础环境 ArkTs ruby DIFY 软链接 硬链接 Linux权限 权限命令 特殊权限 Reactor反应堆 IO 华为证书 HarmonyOS认证 华为证书考试 工具 多产物 宝塔 HarmonyOS Tabs组件 TabContent TabBar TabsController 导航页签栏 滚动导航栏 用户管理 推荐算法 高德地图 鸿蒙接入高德地图 HarmonyOS5.0 大版本升 升级Ubuntu系统 Office 空间 查错 Xshell macbook hdc 裸机装机 linux磁盘分区 裸机安装linux 裸机安装ubuntu 裸机安装kali 裸机 Obsidian Dataview vsxsrv 管道 miniconda MAC devmem stable diffusion RockyLinux nano jdk11安装 jdk安装 openjdk11 openjdk11安装 影视app 截图 录屏 gif ceph GoogLeNet TRAE ollama下载加速 RAGFlow 本地知识库部署 DeepSeek R1 模型 跨域 eNSP 网络规划 VLAN 企业网络 k8s资源监控 annotations自动化 自动化监控 监控service 监控jvm ShenTong AI代码编辑器 MDK 嵌入式开发工具 论文笔记 linux上传下载 Open WebUI 办公自动化 自动化生成 pdf教程 3GPP 卫星通信 can 线程池 g++ g++13 kerberos pyautogui SSH 密钥生成 SSH 公钥 私钥 生成 DocFlow 拓扑图 P2P HDLC rnn uv linux 命令 sed 命令 自动化任务管理 显卡驱动 searxng ros2 moveit 机器人运动 Cookie 金融 流水线 脚本式流水线 x64 SIGSEGV xmm0 AI Agent 字节智能运维 Xinference lio-sam SLAM 实战案例 log4j proxy模式 双系统 GRUB引导 Linux技巧 飞牛nas fnos CLion docker搭建pg docker搭建pgsql pg授权 postgresql使用 postgresql搭建 主从复制 qemu libvirt 嵌入式系统开发 wireshark 显示过滤器 Wireshark安装 openwrt WebVM cfssl selete import save load 迁移镜像 K8S k8s管理系统 GameFramework HybridCLR Unity编辑器扩展 自动化工具 Mermaid 可视化图表 Apache Beam 批流统一 案例展示 数据分区 容错机制 数学建模 电子信息 通信工程 毕业 ufw ajax 进程程序替换 execl函数 execv函数 execvp函数 execvpe函数 putenv函数 内存管理 考试 相机 postgres Dify重启后重新初始化 kubeless autoware UFW Trae叒更新了? deepseek-v3 ktransformers hosts hosts文件管理工具 开源软件 动态库 GCC编译器 -fPIC -shared 桌面快捷方式 MLLMs VLM gpt-4v 超级终端 多任务操作 提高工作效率 fabric RAGflow 信号 内核 飞书 pppoe radius 远程过程调用 Windows环境 autodl Ubuntu 24.04.1 轻量级服务器 SSL证书 code-server 流式接口 僵尸世界大战 游戏服务器搭建 银河麒麟桌面操作系统 压测 ECS 内网服务器 内网代理 内网通信 TrinityCore 魔兽世界 open Euler dde 音乐服务器 Navidrome 音流 恒源云 bootstrap 深度优先 并集查找 换根法 树上倍增 无桌面 XFS xfs文件系统损坏 I_O error SSL 域名 Spring Security 移动云 windows日志 ISO镜像作为本地源 MNN Qwen vscode 1.86 社交电子 直流充电桩 充电桩 token sas Nuxt.js 服务器部署ai模型 X11 Xming sysctl.conf vm.nr_hugepages mock mock server 模拟服务器 mock服务器 Postman内置变量 Postman随机数据 KingBase cpp-httplib URL 模拟退火算法 nfs 备份SQL Server数据库 数据库备份 傲梅企业备份网络版 ai工具 FunASR ASR 业界资讯 思科模拟器 Cisco 备选 api 调用 示例 能力提升 面试宝典 IT信息化 C++软件实战问题排查经验分享 0xfeeefeee 0xcdcdcdcd 动态库加载失败 程序启动失败 程序运行权限 标准用户权限与管理员权限 大数据平台 致远OA OA服务器 服务器磁盘扩容 加解密 Yakit yaklang netty wsgiref Web 服务器网关接口 SysBench 基准测试 W5500 OLED u8g2 TCP服务器 sqlite3 LORA camera Arduino 网站搭建 serv00 .net mvc断点续传 OD机试真题 服务器能耗统计 田俊楠 语音识别 搭建个人相关服务器 工业4.0 繁忙 解决办法 替代网站 汇总推荐 AI推理 pgpool 存储维护 NetApp存储 EMC存储 欧标 OCPP 智能音箱 智能家居 AD 域管理 迁移指南 AP配网 AK配网 小程序AP配网和AK配网教程 WIFI设备配网小程序UDP开 gradle TrueLicense less visual studio Jellyfin MQTT协议 消息服务器 代码 飞牛 dba 互信 云耀服务器 React Next.js 开源框架 话题通信 服务通信 机柜 1U 2U Web服务器 多线程下载工具 PYTHON 服务器扩容没有扩容成功 clickhouse 硅基流动 ChatBox 服务器部署 本地拉取打包 联机 僵尸毁灭工程 游戏联机 开服 代码规范 zerotier 弹性服务器 nacos deepseak 豆包 KIMI 腾讯元宝 树莓派 显示器 金仓数据库 2025 征文 数据库平替用金仓 金仓数据库概述 金仓数据库的产品优化提案 软件开发 信任链 日志分析 系统取证 AimRT Webserver 异步 技术共享 机架式服务器 1U工控机 国产工控机 计算机系统 web开发 bigdata fpga notepad++ 概率论 考研 accept lua linq 站群服务器 机器人仿真 模拟仿真 openssh 多端开发 智慧分发 应用生态 鸿蒙OS av1 电视盒子 机顶盒ROM 魔百盒刷机 webgl apt crosstool-ng sonoma 自动更新 deepseek r1 玩机技巧 软件分享 软件图标 Ubuntu Server Ubuntu 22.04.5 OpenHarmony EMUI 回退 降级 prometheus数据采集 prometheus数据模型 prometheus特点 Attention Linux awk awk函数 awk结构 awk内置变量 awk参数 awk脚本 awk详解 mm-wiki搭建 linux搭建mm-wiki mm-wiki搭建与使用 mm-wiki使用 mm-wiki详解 交叉编译 Typore 向日葵 历史版本 下载 用户缓冲区 HarmonyOS NEXT 原生鸿蒙 react native 支付 微信支付 开放平台 etl 查看显卡进程 fuser 软件构建 磁盘清理 网络文件系统 cmake 跨平台 Mac软件 AI作画 lvm System V共享内存 进程通信 su sudo sudo原理 su切换 initramfs Linux内核 Grub gpt-3 zookeeper retry 重试机制 玩游戏 llamafactory 微调 rime Echarts图表 折线图 柱状图 异步动态数据 鸿蒙开发 可视化效果 lsb_release /etc/issue /proc/version uname -r 查看ubuntu版本 Charles 可执行程序 对比 meld DiffMerge OpenCore cpolar 终端 需求分析 提示词 系统内核 Linux版本 树莓派项目 多路转接 进程池实现 Bluetooth 配对 direct12 mac安装软件 mac卸载软件 mac book mac cocoapods macos cocoapods Mac部署 Ollama模型 Openwebui 配置教程 AI模型 brew 编译 烧录 uni-app x 文件清理 开发工具 技能大赛 IMX317 MIPI H265 VCU IO模型 深度求索 私域 企业网络规划 华为eNSP ubuntu24.04.1 互联网医院 实习 线程 RoboVLM 通用机器人策略 VLA设计哲学 vlm fot robot 视觉语言动作模型 ssh远程登录 xpath定位元素 IPv4 子网掩码 公网IP 私有IP 浏览器开发 AI浏览器 openstack Xen OpenSSH seatunnel ubuntu24 vivado24 yum源切换 更换国内yum源 序列化反序列化 PPI String Cytoscape CytoHubba docker部署翻译组件 docker部署deepl docker搭建deepl java对接deepl 翻译组件使用 自动化编程 计算机 springboot远程调试 java项目远程debug docker远程debug java项目远程调试 springboot远程 增强现实 沉浸式体验 技术实现 案例分析 AR bat 软负载 端口 查看 ss Node-Red 编程工具 流编程 easyui 网络建设与运维 网络搭建 神州数码 神州数码云平台 云平台 免费域名 域名解析 OpenManus 容器技术 输入法 性能调优 安全代理 DeepSeek r1 端口聚合 windows11 image copilot lb 协议 图片增强 增强数据 scapy Helm k8s集群 生活 Docker快速入门 netlink libnl3 软件卸载 系统清理 ShapeFile GeoJSON Nginx 底层实现 VGG网络 卷积层 池化层 WireGuard 异地组网 SystemV 计算机科学与技术 IPv6 IPv6测试 IPv6测速 IPv6检测 IPv6查询 EVE-NG GRE IPv4/IPv6双栈 双栈技术 网路规划设计 ensp综合实验 IPv4过渡IPv6 IPv4与IPv6 post.io 企业邮箱 搭建邮箱 pthread 静态IP client-go k8s二次开发 源代码 Masshunter 质谱采集分析软件 使用教程 科研软件 VM虚拟机 android-studio 轮播图 LLaMA-Factory isaacgym python高级编程 Ansible elk stack Linux指令 Radius 高效远程协作 TrustViewer体验 跨设备操作便利 智能远程控制 laravel CORS 根服务器 es Wi-Fi h.264 黑客技术 AI agent iDRAC R720xd ldap 内网环境 jetty undertow 相差8小时 UTC 时间 qt项目 qt项目实战 qt教程 muduo MI300x uniapp HTTP 服务器控制 ESP32 DeepSeek thingsboard tailscale derp derper 中转 Anolis nginx安装 linux插件下载 游戏开发 架构与原理 vue-i18n 国际化多语言 vue2中英文切换详细教程 如何动态加载i18n语言包 把语言json放到服务器调用 前端调用api获取语言配置文件 温湿度数据上传到服务器 Arduino HTTP 服务器主板 AI芯片 我的世界服务器搭建 minecraft XCC Lenovo idm 北亚数据恢复 oracle数据恢复 VNC 域名服务 DHCP 符号链接 配置 VS Code 小智AI服务端 xiaozhi TTS wordpress 无法访问wordpess后台 打开网站页面错乱 linux宝塔面板 wordpress更换服务器 阿里云ECS 信创 信创终端 中科方德 win服务器架设 windows server 超融合 UOS1070e 小番茄C盘清理 便捷易用C盘清理工具 小番茄C盘清理的优势尽显何处? 教你深度体验小番茄C盘清理 C盘变红?!不知所措? C盘瘦身后电脑会发生什么变化? saltstack 代码托管服务 nosql AI员工 banner powerbi Web应用服务器 影刀 授时服务 北斗授时 NFC 近场通讯 智能门锁 联网 easyconnect 代理 Pyppeteer 动态规划 glm4 负载测试 高效I/O VPN wireguard 充电桩平台 充电桩开源平台 umeditor粘贴word ueditor粘贴word ueditor复制word ueditor上传word图片 ueditor导入word ueditor导入pdf ueditor导入ppt 免费 电路仿真 multisim 硬件工程师 硬件工程师学习 电路图 电路分析 仪器仪表 分布式账本 共识算法 Python 视频爬取教程 Python 视频爬取 Python 视频教程 vCenter服务器 ESXi主机 监控与管理 故障排除 日志记录 paddle AWS Putty 花生壳 百度云 矩池云 数据下载 数据传输 pxe LVS issue socket 热键 机架式 IDC 性能监控 MateBook 粘包问题 语法 VR手套 数据手套 动捕手套 动捕数据手套 sequoiaDB navicat 移动开发 元服务 应用上架 邮件APP 免费软件 嵌入式Linux IPC 合成模型 扩散模型 图像生成 代理服务器 MacOS vpn 搜狗输入法 中文输入法 fork wait waitpid exit ELF加载 csrutil mac恢复模式进入方法 SIP 恢复模式 xfce archlinux kde plasma wpf pyicu beautifulsoup 子系统 星河版 鸿蒙NEXT NVM Node Yarn PM2 comfyui comfyui教程 华为鸿蒙系统 ArkTS语言 Component 生命周期 条件渲染 Image图片组件 STL mvc harmonyosnext 导航栏 顽固图标 启动台 wifi驱动 GKI KMI 互联网实用编程指南 AppLinking 应用间跳转 苹果电脑装windows系统 mac安装windows系统 mac装双系统 macbook安装win10双 mac安装win10双系统 苹果电脑上安装双系统 mac air安装win yum换源 基础指令 libreoffice word转pdf charles C/C++ clipboard 剪贴板 剪贴板增强 泰山派 根文件系统 figma #影刀RPA# nac 802.1 portal SSH 服务 SSH Server OpenSSH Server jina yaml Ultralytics 可视化 fast Python基础 Python技巧 cd 目录切换 TCP协议 USB网络共享 bot docker命令大全 docker部署Python 抗锯齿 dock 加速 项目部署 deployment daemonset statefulset cronjob 钉钉 自学笔记 小米 澎湃OS Android 解决方案 接口优化 Sealos virtualbox 电视剧收视率分析与可视化平台 网页服务器 web服务器 qt5 客户端开发 Zoertier 内网组网 GeneCards OMIM TTD 机械臂 脚本 solr 可用性测试 Linux的基础开发工具 easyTier 组网 线程同步 线程互斥 条件变量 d3d12 anythingllm open-webui docker国内镜像 finalsheel MinIO 红黑树封装map和set LSTM 集成 scrapy 5分钟快速学 docker入门 代理配置 企业级DevOps openresty 转换 服务注册与发现 nacos容器环境变量 docker启动nacos参数 nacos镜像下载 工作流自动化工具 bushujiaocheng 部署教程 AI算力 租算力 到算家云 dify部署 lvs 多媒体 BitTorrent 搜索 GIS 遥感 WebGIS 服务器时间 Headless Linux SEO 国标28181 监控接入 语音广播 流程 SDP 聊天室 带外管理 宕机切换 服务器宕机 sqlite swoole Erlang OTP gen_server 热代码交换 事务语义 xss AISphereButler hugo sentinel 干货分享 黑客工具 密码爆破 流量运营 磁盘镜像 服务器镜像 服务器实时复制 实时文件备份 分布式训练 midjourney chfs ubuntu 16.04 IDEA tidb ABAP 状态模式 音乐库 端口测试 服务器正确解析请求体 数字证书 签署证书 Carla 服务器ssl异常解决 配置原理 solidworks安装 7-zip java-zookeeper 三次握手 logstash OpenManage pyscenic 生信教程 能源 rtcp CPU架构 服务器cpu h.265 腾讯云服务器 轻量应用服务器 linux系统入门 linux命令 anonymous vue在线预览excel和编辑 vue2打开解析xls电子表格 浏览器新开页签或弹框内加载预览 文件url地址或接口二进制文档 解决网页打不开白屏报错问题 静态NAT 分布式数据库 集中式数据库 业务需求 选型误 5090 显卡 AI性能 科勘海洋 数据采集浮标 浮标数据采集模块 Svelte OpenAI 全栈 aiohttp asyncio 移动魔百盒 服务网格 istio regedit 开机启动 Linux环境 ArtTS whistle 极限编程 NVIDIA 欧拉系统 数据库管理 swift Bandizip Mac解压 Mac压缩 压缩菜单 端口开放 IP地址 计算机基础 function address 函数 地址 broadcom MySQL ps命令 手动分区 chrome历史版本下载 chrominum下载 时间轮 flink 进程等待 内存泄漏 路径规划 环境部署 嵌入式实时数据库 gstreamer 文档 烟花代码 烟花 元旦 问题解决 抓包工具 达梦 DM8 集群管理 输入系统 AzureDataStudio webview watchtower 医院门诊管理系统 Modbus TCP mapreduce 4 - 分布式通信、分布式张量 代码复审 文件共享 springboot容器部署 springboot容器化部署 微服务容器化负载均衡配置 微服务容器多节点部署 微服务多节点部署配置负载均衡 BCLinux 通用环境搭建 dockerfile 共享 设置 影刀证书 分享 线程安全 电脑操作 podman registries lstm LSTM-SVM 时间序列预测 HBase分布式集群 HBase环境搭建 HBase安装 HBase完全分布式环境 根目录 线性代数 电商平台 佛山戴尔服务器维修 佛山三水服务器维修 Unity插件 ardunio BLE hexo 西门子PLC 通讯 mcp服务器 client close WINCC 程序化交易 量化交易 高频交易 massa sui aptos sei lrzsz caddy 火山引擎 cocos2d 3dcoat PTrade QMT 量化股票 aac mcp协议 go-zero 工厂方法模式 自定义登录信息展示 motd 美化登录 openvino 制造 动态域名 惠普服务器 惠普ML310e Gen8 惠普ML310e Gen8V2 风扇散热策略 曙光 海光 宁畅 中科可控 RNG 状态 可复现性 随机数生成 光电器件 LED 大厂程序员 硅基计算 碳基计算 认知计算 生物计算 AGI 系统架构设计 软件哲学 程序员实现财富自由 gitlab服务器 Cache Aside Read/Write Write Behind 分类 proto actor actor model Actor 模型 模块测试 bug定位 缺陷管理 雾锁王国 风扇控制软件 macOS win向maOS迁移数据 GRANT REVOKE qtcreator bert java毕业设计 微信小程序医院预约挂号 医院预约 医院预约挂号 小程序挂号 OS 软件商店 livecd systemtools 实时日志 logs NTP服务器 orbslam2 ANDROID_HOME zshrc 自定义shell当中管道的实现 匿名和命名管道 latex 更换镜像源 红黑树 pipe函数 管道的大小 匿名管道的四种情况 本地不受DeepSeek CodeBuddy首席试玩官 Linux的进程概念 cuda驱动 Navigation 路由跳转 鸿蒙官方推荐方式 鸿蒙原生开发 Python学习 Python编程 亲测 linux/cmake 鸿蒙面试 面试题 容器清理 大文件清理 空间清理 数码相机 全景相机 设备选择 实用技巧 数字空间 tftp homebrew windows转mac ssh密匙 Mac配brew环境变量 李心怡 零售 docker search 知行EDI 电子数据交换 知行之桥 EDI homeassistant 智能问答 Spring AI Milvus 漏洞报告生成 定义 核心特点 优缺点 适用场景 web环境 学习路线 烟雾检测 yolo检测 消防检测 Web3 Telegram GPUGEEK tar.gz tar.xz linux压缩 基本指令 模板 高可用 恒玄BES 仓库 软路由 Linux系统编程 写时拷贝 Linux的进程调度队列 活动队列 sql注入 生成对抗网络 文件权限 proxy_pass yashandb 网络原理 网络库 泛型编程 Async注解 实时云渲染 云渲染 3D推流 环境 非root vmware tools 站群 多IP 证书 签名 MCP 服务器 JADX-AI 插件 排序算法 选择排序 jQuery 物理服务器 服务器租用 云服务器租用 物理机租用 网络接口 时间间隔 所有接口 多网口 电子信息工程 事件分析 边缘服务器 利旧 AI识别 DELL R730XD维修 全国服务器故障维修 客户端-服务器架构 点对点网络 服务协议 网络虚拟化 网络安全防御 零日漏洞 CVE 独立服务器 linux cpu负载异常 raid eventfd 高性能 万物互联 工业自动化 工厂改造 LangGraph 模型上下文协议 MultiServerMCPC load_mcp_tools load_mcp_prompt 若依 内存不足 outofmemory Key exchange 主包过大 Windows 11 重装电脑系统 Metastore Catalog mujoco Ubuntu 24.04 搜狗输入法闪屏 Ubuntu中文输入法 能效分析 nginx默认共享目录 ubantu 青少年编程 迁移 IT 护眼模式 重置密码 dnf gerrit codereview code-review 系统完整性 越狱设备 三维重建 FS bootfs rootfs linux目录 Linux的进程控制 C++11 lambda Makefile VUE Mysql PATH 命令行参数 main的三个参数 linux常用命令 激光雷达 镭眸 机床 仿真 课件 教学 课程 汽车 九天画芯 铁电液晶 显示技术 液晶产业 技术超越 软硬链接 文件 NVIDIA显卡安装 Ubuntu开机黑屏 CAD瓦片化 栅格瓦片 矢量瓦片 Web可视化 DWG解析 金字塔模型 Multi-Agent 蜂窝网络 频率复用 射频单元 无线协议接口RAN 主同步信号PSS 手机 nmcli 网络配置 containerd 访问公司内网 安全性测试 微信自动化工具 微信消息定时发送 Jenkins流水线 声明式流水线 回归 原子操作 AXI 电子器件 二极管 三极管 rxjava 量子计算 STP 生成树协议 PVST RSTP MSTP 防环路 网络基础 docker安装mysql win下载mysql镜像 mysql基本操作 docker登陆私仓 docker容器 deepseek与mysql Playwright MCP 多系统 muduo库 自动化测试框架 Typescript Apache OpenNLP 句子检测 分词 词性标注 核心指代解析 华为昇腾910b3 authing 事件驱动 access blocked 破解 流量 janus rtmp http状态码 请求协议 asp.net EF Core 客户端与服务器评估 查询优化 数据传输对象 查询对象模式 A2A 实时传输 服务器托管 云托管 数据中心 idc机房 AI导航站 网络IO 队列 数据库占用空间 视频服务器 过期连接 teamspeak 进程管理 Modbustcp服务器 Lenovo System X GNOME Scoket SFTP CTE AGE Windows应急响应 应急响应 webshell 网络攻击防御 网络攻击 octomap_server Windows Hello 摄像头 指纹 生物识别 bpf bpfjit pcap vr看房 在线看房系统 房产营销 房产经济 三维空间 GenAI LLM 推理优化 LLM serving react Native 学习笔记 二级页表 tvm安装 深度学习编译器 杂质 数字比特流 模拟信号 将二进制数据映射到模拟波形上 频谱资源 振幅频率相位 载波高频正弦波 容器化 Serverless MobileNetV3 深度强化学习 深度Q网络 Q_Learning 经验回收 笔记本电脑 Arduino下载开发板 esp32开发板 esp32-s3 dsp开发 pow 指数函数 优化 Autoware 辅助驾驶 AOD-PONO-Net 图像去雾技术 NAT 软件安装 权限掩码 粘滞位 ICMPv6 CAN 多总线 network NetworkManager 电子学会 仙盟大衍灵机 东方仙盟 仙盟创梦IDE usb typec 触觉传感器 GelSight GelSightMini GelSight触觉传感器 地平线5 低成本 网络带宽 问题排查 OSB Oracle中间件 SOA RHEL 去中心化 相机标定 鼠标 磁盘IO iostat 服务发现 Featurize Mobilenet 分割 信创国产化 达梦数据库 pikachu靶场 XSS漏洞 XSS DOM型XSS FreeRTOS 高考 麒麟OS MQTT Broker GMQT CLI JavaScript langgraph.json debezium 数据变更 android-ndk Unlocker illustrator 分布式总线 命令键 包装类 MinerU Agentic Web NLWeb 自然语言网络 微软build大会 记账软件 容器部署 unionFS OverlayFS OCI docker架构 写时复制 编程与数学 开启黑屏 nvidia驱动 Tesla显卡 tty2 客户端/服务器架构 分布式应用 三层架构 Web应用 跨平台兼容性 药品管理 百度 messages dmesg coffeescript English 冯诺依曼体系结构 Quixel Fab UE5 游戏商城 编译器 udp回显服务器 elementui 若依框架 CKEditor5 桶装水小程序 在线下单送水小程序源码 桶装水送货上门小程序 送水小程序 订水线上商城 webgis cesium 服务 Make SFTP服务端 报警主机 豪恩 VISTA120 乐可利 霍尼韦尔 枫叶 时刻 dfs js逆向 矩阵乘法 3D深度学习 blender three.js 数字孪生 HarmonyOS SDK Map Kit 地图