ARM與Cortex筆記

本文介绍了ARM处理器的发展历程和关键技术,包括RISC架构、Von Neumann与Harvard架构的区别、Pipeline技术、Branch Prediction以及Cortex A系列的Superscalar架构。特别提到了Cortex A8的Dual-Issue、NEON多媒体指令集和TrustZone安全技术,阐述了这些技术如何提高处理器性能和安全性。
摘要由CSDN通过智能技术生成

ARM與Cortex筆記

hlchou@mail2000.com.tw
by loda


Loda's Blog

App BizOrz


Android/Linux Source Code Tags
App BizOrz 
BizOrz.COM 
BizOrz Blog


曾聽過一段話,有人問蘇格拉底為何成為雅典最有智慧的人,他說:雅典人自以為知道什麼,卻不知道其實自己什麼都不知道,他只知道一件事,就是他什麼都不知道. 希望個人在技術領域專研,也應常保此心.

因著工作的關係,在ARM的處理器上經歷了Real-Time OS,Linux相關的Porting工作,希望可以透過這篇文章,把相關的資訊做一個整理(溫故知新),若你原本已經是ARM架構的熟手,本文應該幫助有限,主要希望對有志於在ARM相關產品開發更進一步了解的人有所幫助,然個人所學有限,若有不足之處,還請不吝指教,

參考ARM的網站http://www.arm.com/about/company-profile/index.php,ARM公司成立於1990年,目前為止已經銷售了超過150億個基於ARM的晶片,並向200多加公司銷售了超過600個處理器的授權,並藉此收取ARM晶片的授權費用,目前全世界有超過95%的手機以及超過25%的消費性電子產品使用ARM做為處理器曲7超過ㄨㄛㄨㄛ.

從ARM(Advanced RISC Machines)公司的名稱可以知道,這是一家專注在RISC(Reduced Instruction Set computer)架構的處理器公司,最早的ARM1原型是1985年在英國劍橋的Acorn計算機公司所設計,並由美國的VLSI公司製造,也因此在Wiki上看到,早期ARM1,ARM2,ARM250,ARM3..的處理器,都被Acorn這家公司採用作為計算機核心處理器.

1978/12/5,物理學家赫爾曼·豪澤(Hermann Hauser)和工程師Chris Curry,在英國康橋創辦了CPU公司(Cambridge Processing Unit)並在1979年,CPU公司改名為Acorn電腦公司,在1985年,Roger Wilson和Steve Furber設計了他們自己的第一代32位、6M Hz的處理器,用它做出了一台RISC指令集的電腦,簡稱ARM(Acorn RISC Machine).

