新闻详情

新闻详情

首页 / 资讯中心 / 详情

Petalinux实战指南:ZYNQ嵌入式Linux系统定制与启动全解析

发布时间:2026/9/28 15:28:11来源:尧图网络
Petalinux实战指南:ZYNQ嵌入式Linux系统定制与启动全解析
裸机跑通了Linux起不来我懂这种感觉。ZYNQ的双核ARM Cortex-A9和FPGA逻辑放在同一颗芯片里裸机环境下自己写写外设驱动、跑跑DMA逻辑还算是顺手。但一旦产品需求变成“要有文件系统、要跑网络协议栈、要能在应用层做业务”Linux就成了绕不过去的坎。而Petalinux这套工具就是Xilinx官方给出的“帮你把Linux搬上ZYNQ”的标准路径——它本质上是对Yocto Project的深度封装把内核、U-Boot、设备树、根文件系统这一整套东西的构建过程都固化成了模板和命令。我手上这块ZYNQ-7020开发板用了挺长时间从Vivado 2023.1建硬件工程到Petalinux 2023.1定制系统镜像再到SD卡启动、添加自研驱动中间踩过的坑能写满一页A4纸。这篇文章就是我个人实践的全流程梳理重点放在“版本怎么匹配”“命令怎么用”“报错怎么查”这三件最磨人的事上。适合两类人看一是刚接触Petalinux、被官方文档绕晕的初学者二是已经在用但被某个构建报错卡住、想快速定位问题的开发者。1. 环境准备与版本匹配1.1 为什么必须强调版本对应先把这个最容易忽略的问题放最前面Petalinux和Vivado的版本号必须严格对应。2023.1版本的Petalinux就要配合Vivado 2023.1导出的硬件描述文件XSA使用。如果你用Vivado 2022.2建工程导出XSA后拿给Petalinux 2023.1去导入大概率会在设备树生成阶段报一些莫名其妙的问题比如“xsa_parser”解析失败、U-Boot配置时找不到某个外设节点。原因在于XSA文件里不仅包含硬件连接信息还包含Vivado版本相关的元数据。Petalinux在导入XSA时会按版本规则去解释这些元数据。版本错位时底层库容易解析错位报错信息又往往不直接提示“版本不匹配”而是抛出类似“ERROR: Failed to parse XSA file”这种让人一头雾水的提示。我个人的做法是先在Vivado里查Help - About确认版本号再对照Petalinux官方Release Notes找匹配版本。Vivado 2023.1配Petalinux 2023.1Vivado 2023.2配Petalinux 2023.2别跳版本。另外同一台机器上如果要装多个版本的Petalinux建议分别放在不同目录比如/opt/petalinux/2023.1和/opt/petalinux/2023.2用哪个版本就source哪个环境。1.2 宿主机环境与依赖安装Petalinux本质上依赖Yocto构建系统Yocto对宿主机环境要求是出了名的挑剔。2023.1版本官方支持Ubuntu 20.04和22.04LTS版本我用的是Ubuntu 22.04.3跑下来整体稳定。系统内存建议16GB以上磁盘空间至少100GBYocto构建中间产物非常大构建时CPU多核编译非常吃内存8GB内存的机器建议同时开-j的并行度调低一点否则编到一半内存不足直接OOM。在安装Petalinux之前先更新系统并安装依赖包。官方文档给了一长串我整理成实际够用的一套sudo apt update sudo apt install -y \ build-essential gcc g make net-tools \ libncurses5-dev libncursesw5-dev zlib1g-dev \ libssl-dev libtinfo-dev bison flex \ file python3 python3-pip python3-venv \ iproute2 gawk xz-utils diffstat \ texinfo telnet chrpath socat \ libegl1-mesa libgl1-mesa-glx libgmp-dev \ libmpc-dev libmpfr-dev libftdi1-2 \ lib32z1 lib32stdc6 libc6-dev-i386 \ unzip dos2unix tftpd-hpalibncurses这个包特别容易漏。漏了的话在petalinux-config -c kernel打开menuconfig界面时会直接报“menuconfig requires ncurses development files”的错误一脸懵的人不在少数。还有一个老坑Ubuntu默认的/bin/sh指向的是dash而不是bashPetalinux的很多脚本依赖bash特性。发现Perl相关脚本报错时先执行sudo dpkg-reconfigure dash在弹窗里选“No”不将dash作为默认shell这个步骤非常重要。1.3 安装与首次Source安装包一般是一个.run文件比如petalinux-v2023.1-1013-installer.run。下载后先给执行权限然后运行安装chmod x petalinux-v2023.1-1013-installer.run ./petalinux-v2023.1-1013-installer.run --dir /opt/petalinux/2023.1安装过程会要求你同意License直接输入y回车即可。装完后记得把安装目录软链一下方便后续使用sudo ln -s /opt/petalinux/2023.1 /opt/petalinux每次打开新终端都要先source环境变量才能使用petalinux命令source /opt/petalinux/settings.sh这一步漏掉的后果非常典型终端里输入petalinux-create会提示“command not found”。很多教程默认你source过但新手真的很容易在这卡住。我的习惯是把这一行写进~/.bashrc末尾这样每次开终端就自动生效省得忘。2. 用XSA文件创建Petalinux工程2.1 硬件工程导出的关键选项Petalinux工程的起点是Vivado里导出的XSA硬件描述文件。很多人在这一步就踩坑导出时没勾选“Include bitstream”导致后期打包BOOT.BIN时找不到FPGA配置文件启动后PL侧逻辑完全不工作。正确的导出流程是在Vivado里完成RTL设计、地址分配、管脚约束后先Generate Bitstream生成比特流然后File - Export Hardware弹窗里必须勾选“Include bitstream”导出成功后得到一个.xsa文件。我一般把它命名为system.xsa放在一个专门的硬件导出目录里方便Petalinux工程引用。还要检查一个容易被忽略的点ZYNQ的PS配置里DDR型号是否正确、UART是否勾选并分配了管脚、SDIO接口是否启用。这些信息都会在Petalinux配置阶段直接影响U-Boot和设备树的生成。比如DDR型号选错了后面启动到U-Boot阶段会在DDR初始化时报错表现为串口输出一段错误后反复重启。2.2 创建工程并导入硬件配置拿到XSA文件后回到终端先创建一个Petalinux工程。ZYNQ系列用的是zynq模板针对ZYNQ-7000的ARM Cortex-A9注意区分Cortex-A53的zynqMP模板source /opt/petalinux/settings.sh petalinux-create -t project --template zynq --name zynq_linux cd zynq_linux创建完成后工程目录里有一个project-spec/文件夹后续所有定制都围绕这个目录展开。接着导入硬件配置petalinux-config --get-hw-description../xsa_dir/这里的../xsa_dir/是存放system.xsa文件的目录路径。执行后会自动进入一个图形化配置界面。第一次进来别乱动但有几个地方要确认Subsystem AUTO Hardware Settings - MemoryDDR大小和型号自动读取自XSA确认和你板子一致Linux Components Selection默认会选linux-xlnx内核保持默认即可Auto Config Settings - U-Boot默认的U-Boot配置会打开串口控制台确认串口编号和你板子上的UART编号一致一般是uart0配置完成后选择“Save”然后“Exit”工具会开始生成设备树和U-Boot配置这一步会编译基础代码耗时看机器性能一般几分钟到十几分钟。2.3 配置内核、设备树与根文件系统的入口工程导入成功后三个核心定制入口分别是内核配置petalinux-config -c kernel进入内核menuconfig界面根文件系统配置petalinux-config -c rootfs选择要打包进镜像的软件包设备树修改手动编辑project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi这三个入口我几乎每个项目都会用到。比如内核要加某个驱动模块就在menuconfig里把对应的m或y打开根文件系统要支持SSH登录就要在rootfs配置里勾选openssh等包如果板子上的外设没有对应的内核驱动就得在system-user.dtsi里补设备树节点。2.4 构建与打包镜像所有配置完成后执行构建petalinux-build这个命令会编译内核、U-Boot、设备树和整个根文件系统。首次构建因为要下载大量源码包、编译工具链耗时非常长实测i7-12700的机器大概要40分钟到1小时。构建完成后镜像文件生成在images/linux/目录下重点看两个文件image.ub内核设备树根文件系统的组合镜像和u-boot.elfU-Boot固件。最后一步生成BOOT.BIN这种Bin文件是ZYNQ启动时BootROM加载的第一阶段镜像里面包含FSBLFirst Stage Boot Loader、FPGA比特流和U-Bootpetalinux-package --boot --fsbl images/linux/zynq_fsbl.elf --fpga images/linux/system.bit --u-boot --force注意--fsbl参数默认会去images/linux/下找zynq_fsbl.elf如果在Vivado里没有生成FSBL相关文件需要先去Vivado里从工程导出。生成完成后images/linux/BOOT.BIN就是SD卡启动要用的第一个文件。3. 定制内核实战从内核模块到根文件系统3.1 修改内核配置的正确方式内核配置用petalinux-config -c kernel进入的其实是Linux内核的menuconfig界面。很多人习惯在里面一通勾选但忽略了保存的位置。实际上配置结果会被保存到project-spec/meta-user/recipes-kernel/linux/linux-xlnx/user_ config这个文件里而不是直接写入内核源码树。我建议的方式是进入menuconfig把需要的选项改好后先“Save”到默认路径再“Exit”。退出后检查一下user_ config文件是否更新了。如果后续修改了硬件或者换了XSA重新执行petalinux-config --get-hw-description有可能会覆盖内核配置所以定制过内核的工程最好手动备份一份这个配置文件。常见的内核定制需求举几个例子支持USB存储设备CONFIG_USB_STORAGE、支持FAT文件系统CONFIG_FAT_FS、支持U盘自动挂载CONFIG_AUTOFS_FS、添加某个具体网卡芯片的驱动。这些都是在menuconfig里通过路径寻找并勾选的过程这里不展开每个选项路径找到对应项目即可。3.2 设备树修改的实操技巧设备树是ZYNQ平台外设管理的核心。Petalinux把用户自定义设备树统一放在system-user.dtsi里这个文件会在内核编译时被追加到最终设备树中。比如我要在PL侧添加一个自定义IP核地址分配在0x43C00000中断号是61就在这个文件里写/include/ system-conf.dtsi / { my_ip_0: my_ip43c00000 { compatible xlnx,my-ip-1.0; reg 0x43c00000 0x10000; interrupts 0 29 4; interrupt-parent intc; clock-names s_axi_aclk; clocks clkc 15; }; };注意ZYNQ的中断号在设备树里要减掉32因为前32个是CPU内部中断PL中断映射到GIC的ID 61这里写的就是61 - 32 29。这个细节很多人不知道导致中断始终触发不了。设备树写完后不需要额外编译直接执行petalinux-build重新构建即可。如果只是改设备树可以加速petalinux-build -c device-tree petalinux-build -x package这样只重编设备树部分不用把整个内核和根文件系统都重编一遍省时间。3.3 在根文件系统里添加自研应用根文件系统的内容可以在petalinux-config -c rootfs里配置。常规需求包括开启网络工具net-tools、iproute2、安装ssh服务端openssh-sshd、装文本编辑器vim等。勾选完后保存退出构建时这些包会自动编译进根文件系统。如果是自己的C/C应用程序更高效的方式是用Petalinux的应用模板来创建petalinux-create -t apps --template c --name my_app --enable这个命令会在project-spec/meta-user/recipes-apps/my_app下生成一个应用工程的模板其中files/目录放源码my_app.bb是Yocto的BitBake配方文件。把源码改好后执行petalinux-build -c my_app编译应用再执行petalinux-build整体打包最后生成的image.ub里就会自带这个应用。应用在板子上的路径和权限可以在bb文件里指定默认会在根文件系统的/usr/bin下。这种做法比手动把编译好的二进制塞进根文件系统更规范因为Yocto会处理好依赖关系并且在petalinux-build -x package重新打包时不会丢。3.4 外部内核模块的加入方法“怎么通过Petalinux编译外部的设备树和内核”这个问题我经常在社区里看到其实外部内核模块的加入也走类似应用的模板机制只是类型不同petalinux-create -t modules --name my_driver --enable生成模板后把驱动源码.c文件、Makefile放到project-spec/meta-user/recipes-modules/my_driver/files/并在my_driver.bb中确认源码路径引用正确。构建时这个模块会被编译为.ko文件并通过Yocto的模块安装机制放进根文件系统的/lib/modules/内核版本/extra/目录下。启动板子后执行modprobe my_driver即可加载。如果驱动需要修改设备树来匹配就在3.2节的system-user.dtsi里添加对应的节点。这样“外部驱动设备树改动”的完整闭环也讲清楚了。4. 烧写与启动验证4.1 SD卡分区与文件拷贝ZYNQ最常见的启动方式是SD卡启动系统要求SD卡有两到三个分区。我用下面的分区策略比较稳定分区文件系统大小建议内容分区1FAT32vfat500MBBOOT.BIN、image.ub、boot.scr分区2EXT4剩余空间根文件系统注意顺序很重要第1个分区放启动文件第2个分区放根文件系统。很多人直接用一个FAT分区来存全部文件结果内核启动后找不到根文件系统报Kernel panic - not syncing: VFS: Unable to mount root fs。在Ubuntu下用fdisk重新分区然后格式化sudo fdisk /dev/sdb # 创建分区1类型设为 c (W95 FAT32) # 创建分区2类型设为 83 (Linux) sudo mkfs.vfat -F 32 -n BOOT /dev/sdb1 sudo mkfs.ext4 -L rootfs /dev/sdb2接着挂载分区1把BOOT.BIN和image.ub拷贝进去mount /dev/sdb1 /mnt/boot cp images/linux/BOOT.BIN /mnt/boot/ cp images/linux/image.ub /mnt/boot/ umount /mnt/boot挂载分区2把生成的根文件系统解压进去mount /dev/sdb2 /mnt/rootfs tar -xf images/linux/rootfs.tar.gz -C /mnt/rootfs umount /mnt/rootfsrootfs.tar.gz会在构建结束时自动生成在images/linux/下里面是完整的根文件系统内容。4.2 启动模式与串口连接ZYNQ-7020开发板上有启动模式拨码开关SD卡启动时要把启动模式设为SD通常是MIO[5:4]01具体查看自己板子的原理图按下复位键后整个系统启动流程是BootROM - FSBL - U-Boot - 内核 - 根文件系统。串口连接方面开发板的UART转USB接口连到电脑后在设备管理器里确定COM口号。用任意串口工具连接波特率115200数据位8停止位1无校验这是默认的115200 8N1。启动后串口输出里最先看到的应该是BootROM的输出然后是FSBL打印再是U-Boot的版本信息和倒计时最后是内核启动的日志。按顺序观察这些输出能快速判断卡在哪个阶段。4.3 启动日志里哪些信息值得关注我在调试启动问题时会特别留意以下几类输出FSBL阶段确认“Xilinx Zynq First Stage Boot Loader”正常打印如果卡在这之前往往是启动模式拨码不对或BOOT.BIN缺失U-Boot阶段确认“U-Boot 2023.01”打印后命令提示符Zynq能出现如果卡住多半是DDR初始化问题或U-Boot环境变量错误内核阶段确认Starting kernel ...之后是否有内核版本输出没有的话通常是设备树或者内核镜像不匹配文件系统阶段确认VFS: Mounted root (ext4 filesystem)出现并且init进程正常启动否则是分区格式或bootargs的root参数不对4.4 固化到QSPI Flash的补充说明SD卡启动适合开发调试但产品交付时更多会固化到QSPI Flash。先用SD卡启动系统然后把BOOT.BIN和image.ub写到Flash里去flashcp -v BOOT.BIN /dev/mtd0 flashcp -v image.ub /dev/mtd4具体哪个mtd分区对应BOOT和image要看板子的分区表不同板子不一样。写完后把启动模式拨到QSPI模式重新上电即可。这个方式要比SD卡启动可靠很多因为QSPI Flash芯片不容易被拔掉或者写坏量产阶段也方便。不过要注意QSPI Flash固化后有个问题Xilinx原生的QSPI驱动会在U-Boot阶段自动识别Flash厂商和型号如果你的板子用的是比较冷门的Flash芯片可能在U-Boot阶段直接不识别这就需要在Petalinux的U-Boot配置里手动指定Flash参数了。我踩过这个坑换了颗常用的Winbond 16MB Flash后一次通过。5. 常见报错与排查速查表5.1 构建阶段的典型报错Petalinux构建时报错特别让人头疼因为错误信息经常藏在一大堆日志里。我把实践中遇到频率最高的几个问题和解决方法整理成一个速查表方便大家对照报错信息可能原因解决方法/bin/sh: 1: source: not found系统默认shell是dash执行sudo dpkg-reconfigure dash选择Nobash: petalinux-create: command not found没source环境变量执行source /opt/petalinux/settings.shERROR: Failed to parse XSA fileVivado版本和Petalinux版本不匹配检查两者版本是否同为2023.1重新导出XSAFAILED: recipe ... task do_compile内核或模块源码编译出错先查看build/目录下logs定位编译错误位置ERROR: packagegroup-core-ssh-openssh ... not found本地镜像源缺少包检查网络打开网络联通后再执行petalinux-buildError: No rule to make target ... modules内核头文件或源码树缺失先执行petalinux-build -c kernel -x cleansstate再重新构建5.2 启动阶段的经典故障定位启动阶段的报错更能体现整个系统联调的复杂性。我挑几个常见场景展开说一下排查思路场景一串口完全没有输出。这种情况先别怀疑软件用万用表测量开发板供电是否正常再看启动模式拨码是否在SD位置最后确认串口线连接的TXD/RXD是否接反。排除硬件后看看SD卡是不是没有BOOT.BIN文件。还有一个小细节有些板卡的BOOT模式里SD启动和JTAG启动是共用一部分拨码的拨错位置后BootROM会直接进JTAG等待自然没有任何串口输出。场景二U-Boot起来了但内核没起来。看到U-Boot的倒计时结束后串口输出停在“Starting kernel ...”上十有八九是设备树或者内核镜像有问题。先确认image.ub是否为最新构建产物再检查U-Boot环境变量里的kernel_addr等地址是否与image.ub的实际加载地址匹配。Petalinux默认生成的boot.scr会处理好这套地址匹配但如果自己写过uEnv.txt或者改过U-Boot环境变量就很容易在这里出问题。场景三内核起来了但根文件系统挂载失败。报错VFS: Unable to mount root fs时检查SD卡分区表中根文件系统分区是否存在以及bootargs里的root参数是否指向了正确的设备节点。ZYNQ下SD卡的设备节点通常是/dev/mmcblk0p2第二分区如果U-Boot环境变量里写成root/dev/mmcblk0p1就会挂载失败。用printenv bootargs可以查看当前生效的参数。场景四文件系统起来了但应用跑不起来。这类问题多数是动态库依赖缺失。例如程序依赖libusb但根文件系统里没这个库运行时就会报error while loading shared libraries。解决办法是在rootfs配置里勾选对应的库包或者用petalinux-create -t apps模板创建应用时在bb文件里添加RDEPENDS依赖声明。5.3 两个容易被低估的排障手段第一个是petalinux-build的日志系统。很多人看到终端报错就慌了其实Petalinux把构建日志放在了build/目录下的logs里比如内核编译的日志在build/tmp/work/plnx_zynq-xilinx-linux-gnueabi/linux-xlnx/.../temp/log.do_compile。打开这个文件搜索ERROR:或Error关键字往往能直接看到具体的编译失败原因比在终端翻屏有效得多。第二个是“重来一次”的清理策略。有些报错其实只是某个中间产物过期或损坏此时不需要全部重编。针对性的清理命令是petalinux-build -x cleansstate # 清理所有构建中间状态 petalinux-build -c kernel -x cleansstate # 只清理内核中间状态 petalinux-build -c rootfs -x cleansstate # 只清理根文件系统中间状态我自己的经验是如果某个配置明明改了但构建结果没生效先执行对应组件的cleansstate再重新构建大部分时候问题就解决了。5.4 网络下载慢与Yocto软件源缓存问题Yocto在构建时会从多个开源软件仓库下载源码如果网络情况不佳很容易出现下载超时或校验失败。这个问题的排查思路是先确认网络能访问外部仓库再用Petalinux自带的下载缓存机制把下载好的包放到本地目录下次构建直接复用。Petalinux的下载目录默认在/opt/petalinux/2023.1/downloads你可以把这个目录整体拷贝到一个公共位置然后在petalinux-config里设置Yocto Settings - Local sstate feeds和Download Directory指向这个公共目录。这样团队协作时一台机器下载过源码包其他机器就不用重复下载浪费时间了。我在实践中还发现某些特定的包下载源响应很慢让整个构建卡在“Fetching”阶段很久。这种时候先用petalinux-build带上-v参数看具体卡在哪个包然后手动在被卡住的步骤里等一会儿如果一直没动静就清除该包缓存后重试。6. 一点个人体会整套Petalinux流程跑通之后回头再看真正让我花时间去研究的反而不是工具本身而是对Linux系统启动过程和Yocto构建体系的理解。Petalinux确实把很多复杂的东西做了封装但封装的代价是出了问题以后你必须自己往下挖。记得有一次我改了设备树里的中断号构建成功但中断始终不触发后来才发现ZYNQ的GIC中断号在设备树里要减32这个规则这种细节靠看日志根本发现不了只能靠对硬件机制的深刻理解。用Petalinux做ZYNQ的Linux定制是一项需要同时掌握硬件架构和Linux系统知识的工程能力。建议初学者先把裸机下的启动流程、中断控制器、UART外设这些都搞明白再上手Petalinux会顺畅很多。工具只是加速器对平台的认知才是真正的地基。希望这篇实践记录能给还在ZYNQ Linux里摸爬滚打的人一些参考。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

