0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

為什么要用MMU?為什么要用虛擬地址?

Linux閱碼場 ? 來源:Linux閱碼場 ? 作者:baron ? 2022-04-26 14:37 ? 次閱讀

1、MMU概念介紹

MMU分為兩個部分: TLB maintenance 和 address translation

5f9f94b6-c3bd-11ec-bce3-dac502259ad0.png

MMU的作用,主要是完成地址的翻譯,即虛擬地址到物理地址的轉(zhuǎn)換,無論是main-memory地址(DDR地址),還是IO地址(設備device地址),在開啟了MMU的系統(tǒng)中,CPU發(fā)起的指令讀取、數(shù)據(jù)讀寫都是虛擬地址,在ARM Core內(nèi)部,會先經(jīng)過MMU將該虛擬地址自動轉(zhuǎn)換成物理地址,然后在將物理地址發(fā)送到AXI總線上,完成真正的物理內(nèi)存、物理設備的讀寫訪問.

那么為什么要用MMU?為什么要用虛擬地址?以下總結(jié)了三點:

多個程序獨立執(zhí)行 --- 不需要知道具體物理地址

虛擬地址是連續(xù)的 --- 程序可以在多個分段的物理內(nèi)存運行

允許操作系統(tǒng)管理內(nèi)存 --- 哪些是可見的,哪些是允許讀寫的,哪些是cacheable的……

既然MMU開啟后,硬件會自動的將虛擬地址轉(zhuǎn)換成物理地址,那么還需要我們軟件做什么事情呢?即創(chuàng)建一個頁表翻譯都需要做哪些事情呢?或者說啟用一個MMU需要軟件做什么事情呢?

設置頁表基地址VBAR_EL3 (Specify the location of the translation table)

初始化MAIR_EL3 (Memory Attribute Indirection Register)

配置TCR_EL3 (Configure the translation regime)

創(chuàng)建頁表 (Generate the translation tables)

Enable the MMU

2、虛擬地址空間和物理地址空間

2.1、(虛擬/物理)地址空間的范圍

內(nèi)核虛擬地址空間的范圍是什么?應用程序的虛擬地址空間的范圍是什么?以前我們在學習操作系統(tǒng)時,最??吹降囊痪湓捠牵簝?nèi)核的虛擬地址空間范圍是3G-4G地址空間,應用程序的虛擬地址空間的范圍是0-3G地址空間;到了aarch64上,則為 :內(nèi)核的虛擬地址空間是0xffff000000000000 - 0xffffffffffffffff , 應用程序的虛擬地址空間是: 0x0000000000000000 - 0x0000ffffffffffff.

做為一名杠精,必需告訴你這句話是錯誤的。錯誤主要有兩點:(1) arm處理器,并沒有規(guī)定你的內(nèi)核必需要使用哪套地址空間,以上這是Linux Kernel自己的設計,它設計了讓Linux Kernel使用0xffff000000000000 - 0xffffffffffffffff地址區(qū)間,Userspace使用0x0000000000000000 - 0x0000ffffffffffff地址區(qū)間,這里正好可以舉一個反例,比如optee os,它的kernel mode和user mode使用的都是高位的虛擬地址空間。(2) 高位是有幾個F(幾個1)是根據(jù)你操作系統(tǒng)使用的有效虛擬地址位來決定的,也并非固定的。比如optee中的mode和user mode的虛擬地址空間范圍都是:0x0000000000000000 - 0x00000000ffffffff

其實arm文檔中有一句標準的描述 :高位是1的虛擬地址空間,使用TTBR1ELx基地址寄存器進行頁表翻譯;高位是0的虛擬地址空間,使用TTBR0ELx基地址寄存器頁表翻譯。 所以不應該說,因為你使用了哪個寄存器(TTBR0/TTBR1),然后決定了你使用的哪套虛擬地址空間;應該說,你操作系統(tǒng)(或userspace軟件)使用了哪套虛擬地址空間,決定了使用哪個哪個基地址寄存器(TTBR0/TTBR1)進行翻譯。

如下便是兩套虛擬地址空間和TTBRn_ELx的對應關系,其中高位的位數(shù)不是固定的16(即T1SZ和T0SZ不一定等于16)

