【转贴】一种在BIOS中嵌入应用程序的方法及实现

BIOS和EC 08年做MID时候的一个PPT. Agenda 硬件平台 BIOS介绍 功能 类型,种类 内部模块(AWARD为例) EC介绍 功能(IT8511E LPC EC为例) EC与BIOS关系 硬件平台 BIOS介绍 BIOS (Basic Input Output System)即基本输入/输出系统。 存放在一个不需要电源的记忆体(芯片)中,这就 阅读详情
一种在BIOS中嵌入应用程序的方法及实现

介绍
本文针对Award公司开发的计算机系统BIOS提出了一种嵌入应用程序的方法,其基本原理对别的品牌的BIOS也一样适用,仅需稍加修改。文中作者给出并讨论一个完整的例子程序,该程序已经通过实验验证。

一. BIOS简述
这里所讲的BIOS是指计算机主板上的BIOS,是整个计算机的关键和灵魂,计算机一启动就是执行BIOS程序,它负责加电自检,初始化计算系统,响应用户对系统配置的修改,记录数据到CMOS中,将常驻程序库(Runtime Program)常驻于内存中,提供给系统和应用程序调用,经过一系列复杂操作后,最后将控制权转移给操作系统。
一开始BIOS容量仅有8K,随着计算机复杂程度的提高,以及即插即用、高级电源管理等方面的需要,再加上个别主板厂商添加的辅助功能,BIOS容量迅速增大,目前通常主板上BIOS容量为256Kb,有些已经达到512Kb,这些BIOS中常常还会有几十Kb的剩余空间,而且由于BIOS多采用FlashRom作为存储芯片,便于修改,这就为我们在BIOS中嵌入自己的程序提供了便利。
在BIOS中嵌入程序具有多方面的应用,有些主板厂商在BIOS中嵌入杀毒程序,硬盘恢复精灵,超频工具等,提高了产品的竞争力;台湾威胜公司和Elegent公司联合开发出了嵌入在BIOS中的小型浏览器操作系统,整个BIOS大小仅有512Kb,计算机无需硬盘即可上网冲浪;有些监控系统由于功能简单,完全可以把程序做到BIOS中,一开机就自动运行,既提高了可靠性,又降低了成本。另一方面,将病毒嵌入到BIOS中,一开机就常驻内存也完全可以做到。
BIOS代码虽短,但技术含量相当高,全世界仅有AWARD、PHOENIX、AMI、ACER等几家公司有研发BIOS系统的能力(AWARD 已被PHOENIX收购),其他主板厂商有的是直接购买,有的也会在以上几家公司提供的平台上进行少量功能扩展。作为个别应用的场合,就要完全靠自己对BIOS进行改造。

