luckfox pico max SDK 如何打包 OEM 分区镜像

OEM 分区的内同

luckfox pico max 原厂 oem 分区的内容相当丰富

[root@luckfox root]# tree /oem
/oem
`-- usr
    |-- bin
    |   |-- RkLunch-stop.sh
    |   |-- RkLunch.sh
    |   |-- dumpsys
    |   |-- luckfox_adc_test
    |   |-- luckfox_gpio_test
    |   |-- luckfox_i2c_test
    |   |-- luckfox_pwm_test
    |   |-- luckfox_spi_test
    |   |-- luckfox_uart_test
    |   |-- modetest
    |   |-- mpi_enc_test
    |   |-- mpp_info_test
    |   |-- rgaImDemo
    |   |-- rk_adc_test
    |   |-- rk_event_test
    |   |-- rk_gpio_test
    |   |-- rk_led_test
    |   |-- rk_mpi_adec_test
    |   |-- rk_mpi_aenc_test
    |   |-- rk_mpi_af_test
    |   |-- rk_mpi_ai_test
    |   |-- rk_mpi_amix_test
    |   |-- rk_mpi_ao_test
    |   |-- rk_mpi_avio_test
    |   |-- rk_mpi_dup_venc_test
    |   |-- rk_mpi_mb_test
    |   |-- rk_mpi_mmz_test
    |   |-- rk_mpi_rgn_test
    |   |-- rk_mpi_sys_test
    |   |-- rk_mpi_tde_test
    |   |-- rk_mpi_venc_test
    |   |-- rk_mpi_vi_dup_test
    |   |-- rk_mpi_vi_test
    |   |-- rk_mpi_vpss_test
    |   |-- rk_pwm_test
    |   |-- rk_rve_sample_test
    |   |-- rk_system_test
    |   |-- rk_time_test
    |   |-- rk_watchdog_test
    |   |-- rkaiq_3A_server
    |   |-- rkipc
    |   |-- rkisp_demo
    |   |-- sample_ai
    |   |-- sample_ai_aenc
    |   |-- sample_camera_stresstest
    |   |-- sample_demo_multi_camera_eptz
    |   |-- sample_demo_vi_venc
    |   |-- sample_isp_stresstest
    |   |-- sample_mulit_isp_stresstest
    |   |-- sample_multi_vi
    |   |-- sample_rgn_stresstest
    |   |-- sample_venc_stresstest
    |   |-- sample_vi
    |   |-- sample_vi_vpss_osd_venc
    |   |-- simple_adec_ao
    |   |-- simple_ai
    |   |-- simple_ai_aenc
    |   |-- simple_ao
    |   |-- simple_dual_camera
    |   |-- simple_fast_client
    |   |-- simple_venc_jpeg
    |   |-- simple_venc_osd
    |   |-- simple_vi_eptz_test
    |   |-- simple_vi_get_frame
    |   |-- simple_vi_ivs
    |   |-- simple_vi_rkaiq
    |   |-- simple_vi_rockiva
    |   |-- simple_vi_tde
    |   |-- simple_vi_venc
    |   |-- simple_vi_venc_change_resolution
    |   |-- simple_vi_venc_combo
    |   |-- simple_vi_venc_rtsp
    |   |-- simple_vi_venc_wrap
    |   |-- simple_vi_vpss_venc
    |   `-- vpu_api_test
    |-- etc
    |   |-- init.d
    |   |   `-- bkS50onvifserver
    |   `-- startonvif.sh
    |-- ko
    |   |-- aes_generic.ko
    |   |-- ccm.ko
    |   |-- cfg80211.ko
    |   |-- cmac.ko
    |   |-- ctr.ko
    |   |-- gcm.ko
    |   |-- gf128mul.ko
    |   |-- ghash-generic.ko
    |   |-- gspca_main.ko
    |   |-- hpmcu_wrap.bin
    |   |-- insmod_ko.sh
    |   |-- ipv6.ko
    |   |-- libaes.ko
    |   |-- libarc4.ko
    |   |-- libsha256.ko
    |   |-- mac80211.ko
    |   |-- mpp_vcodec.ko
    |   |-- os04a10.ko
    |   |-- phy-rockchip-csi2-dphy-hw.ko
    |   |-- phy-rockchip-csi2-dphy.ko
    |   |-- release_version.txt
    |   |-- rga3.ko
    |   |-- rk_dvbm.ko
    |   |-- rknpu.ko
    |   |-- rockit.ko
    |   |-- rve.ko
    |   |-- sc3336.ko
    |   |-- sc4336.ko
    |   |-- sc530ai.ko
    |   |-- sha256_generic.ko
    |   |-- video_rkcif.ko
    |   `-- video_rkisp.ko
    |-- lib
    |   |-- README.md
    |   |-- face_mask_classify.data
    |   |-- face_quality_v2.data
    |   |-- libaec_bf_process.so
    |   |-- libdrm.so -> libdrm.so.2.4.0
    |   |-- libdrm.so.2 -> libdrm.so.2.4.0
    |   |-- libdrm.so.2.4.0
    |   |-- libdrm_rockchip.so -> libdrm_rockchip.so.1.0.0
    |   |-- libdrm_rockchip.so.1 -> libdrm_rockchip.so.1.0.0
    |   |-- libdrm_rockchip.so.1.0.0
    |   |-- libiconv.so -> libiconv.so.2.6.1
    |   |-- libiconv.so.2 -> libiconv.so.2.6.1
    |   |-- libiconv.so.2.6.1
    |   |-- libivs.so
    |   |-- libkms.so -> libkms.so.1.0.0
    |   |-- libkms.so.1 -> libkms.so.1.0.0
    |   |-- libkms.so.1.0.0
    |   |-- librga.so
    |   |-- librkAVS_stitchFor1106.so
    |   |-- librkaiq.so
    |   |-- librkaudio.so
    |   |-- librkaudio_common.so
    |   |-- librkaudio_detect.so
    |   |-- librkdemuxer.so
    |   |-- librkfsmk.so
    |   |-- librkmuxer.so
    |   |-- librknnmrt.so
    |   |-- librksysutils.so
    |   |-- librockchip_mpp.so -> librockchip_mpp.so.1
    |   |-- librockchip_mpp.so.0
    |   |-- librockchip_mpp.so.1 -> librockchip_mpp.so.0
    |   |-- librockit.so
    |   |-- librockit_full.so
    |   |-- librockit_tiny.so
    |   |-- librockiva.so
    |   |-- librve.so
    |   |-- libsmartIr.so
    |   |-- libwpa_client.so
    |   |-- libz.so -> libz.so.1
    |   |-- libz.so.1
    |   |-- object_detection_ipc_cls7.data
    |   |-- object_detection_ipc_cls7_v.data
    |   |-- object_detection_pfp.data
    |   `-- object_detection_pfp_896x512.data
    `-- share
        |-- image.bmp
        |-- iqfiles
        |   |-- CAC_sc4336_OT01_40IRC_F16
        |   |   `-- cac_map_hw_2560x1440.bin
        |   |-- sc3336_CMK-OT2119-PC1_30IRC-F16.json
        |   `-- sc4336_OT01_40IRC_F16.json
        |-- rkipc-300w.ini
        |-- rkipc-400w.ini
        |-- rkipc-500w.ini
        |-- simsun_en.ttf
        |-- speaker_test.wav
        `-- vqefiles
            |-- config_aivqe.json
            `-- config_aoagc.json

10 directories, 164 files

搞懂这些东西的生成过程,可以为我们修改/开发相应功能提供极有价值的参考。

生成过程

整个SDK的编译工作由顶部目录 luckfox-pico/build.sh文件负责。
这个文件其实是个软链接,真正的文件在

luckfox/luckfox-pico$ ls ./build.sh -al
lrwxrwxrwx 1 magee magee 18 Oct  2 02:34 ./build.sh -> ./project/build.sh

当执行build.sh时候

```bash
#=========================
# build targets
#=========================
trap 'err_handler' ERR
# 获得顶部项目文件,就是luckfox-pico/project
cd $PROJECT_TOP_DIR
# 清除参数,就是cfg下面的BoardConfig*.mk文件中RK_前缀的变量全部为空
unset_board_config_all
if [ "$1" = "lunch" ]; then
	build_select_board LUNCH-FORCE