5fb48362-c3bd-11ec-bce3-dac502259ad0.png

以下摘自ARM文檔的官方描述:

As Figure shows, for 48-bit VAs:? The address range translated using TTBR0ELx is 0x0000000000000000 to 0x0000FFFFFFFFFFFF.? The address range translated using TTBR1ELx is 0xFFFF000000000000 to 0xFFFFFFFFFFFFFFFF.In an implementation that includes ARMv8.2-LVA and is using Secure EL3 the 64KB translation granule, for 52-bit VAs:? The address range translated using TTBR0ELx is 0x0000000000000000 to 0x000FFFFFFFFFFFFF.? The address range translated using TTBR1ELx is 0xFFF0000000000000 to 0xFFFFFFFFFFFFFFFF.Which TTBRELx is used depends only on the VA presented for translation. The most significant bits of the VA must all be the same value and:? If the most significant bits of the VA are zero, then TTBR0ELx is used.? If the most significant bits of the VA are one, then TTBR1_ELx is used.

2.2、物理地址空間有效位(范圍)

具體每一個core的物理地址是多少位,其實都是定死的,虛擬地址是多少位,是編譯或開發(fā)的時候根據(jù)自己的需要自己配置的。如下表格摘出了部分arm core的物理地址有效位,所以你具體使用多少有效位的物理地址,可以查詢core TRM手冊。

5fd091e2-c3bd-11ec-bce3-dac502259ad0.png

2.2.1、頁表翻譯相關寄存器的配置

ID_AA64MMFR0_EL1.PARange: Physical address size : 讀取arm寄存器,得到當前系統(tǒng)支持的有效物理地址是多少位

5fe643d4-c3bd-11ec-bce3-dac502259ad0.png

TCR_EL1.IPS: Output address size : 告訴mmu,你需要給我輸出多少位的物理地址

5ffd4958-c3bd-11ec-bce3-dac502259ad0.png

TCR_EL1.T0SZ和TCR_EL1.T1SZ: Input address size : 告訴mmu,我輸入的是多少有效位的虛擬地址

601415de-c3bd-11ec-bce3-dac502259ad0.png

3、Translation regimes

內(nèi)存管理單元 (MMU) 執(zhí)行地址翻譯。MMU 包含以下內(nèi)容:

The table walk unit : 它從內(nèi)存中讀取頁表,并完成地址轉(zhuǎn)換

Translation Lookaside Buffers (TLBs) :緩存,相當于cache

軟件看到的所有內(nèi)存地址都是虛擬的。這些內(nèi)存地址被傳遞到 MMU,它檢查最近使用的緩存轉(zhuǎn)換的 TLB。如果 TLB沒有找到最近緩存的翻譯,那么翻譯單元將從內(nèi)存中讀取適當?shù)囊粋€或多個表項目進行地址翻譯,如下所示:

602a4b4c-c3bd-11ec-bce3-dac502259ad0.png

Translation tables 的工作原理是將虛擬地址空間劃分為大小相等的塊,并在表中為每個塊提供一個entry。Translation tables 中的entry 0 提供block 0 的映射,entry 1 提供block 1 的映射,依此類推。每個entry都包含相應物理內(nèi)存塊的地址以及訪問物理地址時要使用的屬性。

603e518c-c3bd-11ec-bce3-dac502259ad0.png

在當前的ARMV8/ARMV9體系中(暫不考慮armv9的RME擴展), 至少存在以下9類Translation regime:

Secure EL1&0 translation regime, when EL2 is disabledNon-secure EL1&0 translation regime, when EL2 is disabledSecure EL1&0 translation regime, when EL2 is enabledNon-secure EL1&0 translation regime, when EL2 is enabledSecure EL2&0 translation regimeNon-secure EL2&0 translation regimeSecure EL2 translation regimeNon-secure EL2 translation regimeSecure EL3 translation regime

這9類Translation regime的地址翻譯的場景如下圖所示:

60592c28-c3bd-11ec-bce3-dac502259ad0.png

Secure and Non-secure地址空間在REE(linux)和TEE(optee)雙系統(tǒng)的環(huán)境下,可同時開啟兩個系統(tǒng)的MMU.