二. 嵌入程序的基础知识
在进行工作前需要几个必备的工具,一个是AWARD公司的BIOS刷新工具AwdFlash;另一个Award BIOS 察看修改工具Cbrom;还有一个是MicroSoft 的汇编工具Masm6.11;最后是作者推荐的二进制文本编辑器HexWorkshop,这些工具都可以从网上下载,下面假定读者已经熟练使用这些工具,具体操作步骤不再祥述。
前面提到BIOS程序是存放在FlashROM芯片中的,实际上它是经过压缩后再存放进去的,仅留下少量启动代码和解压缩程序保持原样,BIOS的执行过程其实相当复杂,好在我们无需去了解其中的详细流程,但有一点应当清楚,BIOS程序实际上也是采用的模块化设计思想,用Cbrom可以察看到BIOS中各个子模块的名称,性质,压缩率等信息,BIOS在执行过程中会将这些模块解压缩到内存中,验证模块的合法性和正确性,如果满足条件,就会转到模块的入口处执行。这里面的详细机制和由来需要参考PNPBIOS协议、PNPISA协议、PCI总线协议和EISA总线协议,内容繁多,本文不拟做深入探讨。
BIOS中有一种模块是ISA模块,来源于ISA协议,由于ISA协议属于早期的协议,内容相对简单,BIOS对ISA模块的验证也较为简单,容易满足,我们可以将自己的程序做成ISA模块挂到BIOS中,这样机器一启动,我们的程序就会启动,而且我们程序的运行是先于操作系统的。
三. 程序设计详细步骤
1. 设计准备
由于系统固有的限制,BIOS中每个模块的大小不能超过64Kb,这里是指没有压缩前的大小,这和DOS下COM程序的限制很相似,实际上我们在用MASM6.11进行编程时的确采用是COM程序的模板,由编译器生成COM文件。然而它又和一般的COM文件具有以下几点不同:
1. 首先它有自己的堆栈段,堆栈大小默认为1K,而COM文件的堆栈是在64K之内的,默认是从段内偏移量0FFFEh处开始。
2. COM文件一开始就是执行代码,而模块一开始是模块头,储存有与模块相关的信息。模块执行代码的入口点在模块中的某一处。
3. COM文件执行完后返回到操作系统,通常通过子功能号4ch的中断INT21h返回到DOS,而模块是远程调用返回,也就是说必须用RETF返回。
4. ISA模块最后一个字节是校验码,所有的字节相加必须为0,BIOS利用这点来验证一个ISA模块的正确性。COM文件没有这点要求。
5. COM文件执行时是先被完整地复制到段内偏移量100h处,然后再执行,而模块的段内偏移量不能确定,有的模块会是0。所以涉及到段内偏移量的汇编指令,如LEA、OFFSET要谨慎适用。
下表是ISA模块头的格式,其中仅列出了几个最基本的相关字段,这是协议中的内容,我们在编写模块头时,需要严格遵循下表的格式:

偏 移 长 度 值 说 明
0h 1 55h 模块标签字节1
1h 1 AAh 模块标签字节2
2h 1 * 模块长度(以512字节为单位)
3h 3 * 入口点,BIOS对此位置做远调用,这里往往放一条跳转指令
6h~19h 20 * 保留

表一 模块头格式
通常一个BIOS嵌入程序设计的基本流程如下,每一步都很关键,有必要给出详细说明:
1. 首先用汇编编写DOS下的COM程序,必须注意到程序是先于操作系统执行的,所以程序中不能调用任何DOS的中断服务。为了程序转化方便,也不要用.code,.startup等汇编伪指令,尽量采用早期的汇编编写方式,争取对整个程序结构的完全控制。
2. 调试通过后,在COM文件前加上文件头,改变返回指令为RETF,控制文件大小为512字节的整数倍,重新编译生成COM文件。
3. 在HexWorkshop中调入刚生成的COM文件,利用其中的checksum工具生成文件的校验码,用100h减去该8位校验码后填入文件最后一个字节。再次生成文件的校验码,确认为零。
4. 用Cbrom将文件作为ISA模块嵌入到BIOS中,在本文中的操作为 “Cbrom save.bin/isa hello.com”,其中save.bin是事先用AwdFlash备份的BIOS文件。注意反复操作时,要先将前一个给释放掉,操作为“Cbrom save.bin/isa release”。
5. 用AwdFlash将新的BIOS文件烧录到FlashROM中。重起计算机,检验程序。
进行以上实验前,最好自备编程器,万一计算机不能正常启动,也可以重新恢复BIOS,如果可以用本身具有双BIOS保护功能的计算机进行实验则更加保险。
下面设计两个简单的Hello程序,分别采用了两种不同的方式,两个程序都是在屏幕上显示一行字“Hello!Press F1 to continue…”,当按下F1功能键后,程序退出,计算机继续启动。
2. Hello程序一
下面给出的源代码是在上面流程2中的文件,所以已经添加了文件头,编译后生成的COM文件是不能在DOS下执行的,请读者务必注意。另外由于程序功能简单,所以在这里文件大小限制为512字节,对不同规模的程序,会有一些小小的变动。程序中所有的中断调用都是BIOS中断服务调用,具体调用规则不做详细说明,请读者查阅有关资料。
;Hello源程序一
code segment
assume cs:code,ds:code
start:

signature db 55h,0aah
comlength db 01h ;文件长512字节
jmp near ptr begin0
reserved db 20 dup(?)

begin0:

mov di,25
mov ah,2
mov bh,0
mov dx,di
mov dh,10 ;将光标移至屏幕
int 10h ;10行25列处

