4.4.4. 系统小型化裁剪
4.4.4.1. 概述
在嵌入式系统开发过程中,系统裁剪旨在去除不必要的功能和文件,以减少对系统资源(如存储、内存和 CPU)的占用,并提升整体性能。通过对系统各个组成部分进行优化和调整,裁剪过程去除了冗余组件,保留了必需的功能,从而确保系统能够更好地适应特定硬件平台和应用需求。
4.4.4.2. 系统裁剪简介
系统裁剪的主要目的是优化存储占用、降低功耗、提升性能,并减少内存占用。这不仅能有效节省存储空间,以适应资源有限的嵌入式设备,还能提高系统启动速度和响应效率,减少资源浪费。
减小存储占用:通过裁剪不必要的功能和模块,减少文件系统、内核、启动程序等占用的存储空间,适应资源受限的硬件环境。
提高启动速度:精简后的系统在启动时能够加载更少的模块,启动过程更加高效。
提升系统性能:去除不必要的功能和驱动,减少内存占用,提升系统响应速度和稳定性。
定制化系统:根据实际需求定制系统组件,实现精细化控制,增强系统的可维护性和可扩展性。
当前系统主要镜像有 uboot、 kernel、 rootfs 等,它们的大小根据 系统分区表 可以获取到:
| 镜像 | 大小 |
|---|---|
| uboot | 2M |
| kernel | 12M |
| rootfs | 250M |
可以看出,在系统镜像中, uboot、 kernel 和 rootfs 的体积呈现出递增的趋势。相较于小尺寸的组件,大尺寸组件的裁剪能够带来更显著的体积缩减效果。例如,对 rootfs 进行 1MB 的裁剪可能相对容易,但要实现相同幅度的裁剪在 uboot 上则要困难得多。 因此,系统裁剪的工作重点应当放在 kernel 和 rootfs 上,这两个部分的优化将对整体系统的大小产生决定性的影响。
4.4.4.3. 系统裁剪方式
uboot 裁剪
uboot 是嵌入式设备中的引导加载程序,其主要功能是启动设备、加载内核和初始化硬件。在进行 uboot 裁剪时,主要目标是精简 uboot 的代码,删除与硬件平台无关的模块和功能。
本平台中 uboot 配置文件是 uboot/configs/hobot_x5_soc_defconfig,可以使用如下命令进行 uboot 的选项配置:
./bd.sh uboot menuconfig
该命令会自动使用板级配置文件中设置的 uboot 配置文件,在配置完成后,自动完成 savedefconfig 和保存工作。该命令详细说明可以参考 配置 Uboot 选项参数 章节。
命令执行成功后会打开 uboot 图形化配置界面,此时可以在这个交互界面下完成选项的配置:

在这个界面,即可根据需求禁用不需要的功能或者命令,以减小 uboot 镜像的大小。
禁用不需要的命令
例如,如果不需要
memtest命令,可以禁用该命令,在 menuconfig 界面取消选中即可:
禁用文件系统支持
如果不需要支持某些文件系统(如 FAT、 ext4 等),可以通过取消相关定义来禁用。例如,禁用 FAT 文件系统支持:

禁用不需要的硬件驱动
如果不需要 I2C 设备支持,可以禁用 I2C 驱动,在 menuconfig 界面取消选中
I2C support即可:
在 menuconfig 的配置界面上完成配置后,选择 Exit 退出,根据提示选择 Yes 保存修改到 .config 文件 (本平台会保存到 uboot/configs/hobot_x5_auto_defconfig 文件)中。
修改完配置项后,需要清理旧的构建文件,并重新编译 uboot 镜像:
# 清理旧的编译文件
./bd.sh uboot clean
# 重新编译
./bd.sh uboot
Linux 内核裁剪
Linux 内核是嵌入式系统的核心,裁剪的目标是根据需求,移除不必要的驱动程序、功能以及文件系统支持,以降低内核的体积和资源消耗,从而得到一个精简高效的 Linux 系统。
通常关于 Linux 内核裁剪主要有如下方法:
删除不使用的功能。如符号表、打印、调试等功能。
删除不使用的驱动。
修改内核源代码。
禁用内核功能、驱动
与 uboot 配置过程类似,本平台提供了相关命令进行 Kernel 的选项配置:
./bd.sh boot menuconfig
该命令详细说明可以参考 配置 Kernel 选项参数 章节。命令执行成功后会打开 Kernel 图形化配置界面,可以在这个交互界面下完成选项的配置,删除不需要的功能模块:

在 Linux 内核 menuconfig 界面中删除不需要的功能或者驱动的操作过程与 uboot 配置相同。内核裁剪的关键在于准确识别哪些部分可以删除,以避免影响系统的正常功能。在 menuconfig 配置界面完成设置后,选择 Exit 退出,并根据提示选择 Yes 保存修改到 .config 文件中(本平台一般使用的是 kernel/arch/arm64/configs/hobot_x5_soc_defconfig)。
修改内核源代码
内核源码庞大,直接修改往往难度很大,可借助相关工具来评估模块以及符号的大小,然后进行针对性的裁剪。
可以使用如下命令显示 vmlinux 文件中的符号信息,vmlinux 文件位于 out/build/kernel 下:
nm --size vmlinux | sort -k 2 -n -r
命令解释:
nm --size vmlinux:列出vmlinux文件中的符号信息,并显示每个符号的大小(以字节为单位)。sort -k 2 -n -r:-k 2:按照第二列(即符号的大小列)进行排序。-n:以数值大小排序,而不是按字典顺序。-r:按降序排序,即从大到小。
截取得到的部分日志如下:
out/build/kernel$ nm --size vmlinux | sort -k 2 -n -r
0000000000200000 b _buf_log_main
0000000000058000 d _printk_rb_static_infos
0000000000040000 b _buf_log_system
0000000000040000 b _buf_log_radio
0000000000040000 b _buf_log_events
0000000000020000 b __log_buf
0000000000018000 d _printk_rb_static_descs
00000000000082f8 b ipc_shm_data
0000000000006000 b memblock_memory_init_regions
0000000000004020 B hstates
0000000000003e14 T hidinput_connect
0000000000003b88 r edid_cea_modes_1
00000000000039c0 R v4l2_dv_timings_presets
0000000000003740 r alg_test_descs
00000000000035c0 r orientation_data
0000000000003480 r wm8962_dapm_widgets
00000000000033b4 T ZSTD_compressBlock_doubleFast_dictMatchState
0000000000002fa8 t allowlist
日志解读:
每一行包含了以下信息:
地址(如
0000000000200000):该符号在vmlinux中的地址。大小(如
b,d,t,T,r等符号类型后面的数值):表示符号所占的字节数。符号类型(如
T,b,d等):表示符号的类型。符号名(如
_buf_log_main,_printk_rb_static_infos等):符号的名称。
例如:
0000000000200000 b _buf_log_main
0000000000058000 d _printk_rb_static_infos
在这个输出中:
_buf_log_main的大小为0x200000(即 2MB),并且它是一个 BSS 段的符号(b表示 BSS)。_printk_rb_static_infos的大小为0x58000(即 348KB),并且它是一个数据段的符号(d表示数据)。
符号类型介绍:
T:表示符号是一个函数并且位于文本(代码)段中。t:表示符号是一个局部函数,位于文本段中。D:表示符号是一个数据段变量。d:表示符号是一个局部数据变量。b:表示符号是一个 BSS 段变量(未初始化数据)。r:表示符号是只读数据。R:表示符号是只读数据,且其地址是由链接器在加载时填充的。W:表示符号是一个弱符号。
根据符号类型可以初步判断哪些内容是可以删除的:
BSS 段 (
b):这部分的符号表示未初始化的静态变量,这些符号可能占用空间,但它们通常是可以裁剪的。如果这些符号对应的变量没有被使用,就可以考虑删除或优化。数据段 (
d):这部分的符号表示已初始化的全局变量,需要确认是否所有的全局变量都被需要,没有使用的全局变量可以裁剪。只读数据段 (
r或R):表示只读的全局变量,通常是库函数中的常量数据。这些数据中对于没有被使用的部分是可以被优化的。文本段 (
T或t):这部分的符号表示函数代码。如果某些函数不被使用或只有在特定条件下才被调用,可以是裁剪的候选。特别是局部函数(t)可以分析后确认是否被优化或者从内核配置中禁用。弱符号 (
W):这类符号是弱符号,通常是可选的或不太重要的。可以考虑裁剪。
可以优先聚焦在那些非常大的符号上,尤其是那些占用数十 KB 或更多内存的符号。确认它是否真的需要,如果不需要,就将其裁剪掉,这样可以节省较多的空间。
其他裁剪方向
去除调试信息 如果目标是生产环境,可以通过禁用调试符号和信息来减少内核镜像的大小。 可以在 menuconfig 中禁用以下选项:
CONFIG_DEBUG_INFO=n # 禁用调试信息 CONFIG_DEBUG_KERNEL=n # 禁用内核调试
根文件系统裁剪
本平台的根文件系统是通过 buildroot 来制作的,详细过程可以参考 使用 Buildroot 制作根文件系统 章节。
文件系统裁剪的主要思路是删、换、压:
删:删除不需要的内容。如帮助文档、没用到的库、调试程序等。
换:使用小尺寸的实现替换大尺寸的实现。如使用 musl libc 库替换 glibc 库等。
压:使用合适的压缩算法。
应用程序及冗余文件裁剪:
在不影响整体功能的情况下,一些应用程序或冗余文件往往可以删除:
调试工具:比如 tcpdump、 mpstat、 strace 等等。
性能测试工具:比如 lmbench、 sysstat、 tiobench 等等。
冗余文件:帮助文档、辅助程序、配置文件和数据模块等,又比如很多应用有相同的功能,只留其一。
采用具有通用功能的替代软件包。 Linux 上有许多具有相似功能的软件包,可以选择其中占存储空间较小的软件包并移植到嵌入式设备上。
资源文件:一些音视频以及 UI 资源往往占用很大空间,如果没有用到,也需要删除。
关于库的裁剪:
使用较小的 C 库,如 musl libc, uclibc 等来替换 glibc。
删除没有用到的库。
可以在 system/buildroot/source 目录下执行执行下面命令删除不需要的应用以及库:
./build.sh menuconfig x5_system_defconfig
进入 menuconfig 界面进行配置:

根文件系统中所有的应用包都在 target packages 目录下,可以根据需求进行修改。比如,禁用 ffmpeg 应用包,就可以在该目录下取消选中 ffmpeg 配置项:

在 menuconfig 配置界面完成设置后,选择 Exit 退出,并根据提示选择 Yes 保存修改到 .config 文件(本平台是 system/buildroot/source/configs/x5_system_defconfig)中。
接着,先清理先前的内容,并重新执行编译命令:
cd system/buildroot/source
./build.sh clean x5_system_defconfig
./build.sh build x5_system_defconfig 0.0.1
另外,strip 会去掉应用程序与库的符号信息和调试信息,大大减少空间占用。本平台默认开启了 buildroot 的 strip 配置项:

该配置项将使用 strip 命令删除目标文件系统中的二进制文件和库,这主要是通过删除调试符号来节省空间,本机调试需要目标上的调试符号,但使用远程调试时则不需要。
4.4.4.4. 系统裁剪的基本原则
在进行系统裁剪的过程中,为了确保裁剪后系统能够正常工作并满足性能和资源要求,需要遵循以下原则:
按需求裁剪
明确目标:裁剪应根据实际应用需求来进行。不要盲目裁剪,首先需要清楚系 需要支持哪些功能、模块和硬件。裁剪的目的是为了适应特定的硬件平台和应用场景, 不是单纯地减小系统体积。
最小化功能集:根据使用场景只保留必要的功能和服务,避免裁剪过多,导致系统无法提供预期功能。
逐步裁剪
分阶段进行:裁剪过程应分阶段进行,从最不重要的模块开始,逐步移除不必要的功能。在每一阶段,进行测试和验证,确保系统的稳定性和功能完整性。
保留核心功能:始终确保系统的基本功能不受影响。例如,内核裁剪时,要特别注意保留对硬件的基本支持,特别是设备驱动和文件系统支持。
安全性和稳定性优先
避免破坏性裁剪:裁剪时不要移除或禁用系统的核心功能,如内核调度、内存管理、硬件抽象层 (HAL) 等。过度裁剪可能会导致系统不稳定,甚至无法启动。
充分测试:每次裁剪后,都应对系统进行全面的功能验证,尤其是对硬件和网络等关键模块的测试。确保不会引入安全漏洞或导致系统崩溃。
最小化依赖
去除冗余依赖:裁剪时应尽量减少对不必要的库和工具的依赖,特别是在 Buildroot 和根文件系统的裁剪中。移除不需要的依赖项,避免增加不必要的库文件和二进制文件。
使用轻量级替代品:例如,用 BusyBox 替代多个常规工具集,选择更小的、资源占用更低的库和工具,以减小根文件系统的体积。
合理管理内核配置
精简内核配置:在内核裁剪过程中,应根据目标硬件精简内核配置。删除不必要的驱动程序、文件系统支持和调试功能,避免加载不需要的模块。
模块化管理:内核模块应该只在需要时加载,减少不必要的内核模块或驱动,这不仅有助于减少内核的体积,还可以优化系统性能。
高效管理存储和内存
优化存储占用:裁剪时应重点关注存储的优化,特别是嵌入式设备存储有限的情况下,尽量减少文件系统 内核镜像和 Uboot 文件的大小。
内存占用优化:减少不必要的内存占用,尤其是在 RAM 限制较大的设备上。通过移除不必要的服务、程序和驱动,可以有效提高内存利用率。
模块化与可扩展性
保持模块化设计:尽量保留系统的模块化特性,即使进行裁剪,也应确保系统可以在需要时灵活地加载模块,而不是直接将所有功能集成到系统中。
可扩展性:在裁剪过程中,不要限制未来的扩展能力。确保裁剪的部分能够轻松地被重新加入到系统中,以便后续的功能扩展。
遵循工具链和标准
使用标准工具链:裁剪过程中应使用一致的工具链和配置工具(如 Uboot 的
make menuconfig、 Kernel 的make menuconfig或 Buildroot 的配置工具)进行操作。这些工具链已经经过优化和广泛使用,能够帮助确保裁剪的系统在目标平台上正常工作。文档化裁剪过程:对于每一次裁剪的决策和步骤,应进行详细记录。这样可以帮助后续人员理解裁剪的目的、方法和实现,便于管理和后期修改。
性能与功耗平衡
优化性能:裁剪不仅是为了减小体积,还应兼顾性能优化。可以通过移除不必要的功能和配置来提高系统性能。
考虑功耗:在嵌入式系统中,功耗往往是设计中的重要考虑因素。裁剪时,可以优先选择低功耗的硬件支持和软件功能,优化系统的功耗表现。
保持向后兼容性
避免破坏兼容性:特别是在内核裁剪和 Uboot 裁剪时,要确保与原先系统兼容。移除某些模块时,注意不要影响现有的硬件支持和系统接口,以便后续的更新和维护不至于引入不必要的问题。
4.4.4.5. 系统裁剪实例
由于 NAND 容量有限,在实际使用中可以根据场景对 NAND 的 Kernel、 system、 hbre 等进行剪裁。以下提供了适用于 BSP 包的 Kernel 和 System 最小配置。只需将这些配置项替换到相应的配置文件中,完成系统裁剪,重新编译后,便可生成最小系统镜像。
system 最小配置
如下是 system 的最小配置:
BR2_aarch64=y
BR2_cortex_a55=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX="aarch64-none-linux-gnu"
BR2_TOOLCHAIN_EXTERNAL_GCC_11=y
BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_20=y
BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC=y
# BR2_TOOLCHAIN_EXTERNAL_INET_RPC is not set
BR2_TOOLCHAIN_EXTERNAL_CXX=y
BR2_CCACHE=y
# BR2_PIC_PIE is not set
BR2_SSP_NONE=y
BR2_RELRO_NONE=y
BR2_FORTIFY_SOURCE_NONE=y
BR2_INIT_SYSV=y
BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
BR2_ROOTFS_MERGED_USR=y
BR2_TARGET_GENERIC_ROOT_PASSWD="root"
BR2_SYSTEM_BIN_SH_BASH=y
BR2_SYSTEM_DEFAULT_PATH="/bin:/sbin:/usr/bin:/usr/sbin"
BR2_PACKAGE_FFMPEG=y
BR2_PACKAGE_FFMPEG_ENCODERS=""
BR2_PACKAGE_FFMPEG_DECODERS=""
BR2_PACKAGE_FFMPEG_MUXERS=""
BR2_PACKAGE_FFMPEG_DEMUXERS=""
BR2_PACKAGE_FFMPEG_PARSERS=""
BR2_PACKAGE_FFMPEG_BSFS=""
BR2_PACKAGE_FFMPEG_PROTOCOLS=""
BR2_PACKAGE_FFMPEG_FILTERS=""
# BR2_PACKAGE_FFMPEG_INDEVS is not set
# BR2_PACKAGE_FFMPEG_OUTDEVS is not set
BR2_PACKAGE_FFMPEG_EXTRACONF=" --disable-everything --enable-gray --enable-safe-bitstream-reader --enable-encoder=adpcm_g726le --enable-encoder=flac --enable-encoder=pcm_alaw --enable-encoder=pcm_mulaw --enable-encoder=adpcm_ima_wav --enable-encoder=srt --enable-encoder=subrip --enable-encoder=text --enable-encoder=movtext --enable-encoder=ass --enable-decoder=adpcm_g726le --enable-decoder=flac --enable-decoder=pcm_alaw --enable-decoder=pcm_mulaw --enable-decoder=adpcm_ima_wav --enable-decoder=h264 --enable-decoder=hevc --enable-decoder=mjpeg --enable-muxer=adts --enable-muxer=mpegts --enable-muxer=rtsp --enable-muxer=rtp --enable-muxer=avi --enable-muxer=flv --enable-muxer=hls --enable-muxer=mp4 --enable-muxer=flac --enable-demuxer=flac --enable-demuxer=aac --enable-demuxer=mpegts --enable-demuxer=h264 --enable-demuxer=hevc --enable-demuxer=mjpeg --enable-demuxer=image2 --enable-demuxer=mov --enable-demuxer=rtsp --enable-demuxer=hls --enable-demuxer=rtp --enable-demuxer=flv --enable-demuxer=mpegps --enable-demuxer=mpegtsraw --enable-demuxer=mpegvideo --enable-parser=h264 --enable-parser=hevc --enable-parser=aac --enable-parser=flac --enable-parser=mjpeg --enable-parser=mpeg4video --enable-parser=mpegvideo --enable-parser=mpegaudio --enable-bsf=h264_mp4toannexb --enable-bsf=aac_adtstoasc --enable-bsf=null --enable-bsf=extract_extradata --enable-protocol=file --enable-protocol=http --enable-protocol=rtp --enable-protocol=rtmpts --enable-protocol=https --enable-protocol=hls --enable-protocol=data --disable-armv5te --disable-armv6 --disable-mmx --disable-optimizations --disable-asm "
BR2_PACKAGE_BZIP2=y
BR2_PACKAGE_MEMSTAT=y
BR2_PACKAGE_MTD=y
BR2_PACKAGE_EUDEV_RULES_GEN=y
# BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set
BR2_PACKAGE_I2C_TOOLS=y
BR2_PACKAGE_TINYALSA=y
BR2_PACKAGE_MINIZIP_ZLIB=y
BR2_PACKAGE_LIBKCAPI=y
BR2_PACKAGE_LIBKCAPI_ENCAPP=y
BR2_PACKAGE_LIBKCAPI_HASHER=y
BR2_PACKAGE_LIBKCAPI_RNGAPP=y
BR2_PACKAGE_LIBOPENSSL_BIN=y
BR2_PACKAGE_LIBOPENSSL_ENGINES=y
BR2_PACKAGE_LIBGPIOD=y
BR2_PACKAGE_LIBGPIOD_TOOLS=y
BR2_PACKAGE_CJSON=y
BR2_PACKAGE_JSONCPP=y
BR2_PACKAGE_LIBEVENT=y
BR2_PACKAGE_LRZSZ=y
BR2_PACKAGE_NET_TOOLS=y
BR2_PACKAGE_OPENSSH=y
BR2_PACKAGE_OPTEE_CLIENT=y
# BR2_PACKAGE_OPTEE_CLIENT_RPMB_EMU is not set
BR2_PACKAGE_SYSKLOGD=y
BR2_PACKAGE_TAR=y
BR2_PACKAGE_UTIL_LINUX_LIBUUID=y
将上面内容替换 BSP 包的 system/buildroot/source/configs/x5_system_defconfig 文件中的内容。
Kernel 最小配置
如下是 Kernel 的最小配置:
CONFIG_WERROR=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_AUDIT=y
CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT=y
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_TASKSTATS=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_MEMCG=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
# CONFIG_RD_ZSTD is not set
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
CONFIG_ARCH_HOBOT=y
CONFIG_ARCH_HOBOT_X5=y
CONFIG_ARM64_VA_BITS_48=y
CONFIG_SCHED_MC=y
CONFIG_SCHED_SMT=y
CONFIG_NR_CPUS=8
CONFIG_HZ_100=y
CONFIG_PARAVIRT=y
CONFIG_KEXEC_FILE=y
CONFIG_CRASH_DUMP=y
CONFIG_COMPAT=y
CONFIG_RANDOMIZE_BASE=y
CONFIG_HOBOT_BOOT_LZ4=y
CONFIG_PM_DEBUG=y
CONFIG_PM_ADVANCED_DEBUG=y
CONFIG_PM_TEST_SUSPEND=y
CONFIG_CPU_IDLE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPUFREQ_DT=y
CONFIG_JUMP_LABEL=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_PAGE_REPORTING=y
CONFIG_KSM=y
CONFIG_MEMORY_FAILURE=y
CONFIG_CMA=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_PACKET_DIAG=y
CONFIG_UNIX=y
CONFIG_UNIX_DIAG=y
CONFIG_NET_KEY=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_MROUTE=y
CONFIG_NET_FOU=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
CONFIG_INET_UDP_DIAG=y
CONFIG_INET_RAW_DIAG=y
# CONFIG_IPV6 is not set
CONFIG_NETWORK_PHY_TIMESTAMPING=y
CONFIG_NETFILTER=y
CONFIG_VLAN_8021Q=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_HFSC=y
CONFIG_NET_SCH_PRIO=y
CONFIG_NET_SCH_MULTIQ=y
CONFIG_NET_SCH_TBF=y
CONFIG_NET_SCH_CBS=y
CONFIG_NET_SCH_ETF=y
CONFIG_NET_SCH_TAPRIO=y
CONFIG_NET_SCH_MQPRIO=y
CONFIG_NET_SCH_SKBPRIO=y
CONFIG_NET_SCH_INGRESS=y
CONFIG_NET_CLS_U32=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=y
CONFIG_NET_ACT_GACT=y
CONFIG_NET_ACT_SKBEDIT=y
CONFIG_DCB=y
CONFIG_NETLINK_DIAG=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
# CONFIG_DMIID is not set
CONFIG_EFI_CAPSULE_LOADER=y
CONFIG_EFI_DISABLE_RUNTIME=y
# CONFIG_ARM_SMCCC_SOC_ID is not set
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_NAND_DENALI_DT=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BLOCK=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=409600
CONFIG_EEPROM_AT24=y
CONFIG_HOBOT_VIO_N2D=m
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_ALACRITECH is not set
# CONFIG_NET_VENDOR_AMAZON is not set
# CONFIG_NET_VENDOR_AMD is not set
# CONFIG_NET_VENDOR_AQUANTIA is not set
# CONFIG_NET_VENDOR_ARC is not set
# CONFIG_NET_VENDOR_ASIX is not set
# CONFIG_NET_VENDOR_BROADCOM is not set
# CONFIG_NET_VENDOR_CADENCE is not set
# CONFIG_NET_VENDOR_CAVIUM is not set
# CONFIG_NET_VENDOR_CORTINA is not set
# CONFIG_NET_VENDOR_DAVICOM is not set
# CONFIG_NET_VENDOR_ENGLEDER is not set
# CONFIG_NET_VENDOR_EZCHIP is not set
# CONFIG_NET_VENDOR_FUNGIBLE is not set
# CONFIG_NET_VENDOR_GOOGLE is not set
# CONFIG_NET_VENDOR_HISILICON is not set
# CONFIG_NET_VENDOR_HUAWEI is not set
# CONFIG_NET_VENDOR_INTEL is not set
# CONFIG_NET_VENDOR_ADI is not set
# CONFIG_NET_VENDOR_LITEX is not set
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MELLANOX is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_MICROCHIP is not set
# CONFIG_NET_VENDOR_MICROSEMI is not set
# CONFIG_NET_VENDOR_MICROSOFT is not set
# CONFIG_NET_VENDOR_NI is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_PENSANDO is not set
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_RENESAS is not set
# CONFIG_NET_VENDOR_ROCKER is not set
# CONFIG_NET_VENDOR_SAMSUNG is not set
# CONFIG_NET_VENDOR_SEEQ is not set
# CONFIG_NET_VENDOR_SOLARFLARE is not set
# CONFIG_NET_VENDOR_SMSC is not set
# CONFIG_NET_VENDOR_SOCIONEXT is not set
CONFIG_STMMAC_ETH=y
CONFIG_STMMAC_SELFTESTS=y
CONFIG_DWMAC_DWC_QOS_ETH=y
# CONFIG_NET_VENDOR_SYNOPSYS is not set
# CONFIG_NET_VENDOR_VERTEXCOM is not set
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WANGXUN is not set
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_NET_VENDOR_XILINX is not set
CONFIG_X5_ETH=y
CONFIG_JPLUS_ETH=y
CONFIG_REALTEK_PHY=y
CONFIG_USB_NET_DRIVERS=m
CONFIG_KEYBOARD_GPIO=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO_SERPORT is not set
CONFIG_SERIO_AMBAKMI=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_LEGACY_PTY_COUNT=16
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=8
CONFIG_SERIAL_8250_RUNTIME_UARTS=8
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_DEV_BUS=y
CONFIG_HW_RANDOM=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_SPI=y
CONFIG_SPI_DESIGNWARE=y
CONFIG_SPI_DW_DMA=y
CONFIG_SPI_DW_MMIO=y
CONFIG_SPI_SPIDEV=m
CONFIG_SPI_SLAVE=y
CONFIG_PPS_CLIENT_HOBOT_PPS=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_HORIZON=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_DWAPB=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_SYSCON_REBOOT_MODE=y
CONFIG_SENSORS_MR75203=y
CONFIG_THERMAL=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_CPU_THERMAL=y
CONFIG_DEVFREQ_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_DW_WATCHDOG=y
CONFIG_MFD_HI6421_PMIC=y
CONFIG_MFD_HPU3501=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_DEBUG=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_HPU3501=y
CONFIG_MEDIA_SUPPORT=y
# CONFIG_DVB_NET is not set
# CONFIG_DVB_DYNAMIC_MINORS is not set
CONFIG_MEDIA_USB_SUPPORT=y
CONFIG_USB_VIDEO_CLASS=m
# CONFIG_RADIO_ADAPTERS is not set
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_HOBOT_VIO=m
CONFIG_HOBOT_VIO_JPLUS=y
CONFIG_HOBOT_VIO_COMMON=m
CONFIG_HOBOT_VIN_NODE=m
CONFIG_HOBOT_VCON=m
CONFIG_HOBOT_CAMSYS=m
CONFIG_HOBOT_GDC_JPLUS=m
CONFIG_HOBOT_SENSOR=m
CONFIG_HOBOT_DESERIAL=m
CONFIG_HOBOT_LPWM=m
CONFIG_HOBOT_OSD=m
CONFIG_HOBOT_VSI_CAM=m
CONFIG_HOBOT_MIPI_CSI=y
CONFIG_HOBOT_CODEC_NODE=m
CONFIG_HOBOT_MIPI_CSI_DRV=m
CONFIG_HOBOT_MIPI_HOST_MAX_NUM=6
CONFIG_HOBOT_MIPI_HOST_SNRCLK=y
CONFIG_HOBOT_MIPI_DEV_MAX_NUM=2
CONFIG_HOBOT_MIPI_PHY=m
CONFIG_HOBOT_MIPI_DEBUG=m
CONFIG_VIDEO_VS_ISP_NAT=m
CONFIG_VIDEO_VS_VSE_NAT=m
CONFIG_VIDEO_VS_SIF_NAT=m
CONFIG_VIDEO_VS_CAM_PULSE=m
CONFIG_VIDEO_VS_ISP_V4L=m
CONFIG_VIDEO_VS_VSE_V4L=m
CONFIG_VIDEO_VS_SIF_V4L=m
CONFIG_VIDEO_VS_GDC_ARM_V4L=m
CONFIG_VIDEO_HOBOTC_JPU=m
CONFIG_VIDEO_HOBOTC_VPU=m
# CONFIG_CXD2880_SPI_DRV is not set
# CONFIG_MEDIA_TUNER_E4000 is not set
# CONFIG_MEDIA_TUNER_FC0011 is not set
# CONFIG_MEDIA_TUNER_FC0012 is not set
# CONFIG_MEDIA_TUNER_FC0013 is not set
# CONFIG_MEDIA_TUNER_FC2580 is not set
# CONFIG_MEDIA_TUNER_IT913X is not set
# CONFIG_MEDIA_TUNER_M88RS6000T is not set
# CONFIG_MEDIA_TUNER_MAX2165 is not set
# CONFIG_MEDIA_TUNER_MC44S803 is not set
# CONFIG_MEDIA_TUNER_MSI001 is not set
# CONFIG_MEDIA_TUNER_MT2060 is not set
# CONFIG_MEDIA_TUNER_MT2063 is not set
# CONFIG_MEDIA_TUNER_MT20XX is not set
# CONFIG_MEDIA_TUNER_MT2131 is not set
# CONFIG_MEDIA_TUNER_MT2266 is not set
# CONFIG_MEDIA_TUNER_MXL301RF is not set
# CONFIG_MEDIA_TUNER_MXL5005S is not set
# CONFIG_MEDIA_TUNER_MXL5007T is not set
# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set
# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set
# CONFIG_MEDIA_TUNER_QT1010 is not set
# CONFIG_MEDIA_TUNER_R820T is not set
# CONFIG_MEDIA_TUNER_SI2157 is not set
# CONFIG_MEDIA_TUNER_SIMPLE is not set
# CONFIG_MEDIA_TUNER_TDA18212 is not set
# CONFIG_MEDIA_TUNER_TDA18218 is not set
# CONFIG_MEDIA_TUNER_TDA18250 is not set
# CONFIG_MEDIA_TUNER_TDA18271 is not set
# CONFIG_MEDIA_TUNER_TDA827X is not set
# CONFIG_MEDIA_TUNER_TDA8290 is not set
# CONFIG_MEDIA_TUNER_TDA9887 is not set
# CONFIG_MEDIA_TUNER_TEA5761 is not set
# CONFIG_MEDIA_TUNER_TEA5767 is not set
# CONFIG_MEDIA_TUNER_TUA9001 is not set
# CONFIG_MEDIA_TUNER_XC2028 is not set
# CONFIG_MEDIA_TUNER_XC4000 is not set
# CONFIG_MEDIA_TUNER_XC5000 is not set
# CONFIG_DVB_M88DS3103 is not set
# CONFIG_DVB_MXL5XX is not set
# CONFIG_DVB_STB0899 is not set
# CONFIG_DVB_STB6100 is not set
# CONFIG_DVB_STV090x is not set
# CONFIG_DVB_STV0910 is not set
# CONFIG_DVB_STV6110x is not set
# CONFIG_DVB_STV6111 is not set
# CONFIG_DVB_DRXK is not set
# CONFIG_DVB_MN88472 is not set
# CONFIG_DVB_MN88473 is not set
# CONFIG_DVB_SI2165 is not set
# CONFIG_DVB_TDA18271C2DD is not set
# CONFIG_DVB_CX24110 is not set
# CONFIG_DVB_CX24116 is not set
# CONFIG_DVB_CX24117 is not set
# CONFIG_DVB_CX24120 is not set
# CONFIG_DVB_CX24123 is not set
# CONFIG_DVB_DS3000 is not set
# CONFIG_DVB_MB86A16 is not set
# CONFIG_DVB_MT312 is not set
# CONFIG_DVB_S5H1420 is not set
# CONFIG_DVB_SI21XX is not set
# CONFIG_DVB_STB6000 is not set
# CONFIG_DVB_STV0288 is not set
# CONFIG_DVB_STV0299 is not set
# CONFIG_DVB_STV0900 is not set
# CONFIG_DVB_STV6110 is not set
# CONFIG_DVB_TDA10071 is not set
# CONFIG_DVB_TDA10086 is not set
# CONFIG_DVB_TDA8083 is not set
# CONFIG_DVB_TDA8261 is not set
# CONFIG_DVB_TDA826X is not set
# CONFIG_DVB_TS2020 is not set
# CONFIG_DVB_TUA6100 is not set
# CONFIG_DVB_TUNER_CX24113 is not set
# CONFIG_DVB_TUNER_ITD1000 is not set
# CONFIG_DVB_VES1X93 is not set
# CONFIG_DVB_ZL10036 is not set
# CONFIG_DVB_ZL10039 is not set
# CONFIG_DVB_AF9013 is not set
# CONFIG_DVB_CX22700 is not set
# CONFIG_DVB_CX22702 is not set
# CONFIG_DVB_CXD2820R is not set
# CONFIG_DVB_CXD2841ER is not set
# CONFIG_DVB_DIB3000MB is not set
# CONFIG_DVB_DIB3000MC is not set
# CONFIG_DVB_DIB7000M is not set
# CONFIG_DVB_DIB7000P is not set
# CONFIG_DVB_DIB9000 is not set
# CONFIG_DVB_DRXD is not set
# CONFIG_DVB_EC100 is not set
# CONFIG_DVB_L64781 is not set
# CONFIG_DVB_MT352 is not set
# CONFIG_DVB_NXT6000 is not set
# CONFIG_DVB_RTL2830 is not set
# CONFIG_DVB_RTL2832 is not set
# CONFIG_DVB_RTL2832_SDR is not set
# CONFIG_DVB_S5H1432 is not set
# CONFIG_DVB_SI2168 is not set
# CONFIG_DVB_SP887X is not set
# CONFIG_DVB_STV0367 is not set
# CONFIG_DVB_TDA10048 is not set
# CONFIG_DVB_TDA1004X is not set
# CONFIG_DVB_ZD1301_DEMOD is not set
# CONFIG_DVB_ZL10353 is not set
# CONFIG_DVB_CXD2880 is not set
# CONFIG_DVB_STV0297 is not set
# CONFIG_DVB_TDA10021 is not set
# CONFIG_DVB_TDA10023 is not set
# CONFIG_DVB_VES1820 is not set
# CONFIG_DVB_AU8522_DTV is not set
# CONFIG_DVB_AU8522_V4L is not set
# CONFIG_DVB_BCM3510 is not set
# CONFIG_DVB_LG2160 is not set
# CONFIG_DVB_LGDT3305 is not set
# CONFIG_DVB_LGDT3306A is not set
# CONFIG_DVB_LGDT330X is not set
# CONFIG_DVB_MXL692 is not set
# CONFIG_DVB_NXT200X is not set
# CONFIG_DVB_OR51132 is not set
# CONFIG_DVB_OR51211 is not set
# CONFIG_DVB_S5H1409 is not set
# CONFIG_DVB_S5H1411 is not set
# CONFIG_DVB_DIB8000 is not set
# CONFIG_DVB_MB86A20S is not set
# CONFIG_DVB_S921 is not set
# CONFIG_DVB_MN88443X is not set
# CONFIG_DVB_TC90522 is not set
# CONFIG_DVB_PLL is not set
# CONFIG_DVB_TUNER_DIB0070 is not set
# CONFIG_DVB_TUNER_DIB0090 is not set
# CONFIG_DVB_A8293 is not set
# CONFIG_DVB_AF9033 is not set
# CONFIG_DVB_ASCOT2E is not set
# CONFIG_DVB_ATBM8830 is not set
# CONFIG_DVB_HELENE is not set
# CONFIG_DVB_HORUS3A is not set
# CONFIG_DVB_ISL6405 is not set
# CONFIG_DVB_ISL6421 is not set
# CONFIG_DVB_ISL6423 is not set
# CONFIG_DVB_IX2505V is not set
# CONFIG_DVB_LGS8GL5 is not set
# CONFIG_DVB_LGS8GXX is not set
# CONFIG_DVB_LNBH25 is not set
# CONFIG_DVB_LNBH29 is not set
# CONFIG_DVB_LNBP21 is not set
# CONFIG_DVB_LNBP22 is not set
# CONFIG_DVB_M88RS2000 is not set
# CONFIG_DVB_TDA665x is not set
# CONFIG_DVB_DRX39XYJ is not set
# CONFIG_DVB_CXD2099 is not set
# CONFIG_DVB_SP2 is not set
CONFIG_DRM=y
CONFIG_DRM_PANEL_ATK_MD0550=y
CONFIG_DRM_SII902X=y
CONFIG_VERISILICON_X5_SYSCON_BRIDGE=m
CONFIG_DRM_VERISILICON=m
CONFIG_VERISILICON_DC8000_NANO=y
CONFIG_VERISILICON_BT1120=y
CONFIG_VERISILICON_DW_MIPI_DSI=y
CONFIG_VERISILICON_WRITEBACK_SIF=y
CONFIG_VERISILICON_GEM_ION=y
CONFIG_VERISILICON_GC_PROC_SUPPORT=y
CONFIG_FB=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_PWM=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_DESIGNWARE_I2S=m
CONFIG_SND_DESIGNWARE_PCM=y
CONFIG_SND_ARCHBAND_PDM=y
CONFIG_SND_VIRT_CODEC=y
CONFIG_SND_SOC_WM8962=y
CONFIG_SND_DUPLEX_CARD=m
CONFIG_SND_HOBOT_SOUND_MACHINE=m
CONFIG_SND_SIMPLE_CARD=m
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_STORAGE=y
CONFIG_USB_UAS=y
CONFIG_USB_DWC3=y
CONFIG_USB_GADGET=y
CONFIG_USB_CONFIGFS=m
CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_CONFIGFS_ACM=y
CONFIG_USB_CONFIGFS_OBEX=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_ECM=y
CONFIG_USB_CONFIGFS_ECM_SUBSET=y
CONFIG_USB_CONFIGFS_RNDIS=y
CONFIG_USB_CONFIGFS_EEM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_LB_SS=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_USB_CONFIGFS_F_UVC=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_FUNCTIONFS=m
CONFIG_USB_FUNCTIONFS_ETH=y
CONFIG_USB_FUNCTIONFS_RNDIS=y
CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_G_MULTI=m
CONFIG_USB_G_MULTI_CDC=y
CONFIG_USB_G_WEBCAM=m
CONFIG_USB_RAW_GADGET=m
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_OF_DWCMSHC=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DEBUG=y
CONFIG_RTC_DRV_DWAPB=y
CONFIG_DMADEVICES=y
CONFIG_DW_AXI_DMAC=y
CONFIG_UIO=y
# CONFIG_VIRTIO_MENU is not set
# CONFIG_VHOST_MENU is not set
CONFIG_STAGING=y
CONFIG_ANDROID_LOGGER=y
CONFIG_BOOTLOADER_LOG=y
CONFIG_ION=y
CONFIG_ION_SYSTEM_HEAP=y
CONFIG_ION_CARVEOUT_HEAP=y
CONFIG_ION_CHUNK_HEAP=y
CONFIG_ION_CMA_HEAP=y
CONFIG_ION_HOBOT=y
# CONFIG_FSL_ERRATUM_A008585 is not set
# CONFIG_HISILICON_ERRATUM_161010101 is not set
# CONFIG_ARM64_ERRATUM_858921 is not set
CONFIG_MAILBOX=y
CONFIG_DROBOT_LITE_MMU=y
CONFIG_REMOTEPROC=y
CONFIG_HOBOT_BPU=y
CONFIG_BPU=m
CONFIG_BPU_CORE=m
CONFIG_PM_DEVFREQ=y
CONFIG_DEVFREQ_GOV_PERFORMANCE=y
CONFIG_DEVFREQ_GOV_POWERSAVE=y
CONFIG_ARM_X5_DDRC_DEVFREQ=y
CONFIG_PM_DEVFREQ_EVENT=y
CONFIG_DEVFREQ_EVENT_X5_DFI=y
CONFIG_EXTCON=y
CONFIG_EXTCON_USB_GPIO=y
CONFIG_IIO=y
CONFIG_IIO_SW_TRIGGER=y
CONFIG_GUC_ADC=y
CONFIG_PWM=y
CONFIG_PWM_DROBOT=y
CONFIG_PHY_SNPS_MIPI_DPHY=y
CONFIG_ARM_DSU_PMU=y
CONFIG_NVMEM_HORIZON_EFUSE=y
CONFIG_TEE=y
CONFIG_OPTEE=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_FANOTIFY=y
CONFIG_VFAT_FS=y
CONFIG_EXFAT_FS=y
CONFIG_TMPFS=y
CONFIG_HUGETLBFS=y
CONFIG_EFIVAR_FS=y
CONFIG_UBIFS_FS=y
CONFIG_PSTORE=y
CONFIG_PSTORE_CONSOLE=y
CONFIG_PSTORE_PMSG=y
CONFIG_PSTORE_RAM=y
CONFIG_SCHED_LOGGER=y
CONFIG_NFS_FS=y
CONFIG_SUNRPC_DEBUG=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_CRYPTO_USER=y
CONFIG_CRYPTO_DH=y
CONFIG_CRYPTO_ECDH=y
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_CMAC=y
CONFIG_CRYPTO_DRBG_HASH=y
CONFIG_CRYPTO_USER_API_HASH=y
CONFIG_CRYPTO_USER_API_SKCIPHER=y
CONFIG_CRYPTO_USER_API_RNG=y
CONFIG_CRYPTO_USER_API_AEAD=y
CONFIG_CRYPTO_DEV_TE=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC7=y
CONFIG_LIBCRC32C=m
CONFIG_XZ_DEC=y
CONFIG_DMA_CMA=y
CONFIG_CMA_SIZE_MBYTES=32
CONFIG_PRINTK_TIME=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_GDB_SCRIPTS=y
CONFIG_VMLINUX_MAP=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_FTRACE is not set
# CONFIG_STRICT_DEVMEM is not set
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
CONFIG_CORESIGHT_CATU=y
CONFIG_CORESIGHT_SINK_TPIU=y
CONFIG_CORESIGHT_SINK_ETBV10=y
CONFIG_CORESIGHT_SOURCE_ETM4X=y
CONFIG_CORESIGHT_CTI=y
CONFIG_CORESIGHT_CTI_INTEGRATION_REGS=y
CONFIG_MEMTEST=y
将上述内容替换 BSP 包的 kernel/arch/arm64/configs/hobot_x5_soc_defconfig 文件中的内容。
编译与测试
编译新镜像
1)编译根文件系统:
按照下面命令重新编译根文件系统:
cd system/ubuntu/source
./build.sh clean
./build.sh menuconfig x5_system_defconfig
./build.sh build x5_system_defconfig 0.0.1
有关 buildroot 编译根文件系统的详细说明请参考 使用 Buildroot 制作根文件系统 章节。
生成的根文件系统镜像在 system/buildroot/source/framework/output/images 目录中:
$ cd system/buildroot/source/framework/output/images
$ ls
deb_make dr-system_0.0.1~gcc11.3.1_all.deb rootfs.tar rtl_bt rtlwifi
2)复制根文件系统镜像到预编译目录:
需要将生成的镜像复制到 system/buildroot/prebuilt 目录下,并且将 system/buildroot/prebuilt/series 文件中的根文件系统镜像的名称修改为 “ dr-system_0.0.1~gcc11.3.1_all.deb” (或者修改为编译根文件系统时候命令中加入的具体版本参数),如下:
# system/buildroot/prebuilt/series
dr-system_0.0.1~gcc11.3.1_all.deb
dr-libgtest_1.14.0~gcc11.3.rel1_arm64.deb
dr-libgdcbin_1.0.0~gcc11.3.rel1_arm64.deb
dr-perf_6.1.12~gcc11.3.rel1_arm64.deb
dr-libdnn_1.24.5~gcc11.3.rel1_arm64.deb
dr-libhpatchz_3.1.1~gcc11.3.rel1_arm64.deb
3)重新编译 BSP 包镜像:
注意 先执行 ./bd.sh distclean 命令清理掉之前的编译产物,再执行 ./bd.sh 重新编译镜像,此时选择配置项为 NAND flash,也就是选项 3 :
$ ./bd.sh distclean
$ ./bd.sh
You're building on #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025
Lunch menu... pick a combo:
0. horizon/x5/board_x5_evb_debug_config.mk
1. horizon/x5/board_x5_evb_jammy_debug_config.mk
2. horizon/x5/board_x5_evb_jammy_release_config.mk
3. horizon/x5/board_x5_evb_nand_debug_config.mk
4. horizon/x5/board_x5_evb_nand_release_config.mk
5. horizon/x5/board_x5_evb_release_config.mk
6. horizon/x5/board_x5_soc_debug_config.mk
7. horizon/x5/board_x5_soc_release_config.mk
Which would you like? [0] : 3
测试新镜像
查看裁剪后生成的根文件系统镜像大小:
$ cd system/buildroot/source/framework/output/images
$ ls -lh dr-system_0.0.1~gcc11.3.1_all.deb
-rw-r--r-- 1 sxq sxq 7.0M Jan 8 20:14 dr-system_0.0.1~gcc11.3.1_all.deb
可以看到根文件系统镜像已经变成了 7MB(裁剪之前是 25MB)。
查看裁剪后生成的 vmlinux 大小:
$ cd out/build/kernel
$ ls -lh vmlinux
-rwxr-xr-x 1 sxq sxq 252M Jan 9 11:23 vmlinux
可以看到 vmlinux 已经变成了 252MB(裁剪之前是 257MB)。
查看内核模块的大小:
$ cd out/deploy/boot/modules/lib/modules
$ du -h --max-depth=1
5.3M ./6.1.83-DR-PL5.1_V1.0.16
5.3M .
可以看到内核模块目录大小变成了 5.3MB(裁剪之前是 20MB)。
待编译结束,即可重新烧录镜像进行测试。
注意 烧录时需要将拨码开关配置为 “[D0:D2] 000”,将板端配置为 NAND 模式才能进行烧录,待烧录完成需要将拨码开关配置为 “[D0:D2] 101”,才能使单板配置为 NAND 模式启动。关于拨码开关的详细配置,可以参考拨码开关(以 EVB 1_b 为例)的相关章节。
关于镜像烧录详细方式,可以参考系统镜像烧写 章节。
待镜像烧录完毕,查看启动日志:
SNOTICE: Welcome to Horizon X5 ASIC BOOTROM - V4.1
NOTICE: OTP config:
NOTICE: otp exist: true
NOTICE: test region size: 304
NOTICE: secure region size: 120
NOTICE: none secure region size: 56
NOTICE: Enable MMU
NOTICE: Booting Trusted Firmware
NOTICE: BL1: v2.8(release):
NOTICE: BL1: Built : 17:42:12, Oct 19 2023
NOTICE: Enter SPI NAND-FLASH Mode......
NOTICE: Nand PAGE_SIZE_4K
NOTICE: Nand is_dummy = true
NOTICE: Nand CLK_12M
NOTICE: SPI baudrate is set to 12000000Hz
NOTICE: Nand reset
NOTICE: reg_status should = 0x18
NOTICE: SPI Nand flash buffer mode set PASS
NOTICE: Manufacturer ID 0x2c Device ID 0x352c
NOTICE: Enter media_source_select process(5).
NOTICE: SPI Nand flash set quad PASS
上述 Uboot 日志中可以看到已经是 NAND flash 了。
内核中可以看到分区情况如下:
root@buildroot:~# cat /proc/mtd
dev: size erasesize name
mtd0: 00040000 00040000 "mbr"
mtd1: 00240000 00040000 "miniboot"
mtd2: 00240000 00040000 "miniboot_bak1"
mtd3: 00040000 00040000 "misc"
mtd4: 00200000 00040000 "uboot"
mtd5: 00180000 00040000 "ubootenv"
mtd6: 02000000 00040000 "boot"
mtd7: 09600000 00040000 "system"
mtd8: 06400000 00040000 "hbre"
mtd9: 0dd80000 00040000 "userdata"
日志中显示了设备的 MTD( Memory Technology Devices )分区信息,其中各个字段解释如下:
dev: 设备的名称标识符。
size: 该分区的大小,以字节为单位。
erasesize: 每次擦除操作的大小,以字节为单位。这个大小通常决定了闪存擦除的最小单位。
name: 分区的名称,通常是为特定用途或功能分配的。
各个分区的具体信息如下:
| dev | size | erasesize | name | 说明 |
|---|---|---|---|---|
| mtd0 | 0x00040000 (256 KB) | 0x00040000 (256 KB) | "mbr" | 主引导记录( MBR ),通常用于启动时的分区信息。 |
| mtd1 | 0x00240000 (2.25 MB) | 0x00040000 (256 KB) | "miniboot" | 小型引导程序,用于初始化设备并加载更大程序。 |
| mtd2 | 0x00240000 (2.25 MB) | 0x00040000 (256 KB) | "miniboot_bak1" | miniboot 的备份,通常用于恢复系统。 |
| mtd3 | 0x00040000 (256 KB) | 0x00040000 (256 KB) | "misc" | 设备的其他配置或不可区分的数据区域。 |
| mtd4 | 0x00200000 (2 MB) | 0x00040000 (256 KB) | "uboot" | uBoot,常见的引导加载程序,用于启动系统。 |
| mtd5 | 0x00180000 (1.5 MB) | 0x00040000 (256 KB) | "ubootenv" | 存储 uBoot 环境变量,如启动设置等。 |
| mtd6 | 0x02000000 (32 MB) | 0x00040000 (256 KB) | "boot" | 存储启动映像的分区。 |
| mtd7 | 0x09600000 (150 MB) | 0x00040000 (256 KB) | "system" | 存储系统文件和核心文件,通常是根文件系统。 |
| mtd8 | 0x06400000 (100 MB) | 0x00040000 (256 KB) | "hbre" | 自定义分区,可能与硬件或应用程序相关。 |
| mtd9 | 0x0dd80000 (223 MB) | 0x00040000 (256 KB) | "userdata" | 存储用户数据的分区,通常用于存储应用数据或用户配置。 |
日志结果和 BSP 包分区表 device/horizon/x5/board_cfg/soc/x5-soc-debug-nand-gpt.json 中的配置是一致的:
{
"mbr": {
"size": "256k",
"medium": "nand"
},
"miniboot": "sub_config/miniboot_nand.json",
"misc": {
"size": "256k",
"medium": "nand"
},
"uboot": {
"part_type": "GOLDEN",
"size": "2m",
"medium": "nand"
},
"ubootenv": {
"size": "1536k",
"medium": "nand"
},
"boot": {
"part_type": "GOLDEN",
"size": "32m",
"medium": "nand"
},
"system": {
"fs_type": "ubifs",
"part_type": "GOLDEN",
"size": "150m",
"medium": "nand"
},
"hbre": {
"fs_type": "ubifs",
"part_type": "GOLDEN",
"size": "100m",
"medium": "nand"
},
"userdata": {
"fs_type": "ubifs",
"part_type": "GOLDEN",
"size": "32m",
"medium": "nand"
}
}
可以根据最终经过裁剪后得到的镜像大小修改分区表中的 size 设定值,以合理分配各个分区容量。
4.4.4.6. 常见问题
在系统裁剪过程中,常见的几个问题包括功能丧失、系统不稳定、依赖问题、性能下降和兼容性问题等。以下是这些问题的具体说明以及相应的解决方案。
功能丧失或不可用
问题描述:裁剪过程中,如果移除了过多的功能或模块,可能会导致系统无法提供所需的基本功能。
解决方案:
需求驱动裁剪:在裁剪之前,首先明确系统必须支持的功能,并确保这些功能在裁剪过程中不被移除。
分阶段裁剪:逐步裁剪,避免一次性删除过多功能,每个阶段后进行系统验证,确保所需功能仍可正常使用。
举例: 如果裁剪掉了某些文件系统支持模块,可能导致存储不可用。为避免此问题,应在裁剪时保留对特定文件系统(如 ext4 或 FAT)的支持。
系统不稳定或崩溃
问题描述:过度裁剪或移除核心模块(如内核调度、内存管理等)会导致系统崩溃或无法启动。
解决方案:
核心功能保护:裁剪时要确保核心功能如内存管理、硬件抽象层( HAL)和中断管理模块不被移除。
充分测试:每次裁剪后进行全面测试,尤其是在硬件和网络模块方面,确保系统在各种条件下稳定运行。
举例: 在裁剪内核时,删除了对特定硬件的驱动支持,导致系统无法识别设备。应通过保留最基本的硬件支持和驱动程序,避免这种情况。
依赖问题
问题描述:裁剪时可能会去除一些不必要的库或工具,但如果裁剪不当,可能导致系统在运行时缺少某些库依赖,导致程序崩溃或无法启动。
解决方案:
最小化依赖:裁剪时,首先识别哪些库和工具是必须的,尽量去除不必要的依赖项。使用静态链接而非动态链接有时可以减少依赖问题。
使用轻量级替代品:例如,使用 BusyBox 替代多个常规工具集,减少不必要的库和工具的依赖。
举例: 裁剪过程中可能去除了某些开发库,导致程序无法启动或运行异常。应通过使用静态链接或者保留必要的依赖项,确保系统稳定运行。
性能下降
问题描述:某些功能虽然看似不必要,但其存在可能对系统的性能有重要影响。
解决方案:
功能裁剪与性能优化平衡:裁剪时不仅要考虑功能的移除,还要关注性能优化。例如,保留对硬件加速支持的驱动,使用高效算法和数据结构。
精简内核配置:精简内核时,应根据目标硬件去除不必要的驱动和模块,确保内核占用更少的资源。
举例: 裁剪时如果移除了对内存页交换( swap)的支持,可能导致内存资源紧张时系统性能下降。应确保内存管理机制完整,避免因过度裁剪引起性能下降。
兼容性问题
问题描述:裁剪可能导致系统与现有硬件或软件的不兼容,尤其是在内核或启动引导程序(如 Uboot)裁剪时。如果移除不当,可能导致系统无法启动或硬件不兼容。
解决方案:
保持向后兼容性:裁剪时要确保不影响系统的基本硬件支持和接口,特别是在内核和引导程序方面。
文档化裁剪过程:记录每一步的裁剪决策和变更,以便日后回滚或调整,保证系统与硬件的兼容性。
举例: 如果在裁剪 Uboot 时删除了对某些启动设备的支持(如 SD 卡启动支持),可能导致系统无法启动。应确保在裁剪过程中保留必要的硬件支持和启动功能。
4.4.4.7. 参考文献
The U-Boot Documentation
Kernel Size Tuning Guide
Buildroot User Manua