在secure和non-secure中使用不同的頁表.secure的頁表可以映射non-secure的內(nèi)存,而non-secure的頁表不能去映射secure的內(nèi)存,否則在轉(zhuǎn)換時會發(fā)生錯誤

606cb78e-c3bd-11ec-bce3-dac502259ad0.png

Two Stage TranslationsEL1&0 Translation regime處于VM(Virtual Machine)或SP(Secure Partition)時,EL2 enabled的情況下,是需要stage2轉(zhuǎn)換的。對于EL2 Translation regime 和 EL3 Translation regime是沒用stage2 轉(zhuǎn)換的。

609ad2fe-c3bd-11ec-bce3-dac502259ad0.png

4、地址翻譯/幾級頁表?

4.1、思考:頁表到底有幾級?

從以下圖來看,有的頁表從L2開始,有得從L1開始,有的從L0開始,還有從L-1開始的,都是到L3終止。那么我們的頁表到底有幾級呢?

60b6e61a-c3bd-11ec-bce3-dac502259ad0.png

4.2、以4KB granule為例,頁表的組成方式

60d12ea8-c3bd-11ec-bce3-dac502259ad0.png

除了第一級index(這里是leve 0 table中的index),每一個查找table/page的index都是9個bit,也就是說除了第一級頁表,后面的每一級table都是有512個offset

如果VA_BIT = 39,那么leve 0 table用BIT[38:39]表示,只有1個offset

如果VA_BIT = 48,那么leve 0 table用BIT[47:39]表示,有512個offset

如果VABIT > 48,那是不存在的,因為arm規(guī)定,大于48的,只有一個,那就是VABIT=52,并且規(guī)定該情況下的最小granue size=64KB,而我們這里講述的是granue size=4KB的情況

如果VABIT = 32,那么leve 0 table就不用了,TTBRELx指向Level 1 table

另外我們還需注意一點,在Level 0 table中,他只能指向DTable,不能指向DBlock

以下針對虛擬地址是48有效位的情形做了一個總結(jié):

60ee14a0-c3bd-11ec-bce3-dac502259ad0.png

4.3、optee實際使用的示例

32位有效虛擬地址、,3級頁表查詢(L1、L2、L3),顆粒的位4KB

61088970-c3bd-11ec-bce3-dac502259ad0.png

如下展示是optee os的頁表結(jié)構(gòu),TTBR0_EL1指向L1 Table,L1 Table中有4個表項,但只用了3個 , 也就對應著3張L2 Table.

611ecdf2-c3bd-11ec-bce3-dac502259ad0.png

配置相關的代碼如下:

61380e3e-c3bd-11ec-bce3-dac502259ad0.png

5、頁表格式(Descriptor format)

5.1、ARMV8支持的3種頁表格式

AArch64 Long Descriptor:我們只學習這個

Armv7-A Long Descriptor :for Large Physical Address Extension (LPAE)

Armv7-A Short Descriptor

5.2、AArch64 Long Descriptor支持的四種entry

對于AArch64 Long Descriptor,又分為下面四種entry:

An invalid or fault entry.

A table entry, that points to the next-level translation table.

A block entry, that defines the memory properties for the access.

A reserved format

注意:entry[1:0] 表示該entry屬于哪類entry, Block Descriptor和Page Descriptor是一個意思。在當前架構(gòu)中,reserved也是invalid。

615b081c-c3bd-11ec-bce3-dac502259ad0.png

5.3、頁表的屬性位介紹( Block Descriptor/Page Descriptor )

5.3.1、stage1的頁表屬性

(Attribute fields in stage 1 VMSAv8-64 Block and Page descriptors)

6173113c-c3bd-11ec-bce3-dac502259ad0.png

PBHA, bits[62:59] :for FEAT_HPDS2

XN or UXN, bit[54] :Execute-never or Unprivileged execute-never

PXN, bit[53] :Privileged execute-never

Contiguous, bit[52] :translation table entry 是連續(xù)的,可以存在一個TLB Entry中

DBM, bit[51] :Dirty Bit Modifier

