最新资讯

  • Rockchip RK3588 - Rockchip Linux SDK编译

Rockchip RK3588 - Rockchip Linux SDK编译

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

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

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