fi
if [ ! -e "$BOARD_CONFIG" ]; then
	build_select_board
fi
[ -L "$BOARD_CONFIG" ] && source $BOARD_CONFIG
export RK_PROJECT_TOOLCHAIN_CROSS=$RK_TOOLCHAIN_CROSS
export PATH="${SDK_ROOT_DIR}/tools/linux/toolchain/${RK_PROJECT_TOOLCHAIN_CROSS}/bin":$PATH

if [[ "$LF_TARGET_ROOTFS" = "ubuntu" ]]; then
	if [ "$(id -u)" != "0" ]; then
		msg_error "Error! Please use sudo ./build.sh to build Ubuntu Image!"
		exit 1
	fi
	if [[ "$LF_SUBMODULES_BY" = "github" ]]; then
		cp ${SDK_ROOT_DIR}/.gitmodules.github ${SDK_ROOT_DIR}/.gitmodules
	else
		if [[ "$LF_SUBMODULES_BY" = "gitee" ]]; then
			cp ${SDK_ROOT_DIR}/.gitmodules.gitee ${SDK_ROOT_DIR}/.gitmodules
		else
			exit 0
		fi
	fi

	if [ -d "$UBUNTU_DIR" ] && [ -f ${UBUNTU_DIR}/luckfox-ubuntu-22.04.3.tar.gz.md5 ]; then
		msg_info "${UBUNTU_DIR} is not empty, skipping submodule update!"
	else
		msg_info "${UBUNTU_DIR} is empty or does not exist, updateing submodule!"
		git submodule update --init --recursive
	fi