GP, bit[50] :for FEAT_BTI

nT, bit[16] :for FEAT_BBM

nG, bit[11] :緩存在TLB中的翻譯是否使用ASID標識

AF, bit[10] :Access flag, AF=0后,第一次訪問該頁面時,會將該標志置為1. 即暗示第一次訪問

SH, bits[9:8] :shareable屬性

AP[2:1], bits[7:6] :Data Access Permissions bits,

NS, bit[5] :Non-secure bit

AttrIndx[2:0], bits[4:2] :

5.3.2、stage2的頁表屬性

(Attribute fields in stage 2 VMSAv8-64 Block and Page descriptors)

618a6882-c3bd-11ec-bce3-dac502259ad0.png

PBHA[3:1], bits[62:60] :for FEAT_HPDS2

PBHA[0], bit[59] :for FEAT_HPDS2

XN[1:0], bits[54:53] :Execute-never

Contiguous, bit[52] :translation table entry 是連續(xù)的,可以存在一個TLB Entry中

DBM, bit[51] :Dirty Bit Modifier

nT, bit[16] :for FEAT_BBM

FnXS, bit[11] :for FEAT_XS

AF, bit[10] :Access flag

SH, bits[9:8] :shareable屬性

S2AP, bits[7:6] :Stage 2 data Access Permissions

MemAttr, bits[5:2] :

5.3.3、其它標志位的詳細介紹

(1)、MemAttr指向MAIR_ELx寄存器中的attrn屬性域,表示內(nèi)存的緩存屬性,如cachable、shareable等

(2)、NSNon-secure比特表示轉(zhuǎn)換后的物理地址是secure的還是non-secure的。

(3)、APData access permissions 數(shù)據(jù)訪問權(quán)限

61a5a9e4-c3bd-11ec-bce3-dac502259ad0.png

(4)、SH

shareable屬性

61ba2540-c3bd-11ec-bce3-dac502259ad0.png

(5)、AFAccess flag, AF=0后,第一次訪問該頁面時,會將該標志置為1. 即暗示第一次訪問(6)、nG對于 EL0/EL1 虛擬地址空間,Page Descriptor屬性字段中的 nG 位將轉(zhuǎn)換標記為Gloabl(G) 或non-Gloabl(nG)。例如,內(nèi)核映射是Gloabl(G)翻譯,應用程序映射是non-Gloabl翻譯。Gloabl翻譯適用于當前正在運的任何應用程序。非全局翻譯僅適用于特定應用程序

non-Gloabl映射在 TLB 中使用 ASID進行標記。在 TLB 查找時,將 TLB 條目中的 ASID 與當前選擇的 ASID 進行比較。如果它們不匹配,則不使用TLB 條目。下圖顯示了內(nèi)核空間中沒有 ASID 標記的全局映射和用戶空間中具有 ASID 標記的非全局映射

61d2f9a8-c3bd-11ec-bce3-dac502259ad0.png

(7)、XN or UXN特權(quán)和非特權(quán)不可從該memory-region中執(zhí)行指令的標志位:Execute-neverUnprivileged execute-never

6、地址翻譯指令介紹

address translation的指令大約14個:

61eb66e6-c3bd-11ec-bce3-dac502259ad0.png

總結(jié)一下:

61fffc64-c3bd-11ec-bce3-dac502259ad0.png

7、地址翻譯相關的系統(tǒng)寄存器總結(jié)

地址轉(zhuǎn)換由系統(tǒng)寄存器的組合控制:

7.1 SCTLR_ELx

6218f750-c3bd-11ec-bce3-dac502259ad0.png

622f2246-c3bd-11ec-bce3-dac502259ad0.png

系統(tǒng)控制寄存器,控制著MMU、I-cache、D-cache的打開與關閉,也控制著translation table walks訪問內(nèi)存的大小端。

M - Enable Memory Management Unit (MMU).

C - Enable for data and unified caches.

EE - Endianness of translation table walks.

7.2 TTBRn_ELx

6249630e-c3bd-11ec-bce3-dac502259ad0.png

62688a72-c3bd-11ec-bce3-dac502259ad0.png

BADDR : 基地址