鸿蒙6适配实战:UI交互与基础能力API变化全解析及兼容处理 2026/9/28 22:48:45

鸿蒙6适配实战:UI交互与基础能力API变化全解析及兼容处理

刚开始接触鸿蒙适配的时候,我一度以为把 API 换一换、编译跑通就算完事。等真正把项目从 HarmonyOS NEXT 迁到鸿蒙 6 之后才发现,UI 交互和基础能力这一层的 API 变化才是最磨人的——它们不像底层接口那样有清晰的替代函数,而是散布在组件属…

阅读更多 →
STM32音频输出实战:PWM与DAC方案对比及WAV播放器实现 2026/9/28 22:48:45

STM32音频输出实战:PWM与DAC方案对比及WAV播放器实现

1. 从蜂鸣器到高保真:为什么STM32音频输出值得折腾很多人第一次在STM32上做音频,都是从蜂鸣器或者PWM驱动小喇叭开始的。那种“滴——”一声的效果确实能响,但离“音乐播放器”四个字还差得远。我最早做这个项目的时候,用STM32F10…

阅读更多 →
一人公司SaaS架构:数据细胞理论,多租户隔离与扩展的最佳实践 2026/9/28 22:48:38

一人公司SaaS架构:数据细胞理论,多租户隔离与扩展的最佳实践