fi

if echo $@ | grep -wqE "help|-h"; then
	if [ -n "$2" -a "$(type -t usage$2)" == function ]; then
		echo "###Current Configure [ $2 ] Build Command###"
		eval usage$2
	else
		usage
	fi
	exit 0
fi

if ! ${RK_PROJECT_TOOLCHAIN_CROSS}-gcc --version &>/dev/null; then
	msg_error "Not found toolchain ${RK_PROJECT_TOOLCHAIN_CROSS}-gcc for [$RK_CHIP] !!!"
	msg_info "Please run these commands to install ${RK_PROJECT_TOOLCHAIN_CROSS}-gcc"
	echo ""
	echo "    cd ${SDK_ROOT_DIR}/tools/linux/toolchain/${RK_PROJECT_TOOLCHAIN_CROSS}/"
	echo "    source env_install_toolchain.sh"
	echo ""
	exit 1
fi

case $RK_PROJECT_TOOLCHAIN_CROSS in
arm-rockchip830-linux-uclibcgnueabihf)
	export RK_LIBC_TPYE=uclibc
	;;
*)
	export RK_LIBC_TPYE=glibc
	;;
esac
export RK_PROJECT_PACKAGE_ROOTFS_DIR=$RK_PROJECT_OUTPUT/rootfs_${RK_LIBC_TPYE}_${RK_CHIP}
export RK_PROJECT_PACKAGE_OEM_DIR=$RK_PROJECT_OUTPUT/oem
export RK_PROJECT_PACKAGE_USERDATA_DIR=$RK_PROJECT_OUTPUT/userdata
export RK_PROJECT_PATH_BOARD_BIN=$RK_PROJECT_PATH_SYSDRV/board_${RK_LIBC_TPYE}_${RK_CHIP}

build_check
__PREPARE_BOARD_CFG

num=$#
option=""
while [ $# -ne 0 ]; do
	case $1 in
	DEBUG) export RK_BUILD_VERSION_TYPE=DEBUG ;;
	all) option=build_all ;;
	save) option=build_save ;;
	allsave) option=build_allsave ;;
	check) option=build_check ;;
	clean)
		option="build_clean $2"
		break
		;;
	firmware) option=build_firmware ;;
	ota) option=build_ota ;;
	updateimg) option=build_updateimg ;;
	unpackimg) option=build_unpack_updateimg ;;
	factory) option=build_factory ;;
	recovery) option=build_recovery ;;
	env) option=build_env ;;
	meta) option=build_meta ;;
	driver) option=build_driver ;;
	sysdrv) option=build_sysdrv ;;
	uboot) option=build_uboot ;;
	kernel) option=build_kernel ;;
	rootfs) option=build_rootfs ;;
	media) option=build_media ;;
	app) option=build_app ;;
	info) option=build_info ;;
	tool) option=build_tool ;;
	buildrootconfig) option=buildroot_config ;;
	kernelconfig) option=kernel_config ;;
	*) option=usage ;;
	esac
	if [ $((num)) -gt 0 ]; then
		shift
	fi