mov si,offset string
;在DOS下调试时应在这里添加 add si,100h
showstr:
mov ah,9
mov al,[si]
and al,0ffh
jz kbinput
mov bh,0
mov bl,0DAh
mov cx,1
int 10h
,
mov ah,2
mov bh,0
inc di
mov dx,di
mov dh,10
int 10h
jmp showstr ;输出字符串

kbinput:
mov ah,0
int 16h
cmp ah,3bh ;接受键盘输入
jne kbinput ;按F1往下执行

mov ax,0 ;返回参数
retf ;远程调用返回

string db 'Hello! Press F1 to continue...',00h ;00h标志字符串结束
org 511 ;文件末尾
checksum db ?
code ends
end start

将上述程序烧入BIOS中运行时,在第一屏信息显示过后,会在第二屏正中央显示一条红底白字的信息,提示按F1键继续,按F1键后,BIOS继续下面的启动步骤。显示第三屏启动信息,即原先的第二屏信息,最后加载操作系统。
以上程序假定了BIOS会将模块解压至段首运行,事实也确是如此,但由于没查到相关资料,目前还不能肯定总会如此。这一点将在下一个Hello程序中有所改进。
3. Hello程序二
Hello程序一在BIOS没有初始化完全的时候即进入运行,所以对程序功能有更多限制,有些BIOS中断服务还不具备,任何对这些服务的调用都会产生意想不到的结果。考虑到BIOS在加载操作系统时实际上是用的INT 19h,Hello程序二就利用挂钩19h中断的方法抢在操作系统之前,BIOS初始化之后运行,这样就可以完整地利用整个计算机系统的所有资源了。
另外必须指出的是,模块本身有责任保持整个模块的校验和为零,也就是说,ISA模块进驻内存中后就不能卸出,BIOS会在模块返回后检查整个模块的检验和,判断模块的正确性,如果错误,则会死机。模块在初始运行时可以更改自己段内的数据,而在BIOS初始化完毕后,模块就不能再有改变自身数据的操作。
;Hello源程序二
.model tiny
.386
code segment
assume cs:code,ds:code
start:
signature db 55h,0aah
comlength db 01h ;文件长512字节
jmp near ptr begin0
reserved db 20 dup(?)
begin0:
call getip ;得到模块的起始段内偏移量
;保存在参数ipstart中
mov ax,0 ;挂钩19h中断
mov es,ax ;保存原来的入口到
mov ax,es:[64h] ;saveip与savecs
mov saveip,ax
mov ax,es:[66h]
mov savecs,ax
mov ax,offset begin1
add ax,ipstart
mov es:[64h],ax
mov es:[66h],cs

mov ax,0 ;重新计算校验码
mov si,510 ;注意不要记入最后一个字节
again: add ax,cs:[si]
dec si
jns again
neg al ;改变最后一个字节
mov checksum,al ;使整个模块校验和为零

mov ax,0
retf ;远程调用返回

begin1: ;19h中断入口
sti ;开中断
pusha
push es
push ds ;保存调用参数

mov ax,cs
mov ds,ax

mov ax,0 ;恢复原19h中断入口
mov es,ax
mov ax,saveip
mov es:[64h],ax
mov ax,savecs
mov es:[66h],ax
;以下基本与程序一相同
;这里为节约篇幅用……代替
;……
mov si,offset string
add si,ipstart ;注意
;……
pop ds
pop es
popa
int 19h ;激发19h中断
iret

getip proc ;得到模块的起始
pop ax ;段内偏移量子程序
push ax
sub ax,29 ;29=模块头大小加3
mov ipstart,ax
ret
getip endp

string db 'Hello! Press F1 to continue...',00h

saveip dw ?
savecs dw ?
ipstart dw ?

org 511
checksum db ?

code ends
end start

