鸿蒙移植i.mx6ull (七) Liteos-a的编译系统(上)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 鸿蒙移植i.mx6ull (七) Liteos-a的编译系统

Liteos-a编译系统分析


1.1 怎么编译子目录


以kernel/liteos_a/fs/fat/Makefile为例:

# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
#    conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
#    of conditions and  he following disclaimer in the documentation and/or other materials
#    provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
#    to endorse or promote products derived from this software without specific prior written
#    permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
include $(LITEOSTOPDIR)/config.mk 
MODULE_NAME := $(notdir $(shell pwd))//当前目录fat
LOCAL_SRCS := $(wildcard os_adapt/*.c)//
LOCAL_SRCS += $(wildcard $(LITEOSTHIRDPARTY)/FatFs/source/*.c)
LOCAL_INCLUDE := \
    -I $(LITEOSTHIRDPARTY)/FatFs/source \
    -I $(LITEOSTOPDIR)/fs/fat/virpart/include
LOCAL_FLAGS := $(LOCAL_INCLUDE) $(LITEOS_GCOV_OPTS)
include $(MODULE)
~                                                                                                  
~


第1行包含config.mk

这是包含一些预先定义的变量,比如默认的编译选项等。


下面的代码定义了LOCAL_SRCS

等于一系列C文件,这就是要编译的源文件。


定义了LOCAL_INCLUDE


这是头文件的目录


定义了LOCAL_FLAGS


这是编译选项


定义了MODULE_NAME

一般等于当前目录的名字,比如fat,以后就编译得到libfat.a


怎么编译?看最后一行

include $(MODULE)


MODULE就是:

MODULE = $(MK_PATH)/module.mk  # kernel/liteos_a/tools/build/mk/module.mk

分析module.mk:

# 找到第1个目标
all : $(LIB)
# LIB是什么, 如果没定义LOCAL_SO,LIB就是 lib$(MODULE_NAME).a, 比如 libfat.a
ifeq ($(LOCAL_SO), y)
LIBSO := $(OUT)/lib/lib$(MODULE_NAME).so
LIBA := $(OUT)/lib/lib$(MODULE_NAME).a
else
LIBSO :=
LIBA := $(OUT)/lib/lib$(MODULE_NAME).a
endif
LIB := $(LIBA) $(LIBSO)
# 怎么编译 LIBA ? 看下图

1671000423309.jpg


1.2 编译哪些子目录


1.2.1 从链接命令看内核的组成


链接命令如下


liteos-a由一系列的库文件组成,reset_vector是它的入口。

1671000441647.jpg

查看链接脚本

vi /home/book/openharmony/kernel/liteos_a/tools/build/liteos_llvm.ld

1671000457334.jpg


查看入口:

grep "reset_vector" * -nwr

1671000474121.jpg

1671000481083.jpg

查看liteos.map文件

1671000489904.jpg


1.2.2 从Makefile开始分析


从链接命令查看内核的组成,是一个取巧的方法。

本质的方法应该是从kernel/liteos_a/Makefile开始分析。


1.3 顶层Makefile分析


指的是kernel/liteos_a/Makefile。


下面是完整的liteos的makefile

# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
#    conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
#    of conditions and the following disclaimer in the documentation and/or other materials
#    provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
#    to endorse or promote products derived from this software without specific prior written
#    permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
LITEOSTOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
export OS=$(shell uname -s)
ifneq ($(OS), Linux)
LITEOSTOPDIR := $(shell dirname $(subst \,/,$(LITEOSTOPDIR))/./)
endif
LITEOSTHIRDPARTY := $(LITEOSTOPDIR)/../../third_party
export LITEOSTOPDIR
export LITEOSTHIRDPARTY
-include $(LITEOSTOPDIR)/tools/build/config.mk
RM = -rm -rf
MAKE = make
__LIBS = libs
APPS = apps
ROOTFSDIR = rootfsdir
ROOTFS = rootfs
LITEOS_TARGET = liteos
LITEOS_LIBS_TARGET = libs_target
LITEOS_MENUCONFIG_H = $(LITEOSTOPDIR)/include/generated/autoconf.h
LITEOS_PLATFORM_BASE = $(LITEOSTOPDIR)/platform
LITEOS_PLATFORM_MENUCONFIG_H = $(LITEOS_PLATFORM_BASE)/include/menuconfig.h
ifeq ($(LOSCFG_PLATFORM_HI3518EV300), y)
FSTYPE = jffs2
endif
ifeq ($(LOSCFG_PLATFORM_HI3516DV300), y)
FSTYPE = vfat
endif
ifeq ($(LOSCFG_PLATFORM_IMX6ULL), y)
FSTYPE = jffs2
endif
ifeq ($(LOSCFG_PLATFORM_STM32MP157), y)
FSTYPE = jffs2
ROOTFS_SIZE = 0xA00000
endif
ROOTFS_DIR = $(OUT)/rootfs
ROOTFS_ZIP = $(OUT)/rootfs.zip
VERSION =
all: $(OUT) $(BUILD) $(LITEOS_TARGET) $(APPS)
lib: $(OUT) $(BUILD) $(LITEOS_LIBS_TARGET)
help:
  $(HIDE)echo "-------------------------------------------------------"
  $(HIDE)echo "1.====make help:    get help infomation of make"
  $(HIDE)echo "2.====make:         make a debug version based the .config"
  $(HIDE)echo "3.====make debug:   make a debug version based the .config"
  $(HIDE)echo "4.====make release: make a release version for all platform"
  $(HIDE)echo "5.====make release PLATFORM=xxx:  make a release version only for platform xxx"
  $(HIDE)echo "6.====make rootfsdir: make a original rootfs dir"
  $(HIDE)echo "7.====make rootfs FSTYPE=***: make a original rootfs img"
  $(HIDE)echo "8.====make test: make the testsuits_app and put it into the rootfs dir"
  $(HIDE)echo "9.====make test_apps FSTYPE=***: make a rootfs img with the testsuits_app in it"
  $(HIDE)echo "xxx should be one of (hi3516cv300 hi3516ev200 hi3556av100/cortex-a53_aarch32 hi3559av100/cortex-a53_aarch64)"
  $(HIDE)echo "*** should be one of (jffs2)"
  $(HIDE)echo "-------------------------------------------------------"
debug:
  $(HIDE)echo "=============== make a debug version  ==============="
  $(HIDE) $(MAKE) all
release:
ifneq ($(PLATFORM),)
  $(HIDE)echo "=============== make a release version for platform $(PLATFORM) ==============="
  $(HIDE)$(SCRIPTS_PATH)/mklibversion.sh $(PLATFORM)
else
  $(HIDE)echo "================make a release version for all platform ==============="
  $(HIDE)$(SCRIPTS_PATH)/mklibversion.sh
endif
##### make dynload #####
-include $(LITEOS_MK_PATH)/dynload.mk
#-----need move when make version-----#
##### make lib #####
$(__LIBS): $(OUT) $(CXX_INCLUDE)
ifeq ($(LOSCFG_PLATFORM_IMX6ULL),y)
BOARD_INCLUDE_DIR := $(LITEOSTOPDIR)/../../vendor/nxp/imx6ull/board
else ifeq ($(LOSCFG_PLATFORM_STM32MP157), y)
BOARD_INCLUDE_DIR := $(LITEOSTOPDIR)/../../vendor/st/stm32mp157/board
else
BOARD_INCLUDE_DIR := $(LITEOSTOPDIR)/../../vendor/hisi/hi35xx/$(LITEOS_PLATFORM)/config/board
endif
$(OUT): $(LITEOS_MENUCONFIG_H)
  $(HIDE)mkdir -p $(OUT)/lib
  $(HIDE)$(CC) -I$(LITEOS_PLATFORM_BASE)/include -I$(BOARD_INCLUDE_DIR) \
  -E $(LITEOS_PLATFORM_BASE)/board.ld.S \
  -o $(LITEOS_PLATFORM_BASE)/board.ld -P
$(BUILD):
  $(HIDE)mkdir -p $(BUILD)
$(LITEOS_LIBS_TARGET): $(__LIBS)
  $(HIDE)for dir in $(LIB_SUBDIRS); \
  do $(MAKE) -C $$dir all || exit 1; \
  done
  $(HIDE)echo "=============== make lib done  ==============="
##### make menuconfig #####
export CONFIG_=LOSCFG_
MENUCONFIG_PATH = $(LITEOSTOPDIR)/tools/menuconfig
KCONFIG_FILE_PATH = $(LITEOSTOPDIR)/Kconfig
menuconfig:$(MENUCONFIG_PATH)/mconf
  $< $(KCONFIG_FILE_PATH)
genconfig:$(MENUCONFIG_PATH)/conf
  $(HIDE)mkdir -p include/config include/generated
  $< --silentoldconfig $(KCONFIG_FILE_PATH)
  -mv -f $(LITEOS_MENUCONFIG_H) $(LITEOS_PLATFORM_MENUCONFIG_H)
##### menuconfig end #######
$(LITEOS_MENUCONFIG_H):
ifneq ($(LITEOS_PLATFORM_MENUCONFIG_H), $(wildcard $(LITEOS_PLATFORM_MENUCONFIG_H)))
  $(HIDE)$(MAKE) genconfig
endif
$(LITEOS_TARGET): $(__LIBS)
  $(HIDE)touch $(LOSCFG_ENTRY_SRC)
  $(HIDE)for dir in $(LITEOS_SUBDIRS); \
  do $(MAKE) -C $$dir all || exit 1; \
  done
  $(LD) $(LITEOS_LDFLAGS) $(LITEOS_TABLES_LDFLAGS) $(LITEOS_DYNLDFLAGS) -Map=$(OUT)/$@.map -o $(OUT)/$@ --start-group $(LITEOS_LIBDEP) --end-group
# $(SIZE) -t --common $(OUT)/lib/*.a >$(OUT)/$@.objsize
  $(OBJCOPY) -O binary $(OUT)/$@ $(LITEOS_TARGET_DIR)/$@.bin
ifeq ($(LOSCFG_PLATFORM_STM32MP157), y)
  mkimage.stm32 -T stm32image -a 0xC0100000 -e 0xC0100000 -d $(LITEOS_TARGET_DIR)/$@.bin $(LITEOS_TARGET_DIR)/liteos.stm32
  mkimage.stm32 -A arm -O linux -T kernel -C none -a 0xC0100000 -e 0xC0100000 -n liteos-a -d $(LITEOS_TARGET_DIR)/$@.bin $(LITEOS_TARGET_DIR)/liteos_with_uboot_header.bin
endif
  $(OBJDUMP) -t $(OUT)/$@ |sort >$(OUT)/$@.sym.sorted
  $(OBJDUMP) -d $(OUT)/$@ >$(OUT)/$@.asm
# $(NM) -S --size-sort $(OUT)/$@ >$(OUT)/$@.size
$(APPS): $(LITEOS_TARGET)
  $(HIDE)$(MAKE) -C apps all
prepare:
  $(HIDE)mkdir -p $(OUT)/musl
ifeq ($(LOSCFG_COMPILER_CLANG_LLVM), y)
  $(HIDE)cp -f $(LITEOSTOPDIR)/../../prebuilts/lite/sysroot/usr/lib/$(LLVM_TARGET)/a7_softfp_neon-vfpv4/libc.so $(OUT)/musl
  $(HIDE)cp -f $(LITEOS_COMPILER_PATH)/lib/$(LLVM_TARGET)/c++/a7_softfp_neon-vfpv4/libc++.so $(OUT)/musl
else
  $(HIDE)cp -f $(LITEOS_COMPILER_PATH)/target/usr/lib/libc.so $(OUT)/musl
  $(HIDE)cp -f $(LITEOS_COMPILER_PATH)/arm-linux-musleabi/lib/libstdc++.so.6 $(OUT)/musl
  $(HIDE)cp -f $(LITEOS_COMPILER_PATH)/arm-linux-musleabi/lib/libgcc_s.so.1 $(OUT)/musl
  $(STRIP) $(OUT)/musl/*
endif
$(ROOTFSDIR): prepare $(APPS)
  $(HIDE)$(MAKE) clean -C apps
  $(HIDE)$(shell $(LITEOSTOPDIR)/tools/scripts/make_rootfs/rootfsdir.sh $(OUT)/bin $(OUT)/musl $(ROOTFS_DIR))
ifneq ($(VERSION),)
  $(HIDE)$(shell $(LITEOSTOPDIR)/tools/scripts/make_rootfs/releaseinfo.sh "$(VERSION)" $(ROOTFS_DIR))
endif
$(ROOTFS): $(ROOTFSDIR)
  $(HIDE)$(shell $(LITEOSTOPDIR)/tools/scripts/make_rootfs/rootfsimg.sh $(ROOTFS_DIR) $(FSTYPE)  ${ROOTFS_SIZE})
  $(HIDE)cd $(ROOTFS_DIR)/.. && zip -r $(ROOTFS_ZIP) $(ROOTFS)
ifneq ($(OUT), $(LITEOS_TARGET_DIR))
  $(HIDE)mv $(ROOTFS_DIR) $(LITEOS_TARGET_DIR)rootfs
endif
clean:
  $(HIDE)for dir in $(LITEOS_SUBDIRS); \
  do $(MAKE) -C $$dir clean|| exit 1; \
  done
  $(HIDE)$(MAKE) -C apps clean
  $(HIDE)$(RM) $(__OBJS) $(LITEOS_TARGET) $(OUT) $(BUILD) $(LITEOS_MENUCONFIG_H) *.bak *~
  $(HIDE)$(RM) $(LITEOS_PLATFORM_MENUCONFIG_H)
  $(HIDE)$(RM) include
  $(HIDE)$(MAKE) cleanrootfs
  $(HIDE)echo "clean $(LITEOS_PLATFORM) finish"
cleanall:
  $(HIDE)$(RM) $(LITEOSTOPDIR)/out
  $(HIDE)find $(LITEOS_PLATFORM_BASE)/ -name board.ld -exec rm -rf {} \;
  $(HIDE)cd sample/sample_osdrv;make clean;cd ../..;
  $(HIDE)echo "clean all"
cleanrootfs:
  $(HIDE)$(RM) $(OUT)/rootfs
  $(HIDE)$(RM) $(OUT)/rootfs.zip
  $(HIDE)$(RM) $(OUT)/rootfs.img
.PHONY: all lib clean cleanall $(LITEOS_TARGET) debug release help
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
打赏
0
0
0
0
15
分享
相关文章
HarmonyOS应用安全全攻略:从系统到代码的全面防护
本文全面解析HarmonyOS应用安全开发,涵盖系统到代码的防护策略。首先介绍HarmonyOS三层安全体系:系统安全层、开发工具层与应用生态层。接着详解设备与数据安全等级划分,提供分级加密实战代码,包括文件读写与HUKS高级加密案例。最后总结开发最佳实践,强调数据分类、最小权限、加密常态及传输安全保障,助你构建更安全的应用。保护用户数据不仅是功能需求,更是开发者责任!
40 0
鸿蒙开发:hvigorw,编译构建,实现命令打包
以上呢,就是hvigorw几个常见的命令,主要用于构建不同类型的包,也是接下来流水线打包,几个比较常用的命令,所以拿来重点概述了,当然了hvigorw还有一些常见的命令,大家直接看官网介绍即可,不在多赘述。
鸿蒙开发:hvigorw,编译构建,实现命令打包
鸿蒙系统被抹黑的深层解析:技术、商业与地缘政治的复杂博弈-优雅草卓伊凡
鸿蒙系统被抹黑的深层解析:技术、商业与地缘政治的复杂博弈-优雅草卓伊凡
113 1
鸿蒙系统被抹黑的深层解析:技术、商业与地缘政治的复杂博弈-优雅草卓伊凡
对鸿蒙 Next 系统“成熟论”的深度剖析-优雅草卓伊凡
对鸿蒙 Next 系统“成熟论”的深度剖析-优雅草卓伊凡
90 10
对鸿蒙 Next 系统“成熟论”的深度剖析-优雅草卓伊凡
HarmonyOS NEXT~鸿蒙系统下的Cordova框架应用开发指南
《HarmonyOS NEXT:鸿蒙系统下的Cordova框架应用开发指南》详细介绍如何将Cordova应用适配到鸿蒙系统。文章涵盖兼容性分析、环境配置、特性适配、性能优化及发布调试等内容。尽管Cordova官方暂无直接支持,但通过Cordova-Android平台与定制插件可实现功能扩展。开发者需注意性能差异,并借助插件机制融入鸿蒙特色功能,如服务卡片和分布式能力。未来,随着鸿蒙生态完善,Cordova在该平台的应用将更加广泛且高效。
147 1
【03】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-在lib目录新建自定义库UtilsLibrary,ComponentLibrary,CommonConstLibrary完成设置SettingsView.ets初始公共类书写-优雅草卓伊凡
【03】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-在lib目录新建自定义库UtilsLibrary,ComponentLibrary,CommonConstLibrary完成设置SettingsView.ets初始公共类书写-优雅草卓伊凡
125 23
【03】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-在lib目录新建自定义库UtilsLibrary,ComponentLibrary,CommonConstLibrary完成设置SettingsView.ets初始公共类书写-优雅草卓伊凡
鸿蒙系统”套壳论”的认知迷思与技术真相-优雅草卓伊凡
鸿蒙系统”套壳论”的认知迷思与技术真相-优雅草卓伊凡
86 0
鸿蒙系统”套壳论”的认知迷思与技术真相-优雅草卓伊凡
HarmonyOS NEXT~鸿蒙系统与mPaaS三方框架集成指南
本文详细介绍了鸿蒙系统(HarmonyOS)与mPaaS框架的集成方法。鸿蒙系统作为华为开发的分布式操作系统,具备分布式架构、微内核设计等特性;mPaaS是蚂蚁金服推出的移动开发平台,提供金融级组件和全生命周期管理能力。文章从环境准备、核心功能集成(如初始化、用户认证、支付功能)、适配问题解决到调试测试及最佳实践,全方位指导开发者高效集成两者。通过遵循指南,可充分利用鸿蒙的特性和mPaaS的金融能力,构建高性能、高安全性的应用,同时避免常见兼容性问题,缩短开发周期。
108 0
HarmonyOS NEXT~鸿蒙系统与Uniapp跨平台开发实践指南
本书《HarmonyOS NEXT~鸿蒙系统与Uniapp跨平台开发实践指南》深入探讨了华为鸿蒙系统(HarmonyOS)与Uniapp框架的融合应用。书中首先介绍了鸿蒙系统的分布式架构特点及其原子化服务理念,随后详细讲解了Uniapp在鸿蒙环境下的适配方案,包括开发环境配置、特有配置项设置以及条件编译调用鸿蒙原生能力的方法。此外,还提供了界面适配策略、性能优化建议及调试发布流程,帮助开发者高效构建多端协同应用。最后展望了鸿蒙生态未来的发展方向,如ArkUI-X的深度集成和全新API能力的应用前景。
119 0
【05】20250416优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-增加告警中心相关卡片页面WarningCardWidget相关-增加Canvas 绘制折线图-Canvas 绘制柱状图-首页-优雅草卓伊凡
【05】20250416优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-增加告警中心相关卡片页面WarningCardWidget相关-增加Canvas 绘制折线图-Canvas 绘制柱状图-首页-优雅草卓伊凡
77 0
【05】20250416优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-增加告警中心相关卡片页面WarningCardWidget相关-增加Canvas 绘制折线图-Canvas 绘制柱状图-首页-优雅草卓伊凡
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问