done

eval "${option:-build_allsave}"

有参数时对应选项,无参数时全编译。
全编译

function build_allsave() {
	# rm -rf ${RK_PROJECT_OUTPUT_IMAGE} ${RK_PROJECT_OUTPUT}
	build_all
	build_save

	build_check_power_domain

	finish_build
}
function build_all() {
	echo "============================================"
	echo "TARGET_ARCH=$RK_ARCH"
	echo "TARGET_UBOOT_CONFIG=$RK_UBOOT_DEFCONFIG $RK_UBOOT_DEFCONFIG_FRAGMENT"
	echo "TARGET_SPL_CONFIG=$RK_SPL_DEFCONFIG"
	echo "TARGET_KERNEL_CONFIG=$RK_KERNEL_DEFCONFIG $RK_KERNEL_DEFCONFIG_FRAGMENT"
	echo "TARGET_KERNEL_DTS=$RK_KERNEL_DTS"
	echo "TARGET_RECOVERY_CONFIG=$RK_CFG_RECOVERY"
	echo "TARGET_RAMBOOT_CONFIG=$RK_CFG_RAMBOOT"
	echo "============================================"

	[[ $RK_ENABLE_RECOVERY = "y" ]] && build_recovery
	build_sysdrv
	build_media
	build_app
	build_firmware

	finish_build
}
function build_firmware() {
	check_config RK_PARTITION_CMD_IN_ENV || return 0

	build_env
	build_meta

	mkdir -p ${RK_PROJECT_OUTPUT_IMAGE}

	if [ "$RK_ENABLE_RECOVERY" = "y" -a -f $PROJECT_TOP_DIR/scripts/${RK_MISC:=recovery-misc.img} ]; then
		cp -fv $PROJECT_TOP_DIR/scripts/$RK_MISC ${RK_PROJECT_OUTPUT_IMAGE}/misc.img
	fi

	__PACKAGE_ROOTFS
	__PACKAGE_OEM

	__BUILD_ENABLE_COREDUMP_SCRIPT

	__RUN_PRE_BUILD_OEM_SCRIPT

	if [ "$RK_BUILD_APP_TO_OEM_PARTITION" = "y" ]; then
		rm -rf $RK_PROJECT_PACKAGE_ROOTFS_DIR/oem/*
		mkdir -p $RK_PROJECT_PACKAGE_ROOTFS_DIR/oem
		build_mkimg $GLOBAL_OEM_NAME $RK_PROJECT_PACKAGE_OEM_DIR
	else
		mkdir -p $RK_PROJECT_PACKAGE_ROOTFS_DIR/oem
		__COPY_FILES $RK_PROJECT_PACKAGE_OEM_DIR $RK_PROJECT_PACKAGE_ROOTFS_DIR/oem
		rm -rf $RK_PROJECT_PACKAGE_OEM_DIR
	fi

	__RUN_POST_BUILD_SCRIPT
	post_overlay

	if [ -n "$GLOBAL_INITRAMFS_BOOT_NAME" ]; then
		build_mkimg boot $RK_PROJECT_PACKAGE_ROOTFS_DIR
	fi

	if [ "$RK_ENABLE_FASTBOOT" = "y" ]; then
		build_mkimg boot $RK_PROJECT_PACKAGE_ROOTFS_DIR
	else
		build_mkimg $GLOBAL_ROOT_FILESYSTEM_NAME $RK_PROJECT_PACKAGE_ROOTFS_DIR
	fi

	# package a empty userdata parition image
	mkdir -p $RK_PROJECT_PACKAGE_USERDATA_DIR
	build_mkimg userdata $RK_PROJECT_PACKAGE_USERDATA_DIR

	build_tftp_sd_update

	[ "$RK_ENABLE_RECOVERY" = "y" -o "$RK_ENABLE_OTA" = "y" ] && build_ota
	build_updateimg

	# Spi_nand mklink
	if [ "${RK_BOOT_MEDIUM}" == "spi_nand" ]; then
		msg_info "MEDIUM SPI_NAND relink Image"
		files=("${RK_PROJECT_OUTPUT_IMAGE}/oem.img"
			"${RK_PROJECT_OUTPUT_IMAGE}/rootfs.img"
			"${RK_PROJECT_OUTPUT_IMAGE}/userdata.img")
		for file in "${files[@]}"; do
			if [ -e "$file" ]; then
				filename=$(basename "$file")
				target=$(readlink -f "$file")
				rm "$file"
				mv "$target" "$RK_PROJECT_OUTPUT_IMAGE/$filename"
			fi
		done
		find "${RK_PROJECT_OUTPUT_IMAGE}" -type f -name "*.ubi" -exec rm {} +
	fi
	finish_build
}

__PACKAGE_OEM 打包oem
在这里,创建了oem的目录,创建了启动文件
export RK_PROJECT_FILE_OEM_SCRIPT=$RK_PROJECT_OUTPUT/S21appinit

function __PACKAGE_OEM() {
	mkdir -p $RK_PROJECT_PACKAGE_OEM_DIR
	__PACKAGE_RESOURCES $RK_PROJECT_PACKAGE_OEM_DIR
	if [ -d "$RK_PROJECT_PACKAGE_OEM_DIR/usr/share/iqfiles" ]; then
		(
			cd $RK_PROJECT_PACKAGE_ROOTFS_DIR/etc
			ln -sf ../oem/usr/share/iqfiles ./
		)
	fi

	mkdir -p $(dirname $RK_PROJECT_FILE_OEM_SCRIPT)
	cat >$RK_PROJECT_FILE_OEM_SCRIPT <<EOF
#!/bin/sh
[ -f /etc/profile.d/RkEnv.sh ] && source /etc/profile.d/RkEnv.sh
case \$1 in
	start)
		sh /oem/usr/bin/RkLunch.sh
		;;
	stop)
		sh /oem/usr/bin/RkLunch-stop.sh
		;;
	*)
		exit 1
		;;
esac
EOF
	chmod a+x $RK_PROJECT_FILE_OEM_SCRIPT
	cp -f $RK_PROJECT_FILE_OEM_SCRIPT $RK_PROJECT_PACKAGE_ROOTFS_DIR/etc/init.d
}

__PACKAGE_RESOURCES $RK_PROJECT_PACKAGE_OEM_DIR 创建oem目录

function __PACKAGE_RESOURCES() {
	local _iqfiles_dir _install_dir _target_dir _avs_calib_install_dir _avs_calib_src
	_target_dir="$1"
	if [ ! -d $_target_dir ]; then
		msg_error "Not found target dir: $_target_dir"
		exit 1
	fi

	#创建两个文件夹
	_install_dir=$_target_dir/usr
	_iqfiles_dir=$_install_dir/share/iqfiles

	#复制$SDK_ROOT_DIR/output/out/sysdrv_out的驱动
	__COPY_FILES $RK_PROJECT_PATH_SYSDRV/kernel_drv_ko/ $_install_dir/ko

	#复制app的内容
	__COPY_FILES $RK_PROJECT_PATH_APP/bin $_install_dir/bin/
	__COPY_FILES $RK_PROJECT_PATH_APP/lib $_install_dir/lib/
	__COPY_FILES $RK_PROJECT_PATH_APP/share $_install_dir/share/
	__COPY_FILES $RK_PROJECT_PATH_APP/usr $_install_dir/
	__COPY_FILES $RK_PROJECT_PATH_APP/etc $_install_dir/etc/

	#复制media的内容
	__COPY_FILES $RK_PROJECT_PATH_MEDIA/bin $_install_dir/bin/
	__COPY_FILES $RK_PROJECT_PATH_MEDIA/lib $_install_dir/lib/
	__COPY_FILES $RK_PROJECT_PATH_MEDIA/share $_install_dir/share/
	__COPY_FILES $RK_PROJECT_PATH_MEDIA/usr $_install_dir/

	if [ -n "$RK_AVS_CALIB" ]; then
		_avs_calib_src=$(find $RK_PROJECT_PATH_MEDIA -name $RK_AVS_CALIB -type f)
		if [ -n "$_avs_calib_src" ]; then
			_avs_calib_install_dir=$_install_dir/share/avs_calib
			mkdir -p $_avs_calib_install_dir
			cp -rfa $_avs_calib_src $_avs_calib_install_dir/calib_file.pto
		fi
	fi

	if [ -n "$RK_AVS_LUT" ]; then
		_avs_lut_src=$(find $RK_PROJECT_PATH_MEDIA -name $RK_AVS_LUT)
		if [ -n "$_avs_lut_src" ]; then
			_avs_lut_install_dir=$_install_dir/share/middle_lut
			mkdir -p $_avs_lut_install_dir
			cp -rfa $_avs_lut_src $_avs_lut_install_dir/
		fi
	fi

	mkdir -p $_iqfiles_dir
	if [ -n "$RK_CAMERA_SENSOR_IQFILES" ]; then
		IFS=" "
		for item in $(echo $RK_CAMERA_SENSOR_IQFILES); do
			if [ -f "$RK_PROJECT_PATH_MEDIA/isp_iqfiles/$item" ]; then
				cp -rfa $RK_PROJECT_PATH_MEDIA/isp_iqfiles/$item $_iqfiles_dir
			fi
		done
		IFS=
	else
		msg_warn "Not found RK_CAMERA_SENSOR_IQFILES on the $(realpath $BOARD_CONFIG), copy all default for emmc, sd-card or nand"
		if [ "$RK_BOOT_MEDIUM" != "spi_nor" ]; then
			cp -rfa $RK_PROJECT_PATH_MEDIA/isp_iqfiles/* $_iqfiles_dir
		fi
	fi

	if [ -n "$RK_CAMERA_SENSOR_CAC_BIN" ]; then
		IFS=" "
		for item in $(echo $RK_CAMERA_SENSOR_CAC_BIN); do
			if [ -d "$RK_PROJECT_PATH_MEDIA/isp_iqfiles/$item" ]; then
				cp -rfa $RK_PROJECT_PATH_MEDIA/isp_iqfiles/$item $_iqfiles_dir
			fi
		done
		IFS=
	fi
}

在$RK_PROJECT_PACKAGE_OEM_DIR基础上打包oem分区

if [ "$RK_BUILD_APP_TO_OEM_PARTITION" = "y" ]; then
		rm -rf $RK_PROJECT_PACKAGE_ROOTFS_DIR/oem/*
		mkdir -p $RK_PROJECT_PACKAGE_ROOTFS_DIR/oem
		build_mkimg $GLOBAL_OEM_NAME $RK_PROJECT_PACKAGE_OEM_DIR
	else
LuckFox Pico是一款基于ARM架构的嵌入式开发板,它支持烧录Linux操作系统。下面是烧录LinuxLuckFox Pico的一般步骤: 1. 准备开发环境:首先,你需要安装交叉编译工具链和相关的开发工具,例如GCC编译器、Make工具等。 2. 获取Linux内核源代码:你可以从Linux内核官方网站或者其他适配了LuckFox Pico的开源项目中获取适用于该开发板的Linux内核源代码。 3. 配置内核:进入内核源代码目录,使用交叉编译工具链进行配置。你可以使用make menuconfig命令来选择适合LuckFox Pico的配置选项,例如选择正确的处理器架构、设备驱动等。 4. 编译内核:使用make命令进行内核编译。这个过程可能需要一些时间,取决于你的电脑性能和内核源代码的大小。 5. 生成根文件系统:除了内核,你还需要一个根文件系统来运行Linux。你可以选择使用已有的根文件系统,或者自己构建一个。根文件系统包含了Linux所需的各种库、工具和配置文件。 6. 烧录内核和根文件系统:将编译好的内核和根文件系统烧录到LuckFox Pico的存储介质中,例如SD卡或者eMMC。你可以使用烧录工具,如dd命令或者专门的烧录软件来完成这个步骤。 7. 启动LuckFox Pico:将烧录好的存储介质插入LuckFox Pico,然后通过串口或者其他方式连接到开发板。启动开发板后,它将加载内核并运行Linux操作系统。 希望以上步骤对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值