ASID :TLB entry區(qū)分user程序所用的ASID

7.3 TCR_ELx

在ARM Core中(aarch64),有三個Translation Control Register 寄存器:

627dddb4-c3bd-11ec-bce3-dac502259ad0.png

6293a64e-c3bd-11ec-bce3-dac502259ad0.png

比特位 功能 說明
ORGN1、IRGN1、ORGN0、IRGN0 cacheable屬性 outer/inner cableability的屬性(如直寫模式、回寫模式)
SH1、SH0 shareable屬性 cache的共享屬性配置(如non-shareable, outer/inner shareable)
TG0/TG1 Granule size Granule size(其實就是頁面的大小,4k/16k/64k)
IPS 物理地址size 物理地址size,如32bit/36bit/40bit
EPD1、EPD0 - TTBREL1/TTBREL0的enable和disable
TBI1、TBI0 - top addr是ignore,還是用于MTE的計算
A1 - ASID的選擇,是使用TTBREL1中的,還是使用TTBREL0中的
AS - ASID是使用8bit,還是使用16bit

7.3 MAIR_ELx

內(nèi)存屬性寄存器,分為8個Attrn,所以一個core,最多只支持8中內(nèi)存屬性。頁表中的每一個entry,都會指向一個Attr域。

62a8e2d4-c3bd-11ec-bce3-dac502259ad0.png

審核編輯 :李倩

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 處理器
    +關注

    關注

    68

    文章

    19028

    瀏覽量

    228441
  • MMU
    MMU
    +關注

    關注

    0

    文章

    91

    瀏覽量

    18235
  • 深度學習
    +關注

    關注

    73

    文章

    5429

    瀏覽量

    120787

原文標題:armv8-armv9 MMU深度學習