隨後,Acorn公司陷入財務困難,並被Olivetti收購,成為一個獨立的Olivetti研究子公司,1990/11/27,ARM獲得蘋果公司與晶片廠商VLSI的投資,成為一家獨立的處理器公司,在穀倉展開創業的歷程,像是大家印象深刻的Apple Newton PDA,用的就是ARM610處理器.(參考文章:http://www5.cnfol.com/big5/news.cnfol.com/100823/101,1587,8274016,00.shtml與 http://big5.buynow.com.cn/gate/big5/www.cnbeta.com/articles/131786.htm )

稍微考古一下,目前處理器的架構中,主要有1940年代提出的Von Neumann記憶體架構,讓程式與資料共用相同的匯流排,以及之後的Harvard架構,讓程式與資料走不同的匯流排,好處在於可以同時進行程式與資料的記憶體存取動作,早期的ARM7跟8051一般是採用Von Neumann架構,一塊Cache供指令與資料存取,而目前新的微處理器架構(例如:ARM11 or Cortex A),通常都採用Harvard架構,也就是處理器會支援I-Cache與D-Cache,區分指令與資料的擷取匯流排,提升處理器的效率. (參考文章:http://en.wikipedia.org/wiki/ARM7 and http://en.wikipedia.org/wiki/Harvard_architecture ).

有關ARM在Von Neumann與Harvard架構的分類,也可以參考網頁http://stenlyho.blogspot.com/2008/08/armcpu.html ,如下所示

Processor Family #of pipeline stages Memory Organization Clock Rate MIPS/MHz
ARM6 3 Von Neumann 25MHz  
ARM7 3 Von Neumann 66MHz 0.9
ARM8 5 Von Neumann 72MHz 1.2
ARM9 5 Harvard 200MHz 1.1
ARM10 6 Harvard 400MHz 1.25
StrongARM 5 Harvard 233MHz 1.15
ARM11 8 Von Neumann/Harvard 550MHz 1.2

ARM是採用RISC 精簡指令集 (Reduced Instruction Set Computing)架構的處理器,RISC架構主要選擇使用頻率較高的簡單指令,避免複雜指令,使用固定長度的指令編碼(支援32bits,16bits或16/32bits混合),單週期指令,便於Pipeline的操作執行,並透過大量暫存器,讓邏輯處理指令只對暫存器進行操作,只有特定載入/儲存的指令可以存取記憶體內容.相比CISC架構,會隨著需求,不斷的加入新的指令集,使得架構越趨複雜,現實應用中,也並非所有的指令都是常被使用的,如下,以CSIC架構的x86 指令集為例,指令集呈現不固定長度的方式,如下例子,有1,2,7與11 bytes的例子

(1bytes)0×48 = dec eax

(2bytes)0×89 F9= mov ecx,edi

(7bytes)0x8B BC 24 A4 01 00 00 = mov edi,dword ptr [esp+000001A4h]

(11bytes)0×81 BC 24 14 01 00 00 FF 00 00 00 = cmp dword ptr [esp+00000114h],0FFh

ARM透過Pipeline的方式加速指令集的處理,在Pipeline執行階段,如果發生中斷,也會把Pipeline中的指令執行完畢才進入中斷,如下所示ARM7支援如下的3階Pipeline

Fetch → Decode → Execute

其中

Fetch 進行指令的擷取動作
Decode Thumb->ARM指令Decompress,ARM指令解碼,暫存器選擇
Execute 進行暫存器/記憶體讀取,算術邏輯運算與暫存器/記憶體回寫動作

每一個CPU週期,處理器都可以同時處理 ‘Fetch’,'Decode’,'Execute’這三個動作,而非把一個指令從Fetch開始到執行完畢後,才處理下一個指令週期,如下圖所示

Time Fetch Decode Execute
Cycle#1 Instruction#1    
Cycle#2 Instruction#2 Instruction#1  
Cycle#3 Instruction#3 Instruction#2 Instruction#1
Cycle#4 Instruction#4 Instruction#3 Instruction#2
Cycle#5 Instruction#5 Instruction#4 Instruction#3
Cycle#6 Instruction#6 Instruction#5 Instruction#4

為了避免在非載入記憶體階段,讓運算指令進行記憶體的存取,而導致Pipeline可重疊執行的能力被破壞,ARM只允許特定載入儲存指令讀寫記憶體的資料. 早期的ARM6,ARM7有約3階的Pipeline,到了ARM8,ARM9時,約為5階的Pipeline,之後的ARM11則為8階的Pipeline,不過,Pipeline過深不一定就能帶來更高的效益,如果程式碼的流程中遇到分支(例如:Branch到另一個程式區塊),就會導致Pipeline中的資料失效,要重新進行指令Fetch的動作.

簡單來說,Pipeline就是把指令的處理分級幾個不同的步驟,例如

ARM9支援如下的5階Pipeline

Fetch → Decode → Execute→ Memory→ Write Back

其中

Fetch 進行指令的擷取(Fetch)動作
Decode 進行ARM/Thumb指令解碼與暫存器的讀取
Execute 進行邏輯運算與記憶體存取位址計算動作
Memory 讀取或寫回記憶體資料
Write Back 將運算或是Load結果回寫暫存器中

ARM10之後,有支援Branch Prediction,以減少在Pipeline執行期間,因為Branch動作導致Pipeline失效 Flush的機會,支援如下的6階Pipeline

Fetch→ Issue → Decode → Execute→ Memory→ Write Back

其中

Fetch 進行Branch Predictor指令分支預測,指令位址計算,與指令的擷取(Fetch)動作
Issue ARM/Thumb指令解碼,若非ARM/Thumb有效指令,就透過Coprocessor Signal判斷是否為Coprocessor指令
Decode 暫存器的讀取,Result Forward,ScoreBoard
Execute 進行算術邏輯運算與Branch/Data存取記憶體位址計算,乘法運算
Memory 讀取或寫回記憶體資料,Coprocessor資料存取,乘法相加處理
Write Back 將運算或是Load結果回寫暫存器中

ARM11採用Scalar架構的Pipeline,並在Issue階段支援ALU(arithmetic logic unit),MAC(multiply/accumulate)與Load/Store分種Pipeline的流水線,可以在一個Cycle分發一個對應的處理器動作到一個Pipeline,如下所示的8階Scalar Pipeline (ARM1156T2-S支援9階的Pipeline,其中Fetch Pipeline擴充為3階,細節就不在這討論,可以參考網頁http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0338g/I1002919.html)

Fetch#1→ Fetch#2→ Decode→ISS (ALU Pipeline)→ Shifter→ALU→ SAT→ Write Back

______________________________(MAC Pipeline) → MAC1→MAC2→ MAC3→ Write Back

______________________________(Load/Store Pipeline)→ LS Add→DC1→ DC2→ Write Back

跟之前版本相比ARM11用了兩個Fetch Pipeline階段去支援兩種指令分支預測(Branch Prediction)的機制,第一個Fetch Pipeline階段會根據歷史紀錄進行動態的指令分支預測(Dynamic Branch Prediction),總共紀錄64筆,4種狀態(Strongly taken,Weakly taken,Weakly not-taken and Strongly non-taken)的分支((Branch)目標記憶體位址快取(BTAC,Branch-Target Address Cache),紀錄近期指令分支的情況. 第二個Fetch Pipeline階段,進行靜態的指令分支預測(Static Branch Prediction),會處理不在第一階段範圍中的分支預測記憶體位址. 命中率高的指令分支預測(Branch Prediction)可以避免Pipeline失效重置的問題,讓處理器的運作效率更高. 根據參考的資料,ARM11的Dynamic與Static Branch Prediction在一般執行情況下可以有約85%的命中率,大多數的情況可以介於80%-95%之間(取決於程式碼的大小).

簡介如下,

#1 Fetch#1 進行Dynamic Branch Prediction,指令位址計算,與指令的擷取(Fetch)動作
#2 Fetch#2 進行Static Branch Prediction
#3 Decode ARM/Thumb指令解碼,若非ARM/Thumb有效指令,就透過Coprocessor Signal判斷是否為Coprocessor指令

 

Static BPR Stack

#4 ISS
(Instruction Issue)
暫存器的讀取,與指令執行路徑分派,有三條路徑邏輯運算ALU Pipeline,乘法累加MAC Pipeline,與資料存取Load/Store Pipeline.
ALU Pipeline MAC Pipeline Load/Store Pipeline
#5 Shifter 對邏輯運算指令操作單元(operand)進行Shift MAC1 第1階段乘法累加操作 LS Add 計算產生Load/Store操作的記憶體位址
#6 ALU 進行整數算術邏輯運算 MAC2 第2階段乘法累加操作 DC1 第1階段Data Cache存取
#7 SAT 儲存運算結果 MAC3 第3階段乘法累加操作 DC2 第2階段Data Cache存取
#8 Write Back 將運算或是Load結果回寫暫存器中

接下來,介紹ARM Cortext A系列的架構,在這架構下ARM導入了Superscalar 架構的Pipeline,讓處理器可以在一個週期平行處理一個以上的指令集,以Cortex A8為例,支援13階的整數Pipeline與10階的NEON多媒體指令集Pipeline,以整數處理的指令集為例,Cortex A8支援Dual-Issue,In-Order Pipeline,不同於之前的ARM核心一次只能處理一個整數處理指令集,Cortex A8可以同時Issue兩個整數處理指令集,並在一個週期中,透過兩個整數算術邏輯單元Pipeline平行處理這兩個指令集.

13-Stage Integer Pipeline 10-Stage NEON Pipeline
F#0 F#1 F#2 D#0 D#1 D#2 D#3 D#4 E#0 E#1 E#2 E#3 E#4 E#5 M#0 M#1 M#2 M#3 N#1 N#2 N#3 N#4 N#5 N#6
Instruction Fetch Instruction Decode

 

with Dual-Issues

Architectural

 

Register

File

ALU/MUL Pipeline 0 NEON
Instruction

 

Queue

NEON
Instruction

 

Decode

NEON
Register

 

File

Integer ALU Pipe
ALU Pipeline 1 Integer MUL Pipe
Load/Store Pipeline 0 or 1 Integer Shift Pipe
None-IEEE FP Add Pipe
None-IEEE FP Mul Pipe
IEEE FP Engine
Load/Store Permute Pipe

在Cortex A8架構下,有兩個 ALU Pipeline,ALU 0與ALU1是對稱的,可以同時處理兩個整數邏輯運算,由於Pipeline的特性,在使用上,乘法需求的指令會跟ALU 0成對 (也就是說在這條Pipeline 0連續處理有關整數邏輯運算與乘法相關的指令),而Load/Store 的指令,則適合跟ALU 0或1兩者任一一起成對運作.

其中

13-Stage Integer Pipeline 0-Stage F#0 用來產生要Fetch指令的位址,在文件中這個階段並不納入13階的Pipeline中. (AGC,Address Generator Unit)
1-Stage F#1 RAM+TLB ,

 

支援兩個層級的全域歷史指令分支預測(Global History Branch Preditor)分別為

1,BTB(Branch Target Buffer)

能用來判斷目前所要Fetch的位址是否為分支(Branch)指令,以及所要調到的目標記憶體位址,目前總共可以記錄512筆資料,若BTB命中,接下來就會進行GHB的動作.

2,GHB(Global History Buffer)

包含4096個2bits計數器,用來編碼分支預測的強度與方向,GHB會以10bits長度定址最近十筆分支的位址,與4bits的PC(Program Counter)值.

此外,Return Stack(RS)會記錄八筆32bits Link Register的值,當發現有關於函式返回(Return)相關指令時,Return Stack中所記錄的最近八筆Link Register資訊就可以幫助Dynamic Branch Predictor預測可能的分支結果.

2-Stage F#2 提供12 筆 Fetch Queue
3-Stage D#0 Decode.
4-Stage D#1
5-Stage D#2
6-Stage D#3
7-Stage D#4
8-Stage E#0 Architectural Register File
    ALU/MUL Pipeline 0 ALU Pipeline 1 Load/Store Pipeline 0 or 1
9-Stage E#1 Execution.
10-Stage E#2
11-Stage E#3
12-Stage E#4 BP Update(to F#0) BP Update(to F#0) BP Update(to F#0)
13-Stage E#5      
10-Stage NEON Pipeline     Instruction Decode Load and Store with Alignment
1-Stage M#0 16-entry NEON Instruction Queue/Instruction Decode Mux L1/MCR
2-Stage M#1 Decode Queue and Read/Write Check 8-entry Load Queue
3-Stage M#2 Score-Board and Issue-Logic Load Align
4-Stage M#3 NEON Register Read and M3 fwding muxes Mux with NRF
    Integer ALU Pipe Integer MUL Pipe Integer Shift Pipe None-IEEE FP Add Pipe None-IEEE FP Mul Pipe IEEE Single/Double precision VFP Load/Store and Permute Pipe
5-Stage N#1 FMT DUP SHIFT#1 FFMT FDUP VFP PERM#1
6-Stage N#2 ALU MUL#1 SHIFT#2 FADD#1 FMUL#1 Write Back PERM#2
7-Stage N#3 ABS MUL#2 SHIFT#3 FADD#2 FMUL#2   Store Align
8-Stage N#4   ACC#1   FADD#3 FMUL#3   8-entry Store Queue
9-Stage N#5   ACC#2   FADD#4 FMUL#4    
10-Stage N#6 Write Back (Update to ARM/NEON Register File)

Cortex A8支援兩階的Cache,其中L1 Cache支援16kbytes或32kbytes的I/D-Cache(Harvard架構),與每個Byte有一個Bit的校正碼(Parity Bit),每個Cache都支援4ways的機制(可作為4個快取區塊),並使用Hash Virtual Address Buffer(HVAB)預測Pipeline要去L1 Cache抓取的位置,是在哪一個快取區塊,可降低所需的時間與功耗,並支援Write-Back與Write-Through相關機制.

L2 Cache支援64kbyes-2Mbytes範圍的記憶體大小,指令與資料都共用這一塊L2 Cache空間,提供L1 與 L2 Cache間高速的介面,可用來避免處理器頻繁到外部AXI Bus存取資料與和其他周邊搶資源,所造成的效能影響,L2 Cache支援8ways的機制(可作為8個快取區塊),可選擇支援ECC與Parity Bit校正碼,並支援Write-Back,Write-Through與Write-Allocate機制.

ARM Cortex A8是以Coprocessor的架構支援新的NEON多媒體指令集,ARM對於Coprocessor指令的辨別主要是在指令Decode或Issue 時透過跟Coprocessor判別是否為其支援的指令,

NEON多媒體指令的Pipeline主要是介接在ARM核心整數處理Pipeline之後,也因此所有的例外(Exception)處理與分支Branch預測問題在這之前都已經被處理好了,此外,有關對記憶體資料的Load/Store動作,也會在NEON Pipeline之前,就透過ARM核心的Load/Store Pipeline先從L1 D-Cache執行完畢,並儲存相關資料在NEON Pipeline的Load/Store Data Queue中.

NEON有自己的指令暫存空間(NEON Instruction Queue),基於ARM的Dual-Issue架構,每次處理器週期,最多可以指派兩個有效的NEON指令集,NEON的指令集可以一次從L1或L2 Cache中Load/Store 128bits的資料.

NEON有三個整數SIMD Pipelines(包含整數乘法累加Pipeline,整數Shift Pipeline與整數邏輯運算Pipeline),一個Load-Store/Permute Pipeline(負責NEON資料的Load/Store與資料存取整數單元Integer Unit),兩個SIMD single-precision floating-point Pipelines(分別負責浮點數的乘法與加法)與一個Non-Pipelined Vector Floating-Point Unit(VFPLite,遵循ARM VFPv3浮點數規格,並符合IEEE754關於浮點數的規範,並向後相容原本ARM的浮點數實作). NEON指令在Pipeline中是以in-order方式被執行,所處理的資料要不就是NEON整數SIMD指令就是NEON浮點運算指令.

而隨著處理器時脈的提升,每一個處理器Cycle,每一階的 Pipeline所能做的事情也越加精簡(每一個Cycle執行的時間相對也越短),伴隨著就是Pipeline階數的增加,只要Branch Predition的準確度高,Pipeline被Flush的機率低,就能透過Pipeline階數增加得到處理器時脈提升的效能好處.

ARM指令集在每個指令都有4bits的Condition,對於Pipeline的架構來說,可以直接判斷PSR(Program Ststu Register)決定該指令該如何執行的條件,優化效能.

ARM的處理器核心命名也有一個可識別性,例如:ARM7-TDMI (ARM7-Thumb+Debug+Multiplier+ICE),指的就是這個ARM7-TDMI的核心,支援16bits Thumb Code,晶片除錯JTAG (IEEE 1149.1 ),硬體乘法器(Multiplier)與ICE-RT嵌入式邏輯/追蹤巨集單元.或像是J為支援Jazelle指令集與F為支援向量浮點數.

簡單介紹一下,ARM 最新Cortex系列的處理器,從早期的ARM7(armv4),ARM9(armv5),ARM11(armv6)到現在的Cortex(armv7)架構,每一個世代都有包括新的指令集(例如:v4T導入Thumb指令集,v5E導入增強型DSP指令,v6新增Thumb2SIMD指令集),架構與效能上的諸多改善,而到了Cortex時,ARM第一次同時推出三個等級的產品線,主要說明如下

Cortex A(Application)系列 主要用於高性能的開放平台,一般而言也都具備MMU,例如Symbian,Linux/Android或是Windows Mobile/Phone.
Cortex R(Real-Time)系列 用於高端的嵌入式系統產品,例如汽車電子組件,機械手臂這類要求處理器功能強大,高可靠度與對事件反應快速的應用.
Cortex M
(Microcontroller)系列
用於嵌入式與單晶片的產品,針對過去8051這類單晶片所在的Real-Time,低功耗與成本的應用.

 

目前台灣的新唐也推出Cortex-M0低價處理器(mmm…我理解是在1USD以下),或像是Cortex-M3只支援部分常用Thumb2指令集(不支援ARM指令集)與中斷向量表,藉此提供高密度與效能的執行環境.


以下根據ARM系列的差異,逐一說明

(參考網站 http://en.wikipedia.org/wiki/ARM_architecture)

ARM Family ARM Core ARM Architecture Features Cache
(I/D)
MMU/
MPU
Performance Applied
Product
ARM1 ARMv1 ARM1   None None   ARM Evaluation System second processor for BBC Micro
ARM2 ARMv2 ARM2 ARMv2 added the MUL (multiply) instruction None None 4 MIPS @ 8 MHz
0.33 DMIPS/MHz
Acorn Archimedes, Chessmachine
ARMv2a ARM250 Integrated MEMC (MMU), Graphics and IO processor. ARMv2a added the SWP and SWPB (swap) instructions. None MEMC1a 7 MIPS @ 12 MHz Acorn Archimedes
ARM3 ARMv2a ARM3 First integrated memory cache. 4 KB unified None 12 MIPS @ 25 MHz
0.50 DMIPS/MHz
Acorn Archimedes
ARM6 ARMv3 ARM60 ARMv3 first to support 32-bit memory address space (previously 26-bit) None None 10 MIPS @ 12 MHz 3DO Interactive Multiplayer, Zarlink GPS Receiver
ARM600 As ARM60, cache and coprocessor bus (for FPA10 floating-point unit). 4 KB unified None 28 MIPS @ 33 MHz  
ARM610 As ARM60, cache, no coprocessor bus. 4 KB unified None 17 MIPS @ 20 MHz
0.65 DMIPS/MHz
Acorn Risc PC 600, Apple Newton 100 series
ARM7 ARMv3 ARM700   KB unified None   Acorn Risc PC prototype CPU card
ARM710 As ARM700, no coprocessor bus. KB unified None   Acorn Risc PC 700
ARM710a As ARM710 KB unified None 40 MHz
0.68 DMIPS/MHz
Acorn Risc PC 700Apple eMate 300Psion Series 5 (ARM7100),Acorn A7000(ARM7500), Acorn A7000+ (ARM7500FE), Network Computer (ARM7500FE)
ARM7TDMI ARMv4T ARM7TDMI(-S) 3-stage pipeline, Thumb None None 15 MIPS @ 16.8 MHz
63 DMIPS @ 70 MHz
Game Boy AdvanceNintendo DS,Apple iPodLego NXTJuice Box,GarminNavigation Devices (1990s – early 2000s)
ARM710T As ARM7TDMI, cache 8 KB unified MMU 36 MIPS @ 40 MHz Psion Series 5mx, Psion Revo/Revo Plus/Diamond Mako
ARM720T As ARM7TDMI, cache, MMU with Fast Context Switch Extension 8 KB unified MMU 60 MIPS @ 59.8 MHz Zipit Wireless Messenger
ARM740T As ARM7TDMI, cache 8 KB unified MPU    
ARM7EJ ARMv5TEJ ARM7EJ-S 5-stage pipeline, Thumb, Jazelle DBX, Enhanced DSP instructions None None    
ARM8 ARMv4 ARM810 5-stage pipeline, static branch prediction, double-bandwidth memory 8 KB unified MMU 84 MIPS @ 72 MHz
1.16 DMIPS/MHz
Acorn Risc PC prototype CPU card
StrongARM ARMv4 SA-1 5-stage pipeline 16 KB/8–16 KB MMU 203–206 MHz
1.0 DMIPS/MHz
SA-110

 

Apple Newton 2×00 series, Acorn Risc PC, Rebel/Corel Netwinder, Chalice CATS

SA-1100

Psion netBook

SA-1110

LART (computer), Intel Assabet, Ipaq H36x0, Balloon2, Zaurus SL-5×00, HP Jornada 7xx, Jornada 560 series, Palm Zire 31

ARM9TDMI ARMv4T ARM9TDMI 5-stage pipeline, Thumb None None    
ARM920T As ARM9TDMI, cache, MMU with FCSE (Fast Context Switch Extension) 16 KB/16 KB MMU 200 MIPS @ 180 MHz ArmadilloGP32GP2X (first core),Tapwave Zodiac (Motorola i.MX1), Hewlett-Packard
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值