Hello2程序在执行时,会在第二屏启动画面的最后一行显示一段黑底白字“Hello! Press F1 to continue...”,当按下F1后,计算机就开始加载操作系统。
需要注意的是,在DOS或Windows下调试Hello程序二时,是不能用19h中断的,任何对19h中断的调用要么结束当前程序,要么会造成死机,所以调试时需要暂时用别的中断代替,如保留中断2bh,当调试成功以后,再将中断改回为19h。
另一个在Hello1与Hello2程序中都要注意的问题是,在程序中不要轻易改动模块头的模块长度字节的值,PCI模块支持并赞成这样的改动,而ISA模块没找到相关资料,笔者曾尝试过改动这一值,结果导致Windows98不能进入通常模式。
四. 结束语
在编程实践中作者感到编写BIOS的嵌入程序具有相当难度,它需要有扎实的汇编语言功底和对计算机硬件系统的深入了解,更需要在实践中不断地摸索BIOS程序的特点,只有这样才能够编写出精悍的代码,满足实践应用的需要。
嵌入式:BSP的理解 阅读详情

相关推荐

BIOS入门篇---详解BIOS

BIOS全称basic input output system,即基本输入输出系统,它是PC主板上的固件,负责初始化硬件资源并引导启动OS,可以说BIOS就是为了启动OS而生。大白话“一个电脑的开机程序,就是从按下电源键到看到屏幕LOGO这段时间跑的程序”。

m0_73344394的博客 3024

一种在BIOS中嵌入应用程序的方法及实现

介绍本文针对Award公司开发的计算机系统BIOS提出了一种嵌入应用程序的方法,其基本原理对别的品牌的BIOS也一样适用,仅需稍加修改。文中作者给出并讨论一个完整的例子程序,该程序已经通过实验验证。 正文一. BIOS简述这里所讲的BIOS是指计算机主板上的BIOS,是整个计算机的关键和灵魂,计算机一启动就是执行BIOS程序,它负责加电自检,初始化计算系统,响应用户对系统配置的修改,记录数据到CM

1004

一种基于主板BIOS的身份认证方案及实现

一、BIOS简介BIOS是只读存储器基本输入/输出系统,它是被固化到计算机中的一组程序,为计算机提供最低级的、最直接的硬件控制,在计算机系统中起着非常重要的作用。BIOS是硬件与软件程序之间的接口,负责解决硬件的即时需求,并按软件对硬件的操作要求具体执行。BIOS的功能包括自检及初始化、硬件中断处理、程序服务处理。1. 自检及初始化这个部分的功能是启动计算机,包括三个部分,第一个部分是用于计算机刚

技术联盟 2465

【随笔】入坑半年后对嵌入式的一点认识