文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關推薦

    stm32l053的USB口要用來當做虛擬串口,請問這個驅(qū)動在哪里下載?

    stm32l053的USB口要用來當做虛擬串口,請問這個驅(qū)動在哪里下載?
    發(fā)表于 05-07 08:04

    虛擬機的ip地址和主機一樣嗎

    虛擬機的ip地址和主機一樣嗎? 虛擬機的IP地址和主機的IP地址通常不相同。虛擬機是在主機上通過
    的頭像 發(fā)表于 03-26 15:34 ?4287次閱讀

    為什么要用數(shù)電發(fā)票

    數(shù)據(jù)中臺,作為現(xiàn)代企業(yè)的重要戰(zhàn)略之一,正日益受到企業(yè)界的廣泛重視。在信息時代,數(shù)據(jù)被認為是企業(yè)最重要的資產(chǎn)之一,而數(shù)據(jù)中臺則是將企業(yè)內(nèi)部外部的各種數(shù)據(jù)集中管理、整合和應用的平臺。數(shù)聚將從幾個關鍵角度,來闡述為什么要用數(shù)據(jù)中臺。
    的頭像 發(fā)表于 01-18 11:11 ?331次閱讀

    沒有虛擬地址的處理器是怎么工作的?

    看看沒有虛擬地址的處理器是怎么工作的,編譯環(huán)境除了將高級語言轉(zhuǎn)換成機器碼外,linker把眾多分散開發(fā)文件串起來,使得增量編譯
    的頭像 發(fā)表于 12-07 10:29 ?335次閱讀

    MMU虛擬地址空間布局

    當然虛擬地址空間劃分不只是如此。因為目前應用程序沒有那么大的內(nèi)存需求,所以ARM64處理器不支持完全的64位虛擬地址,實際支持情況如下。 (1)-虛擬地址位寬 虛擬地址的最大寬度是48
    的頭像 發(fā)表于 11-26 16:35 ?793次閱讀

    MMU多級頁表映射過程

    空間,也有相應的頁表負責虛擬地址到物理地址之間的轉(zhuǎn)換。MMU查詢的過程中,用戶進程的一級頁表的基址存放在TTBR0。操作系統(tǒng)的內(nèi)核空間公用一塊地址空間,
    的頭像 發(fā)表于 11-26 16:28 ?872次閱讀
    <b class='flag-5'>MMU</b>多級頁表映射過程

    MMU中的頁命中、缺頁介紹

    頁命中、缺頁 (1)頁命中 ? a) 處理器要對虛擬地址VA進行訪問。 ? b) MMU的TLB沒有命中,通過TWU遍歷主存頁表中的PTEA(PTE地址)。 ? c) 主存向MMU返回
    的頭像 發(fā)表于 11-26 16:19 ?943次閱讀
    <b class='flag-5'>MMU</b>中的頁命中、缺頁介紹

    MMU相關的基本概念

    1-MMU相關的基本概念 (1)虛擬地址相關基本概念 ? 虛擬內(nèi)存(Virtual Memory,VM):為每個進程提供了一致的、連續(xù)的、私有的內(nèi)存空間,簡化了內(nèi)存管理。將主存看成是一個存儲在磁盤
    的頭像 發(fā)表于 11-26 16:11 ?607次閱讀

    為什么要有TLB

    TLB 是 translation lookaside buffer 的簡稱。首先,我們知道 MMU 的作用是把虛擬地址轉(zhuǎn)換成物理地址虛擬地址和物理
    的頭像 發(fā)表于 11-26 15:54 ?608次閱讀
    為什么要有TLB

    MMU包含兩個模塊是什么

    的物理地址也有兩部分:PFN和offset,PFN( Physical frame number)是物理頁框number,offset和上面虛擬地址的offset相同,是頁內(nèi)偏移。 2-MMU包含兩個
    的頭像 發(fā)表于 11-26 15:40 ?544次閱讀
    <b class='flag-5'>MMU</b>包含兩個模塊是什么

    MMU內(nèi)存管理單元的宏觀理解

    (Memory Management Unit,內(nèi)存管理單元)是一種硬件模塊,用于在CPU和內(nèi)存之間實現(xiàn)虛擬內(nèi)存管理。 其主要功能是將虛擬地址轉(zhuǎn)換為物理地址,同時提供訪問權(quán)限的控制和緩存管理等功能。 放在整個大系統(tǒng)多核架構(gòu)里面,
    的頭像 發(fā)表于 11-26 15:21 ?492次閱讀
    <b class='flag-5'>MMU</b>內(nèi)存管理單元的宏觀理解

    linux內(nèi)存性能優(yōu)化介紹

    不同;圖示為 32 位和 64 位系統(tǒng)的虛擬地址空間; 內(nèi)存映射是將虛擬內(nèi)存地址映射到物理內(nèi)存地址,內(nèi)核為每個進程都維護了一張頁表,記錄虛擬地址與物理
    的頭像 發(fā)表于 11-10 15:23 ?622次閱讀
    linux內(nèi)存性能優(yōu)化介紹

    MMU原理:CPU是如何訪問到內(nèi)存的?

    當CPU訪問虛擬地址0的時候,MMU會去查上面頁表的第0行,發(fā)現(xiàn)第0行沒有命中,于是無論以何種形式(R讀,W寫,X執(zhí)行)訪問,MMU都會給CPU發(fā)出page fault,CPU自動跳到fault的代碼去處理fault。
    發(fā)表于 11-09 12:30 ?1004次閱讀
    <b class='flag-5'>MMU</b>原理:CPU是如何訪問到內(nèi)存的?

    虛擬內(nèi)存到物理地址的轉(zhuǎn)換

    處理器根據(jù)頁表基地址控制寄存器TTBCR和虛擬地址來判斷使用哪個頁表基地址寄存器,是TTBR0還是TTBR1。(一個基值是內(nèi)核的,一個用戶態(tài)的) 頁表基地址寄存器中存放著一級頁表的基
    的頭像 發(fā)表于 10-30 17:34 ?631次閱讀
    <b class='flag-5'>虛擬</b>內(nèi)存到物理<b class='flag-5'>地址</b>的轉(zhuǎn)換

    嵌入式Linux運行一定需要MMU嗎?為什么需要MMU?

    虛擬內(nèi)存功能和保護機制的重要角色。 MMU(Memory Management Unit)是一種硬件機制,它為CPU提供了一種虛擬內(nèi)存映射的功能,可以將物理地址映射到
    的頭像 發(fā)表于 10-29 16:28 ?699次閱讀