做SaaS这件事,很多人有一个误区:总觉得“一人公司”就先别碰架构,功能跑起来、客户收进来才是正经事。我在企业服务领域摸爬滚打这些年,反而得出了一个相反的结论——正因为他是一个人,技术架构才是决定你还能不能睡好…

阅读更多 →
遥感道路分割数据集实战:从摸底检查到训练避坑全指南 2026/9/28 22:48:24

遥感道路分割数据集实战:从摸底检查到训练避坑全指南

简介:这是一份面向遥感影像道路分割与图像分割场景的数据集资源,所有图片与掩膜均已处理完毕并完成训练、验证集划分,可直接送入分割模型训练。训练集约两千八百张图像及对应mask,验证集约一千二百张;标签明确区分为背…

阅读更多 →
Android端QNN SDK部署实战:ONNX模型转换、NPU集成与精度调优 2026/9/28 22:48:18

Android端QNN SDK部署实战:ONNX模型转换、NPU集成与精度调优

1. 为什么要在Android上折腾QNN SDK第一次听说QNN SDK是在一个移动端AI部署的群里,有人问“骁龙8 Gen 2上跑YOLOv8能不能到30帧”,底下有人回了一句“用QNN啊,别用NNAPI了”。当时我对QNN的认知基本为零,只知道它是高通的一套神经…

阅读更多 →
深入理解Docker镜像:以Nginx为例从拉取到构建的完整实践 2026/9/28 22:48:18

深入理解Docker镜像:以Nginx为例从拉取到构建的完整实践

1. 一个看似简单的问题:Docker 镜像到底是什么1.1 我为什么会盯上 Nginx 这个例子接触 Docker 这些年,我发现自己被问得最多的问题不是“Docker 怎么安装”,也不是“docker-compose 怎么写”,而是类似“镜像和容器到底啥区别”“我…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