对嵌入式的一点认识 我们自动化系是一个就业非常轻松的专业,可以让我们从事的行业非常丰富: 电子/电气工程师、电气工程师/技术员、自动化工程师、电气工程师、自动控制工程师/技术员、研发工程师、电子工程师/技术员、软件工程师、电子技术研发工程师、设备工程师(调试/安装/维护)、软件工程师、高级软件工程师、嵌入式软件工程师、研发工程师、软件开发工程师、嵌入式软件开发(Linux/单片机/DLC/DSP…...

yy197696的博客 2644

PnP BIOS 说明手册

Plug and Play BIOS Specification,Version 1.0A

2D激光slam数据集的下载与测试

参考博客: https://blog.youkuaiyun.com/qq_24894159/article/details/81265991 https://blog.youkuaiyun.com/fk1174/article/details/52673413#commentBox 数据集下载与生成 下载数据集 下载网址: http://ais.informatik.uni-freiburg.de/slamevaluation/datasets.php 进去网站后点你想下载的对应的"download log file" 然后你

老李的博客 4025

计算机系统:LEA指令详解,提高程序执行效率!

LEA指令是计算机系统中一个非常重要且灵活的指令。通过LEA指令,我们可以在程序中高效地进行地址计算,提高程序执行效率。本文详细介绍了LEA指令的语法和常见用法,包括数组索引计算、结构体成员访问和动态内存分配等。掌握LEA指令的正确使用方法,将帮助开发者编写出更高效的代码。希望本文对你理解LEA指令有所帮助,欢迎留言讨论。注意:本文参考了x86架构相关资料,如有引用不当之处,请指正。

m0_72410588的博客 8988

从零开始:在CentOS服务器上部署R Shiny应用的完整指南

本文提供了一份在CentOS服务器上部署R Shiny应用的完整实战指南。内容涵盖从创建专用用户、安装R语言环境、配置Shiny Server,到最终部署应用并配置防火墙的全过程。针对部署过程中常见的权限、端口及依赖问题,给出了详细的解决方案,旨在帮助数据分析师和开发者将本地Shiny应用稳定、安全地发布至生产环境。

weixin_29079743的博客 134

SYS/BIOS实例分析

阅读目录 SYS/BIOS简介 创建一个SYS/BIOS项目 SYS/BIOS的模块与配置 在项目中导入LOG模块 在项目中导入TSK任务模块 在项目中导入Swi软件中断模块 在项目中导入信号量Semaphore模块 在项目中导入时钟Clock模块 回到目录 SYS/BIOS简介 SYS/BIOS是一个可扩展的实时内核(或者说是操作系统),其提供了许多模块化的APIs(应用程...

kunkliu的博客 2064

【QMIX】一种基于Value-Based多智能体算法

文章目录1. QMIX 解决了什么问题(Motivation)2. QMIX 怎样解决团队收益最大化问题(Method)2.1 算法大框架 —— 基于 AC 框架的 CTDE(Centralized Training Distributed Execution) 模式 QMIX 是一种基于 Value-Based 的多智能体强化学习算法(MARL),其基本思想来源于 Actor-Critic 与 DQN 的结合。使用中心式学习(Centralized Learning)分布式执行(Distributed

qq_38638132的博客 9859

数字IC设计——功耗分析

功耗是数字IC芯片的一个重要指标

知识,既贵,又便宜。 9359

在BIOS中嵌入应用程序的方法及实现

介绍本文针对Award公司开发的计算机系统BIOS提出了一种嵌入应用程序的方法,其基本原理对别的品牌的BIOS也一样适用,仅需稍加修改。文中作者给出并讨论一个完整的例子程序,该程序已经通过实验验证。正文一. BIOS简述这里所讲的BIOS是指计算机主板上的BIOS,是整个计算机的关键和灵魂,计算机一启动就是执行BIOS程序,它负责加电自检,初始化计算系统,响应用户对系统配置的修改,记录数据到CMO

晓斌的博客 2581

CAN总线BusOff恢复机制详解:快慢恢复策略在车载网络中的实战应用

本文深入解析了CAN总线BusOff恢复机制,重点阐述了快慢恢复策略在车载网络中的工程应用。通过对比NXP S32K与STM32平台的实现代码,并结合CANoe仿真与参数优化方法,为工程师提供了从理论到实战的完整解决方案,旨在提升车载网络的可靠性与功能安全。

7up55的博客 614

SYS/BIOS知识整理汇总

本文主要整理BIOS相关组件的执行原理及使用,这里主要包括了硬件中断Hwi模块、软件中断Swi模块、时钟Clock模块、任务Tsk模块、信号量Sem模块。 1.SYS/BIOS概述 SYS/BIOS是一个可扩展的实时内核(或者说是操作系统),其提供了许多模块化的APIs(应用程序接口),支持抢占式多线程,硬件抽象,实时分析和配置工具,其设计目的是为了最大限度地减少对内...

boyemachao的专栏 6936

机器学习---xgboost算法

问题上表现的十分顶尖,本节将较详细的介绍XGBoost的算法原理。成和剪枝分别对应了经验风险最小化和结构风险最小化, XGBoost的决策树生成是结构风险最小。式(1.1)称为经验风险最小化,训练得到的模型复杂度较高。出结果, 是模型的输出结果;等式右边第⼀部分是模型的训练误差,第⼆部分是正则化项,这里。其中,F是假设空间,假设空间是在已知属性和属性可能取值的情况下,对所有可能满足目标的情。最小化,结构风险最小化的模型往往对训练数据以及未知的测试数据都有较好的预测。的正则化项是K棵树的正则化项相加而来的。

weixin_43961909的博客 1万+

QST QMC5883L —— 经典磁传感器的生存指南与替代预案

本文聚焦于QST旗下经典三轴磁力计 QMC5883L,解析其技术渊源、核心特性及当前面临的停产风险。结合真实应用场景提供续命方案与选型建议,为依赖该芯片的开发团队争取过渡时间窗口期。文章包含实测数据对比、生命周期管理策略及潜在替代方案拆解。存续价值判断✔️ 现有产品设计无需大幅改动即可延续生命;❌ 新项目采用将面临更高的维护成本;⚠️ 建议在6个月内完成技术路线切换。#磁传感器 #嵌入式开发 #供应链管理 #QST #QMC5883L。

2501_93066786的博客 997

一种基于BIOS的WINCE启动方法

Windows CE.NET是微软公司向嵌入式领域推出的一款操作系统。它最大程度继承了桌面版Windows操作系统的丰富功能,同时又赋予了许多新特性,以适应嵌入式领域的实际要求。无论是商业应用还是多媒体消费需求,都能被采用CE操作系统的设备轻松满足。最新的.NET版本较之3.0版本,在实时性和稳定性上有大幅度提高,并广泛地被平板电脑、数码相机、彩屏手机、PDA等多种高性能产品所采用,同时工业控制中

changexhao的专栏 2044

下拉式菜单设计——Power BI

Power BI导航设计:多级下拉菜单

weixin_41542593的博客 5433

DSP实时嵌入系统DSP/BIOS学习入门

一、为何接触了DSP/BIOS? 为了得到某些DSP运行中的数据,在尝试了断点实时刷新、printf函数、保存在数组中等三种方式,由于我的系统属于高速时钟以及实时性要求较为严格,前两者直接pass,这两个操作非常费时间,实时性很差,后来了解到了DSP/BIOS这个神奇的方式,尽管最终由于时间的原因没有采取这种方式,但是还是觉得很好奇,就是进行了研究。 二、那点事 本人是机械工程专业,但是感兴趣的确...

weixin_43606771的博客 2123

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

什么是uboot与bios?

title: what is uboot and bios? date: 2022-03-17 17:24:27 tags: 前言preface ​ 最近在漏洞挖掘过程中,涉及到了一些基础的知识比如BIOS,uboot,qemu模拟的方面。 ​ 首先开始我们需要了解机器是怎么运行的 ​ 一般我们使用的机器都是windows或者Linux,(本人是高端MAC本🤣), 什么是BIOS?他有什么用,他做了什么?按下开机键的时候机器干了啥? ​ 问: ​ 计算机是最讲逻辑,他会按照他的规则去运行,但是我们不知道.

doudoudedi 4727

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

CMD文件中,nonBIOS和BIOS文件的区别

在 linker 脚本中的 `BIOS` 和 `nonBIOS` 文件主要用于区分启动时需要执行的 BIOS 引导代码和后续执行的非 BIOS 代码(如操作系统或应用程序代码)。在 DSP 或嵌入式系统的 linker 脚本文件(`.cmd` 文件)中,`nonBIOS` 和 `BIOS` 文件通常是用来区分不同类型的启动代码或系统映像文件。在 `.cmd` 文件中,`BIOS` 和 `nonBIOS` 区域通常是通过定义特定的内存区域来映射到不同的地址范围。

qq_18421935的博客 1365

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

嵌入式系统UBOOT——BIOS、BootLoader、uboot对比(转)

bios BIOS是英文"Basic Input Output System"的缩略语,直译过来后中文名称就是"基本输入输出系统"。其实,它是一组固化到计算机内主板上一个ROM芯片上的程序,它保存着计算机最重要的基本输入输出的程序、系统设置信息、开机后自检程序和系统自启动程序。 其主要功能是为计算机提供最底层的、最直接的硬件设置和控制。 BootLoader BootLoader是一段小程序,可以...

li7720681的博客 2843

BIOS + EC

BIOS + EC1参考 1 参考 1、BIOS与EC之间关系 2、BIOS和EC 3、蓝天DOS下刷BIOS、EC小教程(以775TM为例)

天道酬勤 5453
上一篇: shell经典,shell十三问
下一篇: 盒子们牵动了谁的神经
freexploit
博客等级 码龄22年 315粉丝 778原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值