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

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

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

從高級(jí)的視角來查看Linux引導(dǎo)過程

Q4MP_gh_c472c21 ? 來源:未知 ? 作者:李倩 ? 2018-08-22 14:10 ? 次閱讀

早期時(shí),啟動(dòng)一臺(tái)計(jì)算機(jī)意味著要給計(jì)算機(jī)喂一條包含引導(dǎo)程序的紙帶,或者手工使用前端面板地址/數(shù)據(jù)/控制開關(guān)來加載引導(dǎo)程序。盡管目前的計(jì)算機(jī)已經(jīng)裝備了很多工具來簡(jiǎn)化引導(dǎo)過程,但是這一切并沒有對(duì)整個(gè)過程進(jìn)行必要的簡(jiǎn)化。

讓我們先從高級(jí)的視角來查看Linux引導(dǎo)過程,這樣就可以看到整個(gè)過程的全貌了。然后將回顧一下在各個(gè)步驟到底發(fā)生了什么。在整個(gè)過程中,參考一下內(nèi)核源代碼可以幫助我們更好地了解內(nèi)核源代碼樹,并在以后對(duì)其進(jìn)行深入分析。

1、概述

圖 1 是我們?cè)?0,000 英尺的高度看到的視圖。

當(dāng)系統(tǒng)首次引導(dǎo)時(shí),或系統(tǒng)被重置時(shí),處理器會(huì)執(zhí)行一個(gè)位于已知位置處的代碼。在個(gè)人計(jì)算機(jī)(PC)中,這個(gè)位置在基本輸入/輸出系統(tǒng)(BIOS)中,它保存在主板上的閃存中。嵌入式系統(tǒng)中的中央處理單元(CPU)會(huì)調(diào)用這個(gè)重置向量來啟動(dòng)一個(gè)位于閃存/ROM中的已知地址處的程序。在這兩種情況下,結(jié)果都是相同的。因?yàn)镻C提供了很多靈活性,BIOS必須確定要使用哪個(gè)設(shè)備來引導(dǎo)系統(tǒng)。稍后我們將詳細(xì)介紹這個(gè)過程。

當(dāng)找到一個(gè)引導(dǎo)設(shè)備之后,第一階段的引導(dǎo)加載程序就被裝入RAM并執(zhí)行。這個(gè)引導(dǎo)加載程序在大小上小于512 字節(jié)(一個(gè)扇區(qū)),其作用是加載第二階段的引導(dǎo)加載程序。

當(dāng)?shù)诙A段的引導(dǎo)加載程序被裝入RAM 并執(zhí)行時(shí),通常會(huì)顯示一個(gè)動(dòng)畫屏幕,并將Linux 和一個(gè)可選的初始 RAM磁盤(臨時(shí)根文件系統(tǒng))加載到內(nèi)存中。在加載映像時(shí),第二階段的引導(dǎo)加載程序就會(huì)將控制權(quán)交給內(nèi)核映像,然后內(nèi)核就可以進(jìn)行解壓和初始化了。在這個(gè)階段中,第二階段的引導(dǎo)加載程序會(huì)檢測(cè)系統(tǒng)硬件、枚舉系統(tǒng)鏈接的硬件設(shè)備、掛載根設(shè)備,然后加載必要的內(nèi)核模塊。完成這些操作之后啟動(dòng)第一個(gè)用戶空間程序(init),并執(zhí)行高級(jí)系統(tǒng)初始化工作。

這就是 Linux引導(dǎo)的整個(gè)過程?,F(xiàn)在讓我們深入挖掘一下這個(gè)過程,并深入研究一下Linux引導(dǎo)過程的一些詳細(xì)信息。

2、系統(tǒng)啟動(dòng)

系統(tǒng)啟動(dòng)階段依賴于引導(dǎo)Linux系統(tǒng)上的硬件。在嵌入式平臺(tái)中,當(dāng)系統(tǒng)加電或重置時(shí),會(huì)使用一個(gè)啟動(dòng)環(huán)境。這方面的例子包括U-Boot、RedBoot和Lucent的MicroMonitor。嵌入式平臺(tái)通常都是與引導(dǎo)監(jiān)視器搭配銷售的。這些程序位于目標(biāo)硬件上的閃存中的某一段特殊區(qū)域,它們提供了將Linux內(nèi)核映像下載到閃存并繼續(xù)執(zhí)行的方法。除了可以存儲(chǔ)并引導(dǎo)Linux映像之外,這些引導(dǎo)監(jiān)視器還執(zhí)行一定級(jí)別的系統(tǒng)測(cè)試和硬件初始化過程。在嵌入式平臺(tái)中,這些引導(dǎo)監(jiān)視器通常會(huì)涉及第一階段和第二階段的引導(dǎo)加載程序。

在 PC 中,引導(dǎo)Linux 是從 BIOS 中的地址0xFFFF0 處開始的。BIOS的第一個(gè)步驟是加電自檢(POST)。POST的工作是對(duì)硬件進(jìn)行檢測(cè)。BIOS的第二個(gè)步驟是進(jìn)行本地設(shè)備的枚舉和初始化。

給定 BIOS 功能的不同用法之后,BIOS由兩部分組成:POST 代碼和運(yùn)行時(shí)服務(wù)。當(dāng)POST 完成之后,它被從內(nèi)存中清理了出來,但是BIOS運(yùn)行時(shí)服務(wù)依然保留在內(nèi)存中,目標(biāo)操作系統(tǒng)可以使用這些服務(wù)。

要引導(dǎo)一個(gè)操作系統(tǒng),BIOS運(yùn)行時(shí)會(huì)按照CMOS的設(shè)置定義的順序來搜索處于活動(dòng)狀態(tài)并且可以引導(dǎo)的設(shè)備。引導(dǎo)設(shè)備可以是軟盤、CD-ROM、硬盤上的某個(gè)分區(qū)、網(wǎng)絡(luò)上的某個(gè)設(shè)備,甚至是USB閃存。

通常,Linux都是從硬盤上引導(dǎo)的,其中主引導(dǎo)記錄(MBR)中包含主引導(dǎo)加載程序。MBR是一個(gè)512 字節(jié)大小的扇區(qū),位于磁盤上的第一個(gè)扇區(qū)中(0道0 柱面1 扇區(qū))。當(dāng) MBR 被加載到RAM 中之后,BIOS 就會(huì)將控制權(quán)交給MBR。

注意:要查看 MBR的內(nèi)容,請(qǐng)使用下面的命令:

# ddif=/dev/hda of=mbr.bin bs=512 count=1#od -xambr.bin

這 個(gè)dd 命令需要以root用戶的身份運(yùn)行,它從/dev/hda(第一個(gè)IDE 盤)上讀取前 512 個(gè)字節(jié)的內(nèi)容,并將其寫入mbr.bin 文件中。od命令會(huì)以十六進(jìn)制和ASCII碼格式打印這個(gè)二進(jìn)制文件的內(nèi)容。

MBR 中的主引導(dǎo)加載程序是一個(gè)512 字節(jié)大小的映像,其中包含程序代碼和一個(gè)小分區(qū)表(參見圖2)。前 446個(gè)字節(jié)是主引導(dǎo)加載程序,其中包含可執(zhí)行代碼和錯(cuò)誤消息文本。接下來的64個(gè)字節(jié)是分區(qū)表,其中包含4 個(gè)分區(qū)的記錄(每個(gè)記錄的大小是16 個(gè)字節(jié))。MBR以兩個(gè)特殊數(shù)字的字節(jié)(0xAA55)結(jié)束。這個(gè)數(shù)字會(huì)用來進(jìn)行MBR的有效性檢查。

圖2. MBR剖析

主引導(dǎo)加載程序的工作是查找并加載次引導(dǎo)加載程序(第二階段)。它是通過在分區(qū)表中查找一個(gè)活動(dòng)分區(qū)來實(shí)現(xiàn)這種功能的。當(dāng)找到一個(gè)活動(dòng)分區(qū)時(shí),它會(huì)掃描分區(qū)表中的其他分區(qū),以確保它們都不是活動(dòng)的。當(dāng)這個(gè)過程驗(yàn)證完成之后,就將活動(dòng)分區(qū)的引導(dǎo)記錄從這個(gè)設(shè)備中讀入RAM中并執(zhí)行它。

4、第二階段引導(dǎo)加載程序

次引導(dǎo)加載程序(第二階段引導(dǎo)加載程序)可以更形象地稱為內(nèi)核加載程序。這個(gè)階段的任務(wù)是加載Linux內(nèi)核和可選的初始 RAM磁盤。

在 x86 PC環(huán)境中,第一階段和第二階段的引導(dǎo)加載程序一起稱為L(zhǎng)inux Loader(LILO)或GRand Unified Bootloader(GRUB)。由于LILO有一些缺點(diǎn),而 GRUB克服了這些缺點(diǎn),因此下面讓我們就來看一下GRUB。

關(guān)于 GRUB,很好的一件事情是它包含了有關(guān)Linux文件系統(tǒng)的知識(shí)。GRUB不像LILO 一樣使用裸扇區(qū),而是可以從ext2 或 ext3 文件系統(tǒng)中加載Linux 內(nèi)核。它是通過將兩階段的引導(dǎo)加載程序轉(zhuǎn)換成三階段的引導(dǎo)加載程序來實(shí)現(xiàn)這項(xiàng)功能的。階段1 (MBR)引導(dǎo)了一個(gè)階段1.5 的引導(dǎo)加載程序,它可以理解包含Linux 內(nèi)核映像的特殊文件系統(tǒng)。這方面的例子包括reiserfs_stage1_5(要從Reiser日志文件系統(tǒng)上進(jìn)行加載)或e2fs_stage1_5(要從ext2或 ext3 文件系統(tǒng)上進(jìn)行加載)。當(dāng)階段1.5 的引導(dǎo)加載程序被加載并運(yùn)行時(shí),階段2的引導(dǎo)加載程序就可以進(jìn)行加載了。

當(dāng)階段2加載之后,GRUB就可以在請(qǐng)求時(shí)顯示可用內(nèi)核列表(在/etc/grub.conf中進(jìn)行定義,同時(shí)還有幾個(gè)軟符號(hào)鏈接/etc/grub/menu.lst和/etc/grub.conf)。我們可以選擇內(nèi)核甚至修改附加內(nèi)核參數(shù)。另外,我們也可以使用一個(gè)命令行的shell對(duì)引導(dǎo)過程進(jìn)行高級(jí)手工控制。

GRUB階段引導(dǎo)加載程序:/boot/grub目錄中包含了stage1、stage1.5和stage2引導(dǎo)加載程序,以及很多其他加載程序(例如,CR-ROM使用的是iso9660_stage_1_5)。

將第二階段的引導(dǎo)加載程序加載到內(nèi)存中之后,就可以對(duì)文件系統(tǒng)進(jìn)行查詢了,并將默認(rèn)的內(nèi)核映像和initrd映像加載到內(nèi)存中。當(dāng)這些映像文件準(zhǔn)備好之后,階段2 的引導(dǎo)加載程序就可以調(diào)用內(nèi)核映像了。

5、內(nèi)核

當(dāng)內(nèi)核映像被加載到內(nèi)存中,并且階段2 的引導(dǎo)加載程序釋放控制權(quán)之后,內(nèi)核階段就開始了。內(nèi)核映像并不是一個(gè)可執(zhí)行的內(nèi)核,而是一個(gè)壓縮過的內(nèi)核映像。通常它是一個(gè)zImage(壓縮映像,小于512KB)或一個(gè)bzImage(較大的壓縮映像,大于512KB),它是提前使用zlib進(jìn)行壓縮過的。在這個(gè)內(nèi)核映像前面是一個(gè)例程,它實(shí)現(xiàn)少量硬件設(shè)置,并對(duì)內(nèi)核映像中包含的內(nèi)核進(jìn)行解壓,然后將其放入高端內(nèi)存中,如果有初始RAM磁盤映像,就會(huì)將它移動(dòng)到內(nèi)存中,并標(biāo)明以后使用。然后該例程會(huì)調(diào)用內(nèi)核,并開始啟動(dòng)內(nèi)核引導(dǎo)的過程。

當(dāng) bzImage(用于i386映像)被調(diào)用時(shí),我們從./arch/i386/boot/head.S的start 匯編例程開始執(zhí)行(主要流程圖請(qǐng)參看圖3)。這個(gè)例程會(huì)執(zhí)行一些基本的硬件設(shè)置,并調(diào)用./arch/i386/boot/compressed/head.S中的startup_32例程。此例程會(huì)設(shè)置一個(gè)基本的環(huán)境(堆棧等),并清除Block Started by Symbol(BSS)。然后調(diào)用一個(gè)叫做decompress_kernel的C 函數(shù)(在./arch/i386/boot/compressed/misc.c中)來解壓內(nèi)核。當(dāng)內(nèi)核被解壓到內(nèi)存中之后,就可以調(diào)用它了。這是另外一個(gè)startup_32函數(shù),但是這個(gè)函數(shù)在./arch/i386/kernel/head.S中。

在這個(gè)新的 startup_32函數(shù)(也稱為清除程序或進(jìn)程0)中,會(huì)對(duì)頁(yè)表進(jìn)行初始化,并啟用內(nèi)存分頁(yè)功能。然后會(huì)為任何可選的浮點(diǎn)單元(FPU)檢測(cè)CPU的類型,并將其存儲(chǔ)起來供以后使用。然后調(diào)用start_kernel函數(shù)(在init/main.c中),它會(huì)將您帶入與體系結(jié)構(gòu)無關(guān)的Linux 內(nèi)核部分。實(shí)際上,這就是Linux 內(nèi)核的 main函數(shù)。

圖3. Linux內(nèi)核i386引導(dǎo)的主要函數(shù)流程

注意函數(shù)decompress_kernel就是顯示我們通??吹降慕鈮合⒌牡胤剑?/p>

Uncompressing Linux... Ok, booting thekernel.

通過調(diào)用start_kernel,會(huì)調(diào)用一系列初始化函數(shù)來設(shè)置中斷,執(zhí)行進(jìn)一步的內(nèi)存配置,并加載初始RAM磁盤。最后,要調(diào)用kernel_thread(在arch/i386/kernel/process.c中)來啟動(dòng)init函數(shù),這是第一個(gè)用戶空間進(jìn)程(user-spaceprocess)。最后,啟動(dòng)空任務(wù),現(xiàn)在調(diào)度器就可以接管控制權(quán)了(在調(diào)用cpu_idle之后)。通過啟用中斷,搶占式的調(diào)度器就可以周期性地接管控制權(quán),從而提供多任務(wù)處理能力。

在內(nèi)核引導(dǎo)過程中,初始 RAM磁盤(initrd)是由階段2引導(dǎo)加載程序加載到內(nèi)存中的,它會(huì)被復(fù)制到RAM 中并掛載到系統(tǒng)上。這個(gè)initrd 會(huì)作為RAM中的臨時(shí)根文件系統(tǒng)使用,并允許內(nèi)核在沒有掛載任何物理磁盤的情況下完整地實(shí)現(xiàn)引導(dǎo)。由于與外圍設(shè)備進(jìn)行交互所需要的模塊可能是initrd的一部分,因此內(nèi)核可以非常小,但是仍然需要支持大量可能的硬件配置。在內(nèi)核引導(dǎo)之后,就可以正式裝備根文件系統(tǒng)了(通過pivot_root):此時(shí)會(huì)將initrd根文件系統(tǒng)卸載掉,并掛載真正的根文件系統(tǒng)。

initrd函數(shù)讓我們可以創(chuàng)建一個(gè)小型的Linux內(nèi)核,其中包括作為可加載模塊編譯的驅(qū)動(dòng)程序。這些可加載的模塊為內(nèi)核提供了訪問磁盤和磁盤上的文件系統(tǒng)的方法,并為其他硬件提供了驅(qū)動(dòng)程序。由于根文件系統(tǒng)是磁盤上的一個(gè)文件系統(tǒng),因此initrd函數(shù)會(huì)提供一種啟動(dòng)方法來獲得對(duì)磁盤的訪問,并掛載真正的根文件系統(tǒng)。在一個(gè)沒有硬盤的嵌入式環(huán)境中,initrd可以是最終的根文件系統(tǒng),或者也可以通過網(wǎng)絡(luò)文件系統(tǒng)(NFS)來掛載最終的根文件系統(tǒng)。

6、Init

當(dāng)內(nèi)核被引導(dǎo)并進(jìn)行初始化之后,內(nèi)核就可以啟動(dòng)自己的第一個(gè)用戶空間應(yīng)用程序了。這是第一個(gè)調(diào)用的使用標(biāo)準(zhǔn)C庫(kù)編譯的程序。在此之前,還沒有執(zhí)行任何標(biāo)準(zhǔn)的C 應(yīng)用程序。

在桌面 Linux 系統(tǒng)上,第一個(gè)啟動(dòng)的程序通常是/sbin/init。但是這不是一定的。很少有嵌入式系統(tǒng)會(huì)需要使用init所提供的豐富初始化功能(這是通過/etc/inittab進(jìn)行配置的)。在很多情況下,我們可以調(diào)用一個(gè)簡(jiǎn)單的shell腳本來啟動(dòng)必需的嵌入式應(yīng)用程序。

7、結(jié)束語(yǔ)

與Linux本身非常類似,Linux的引導(dǎo)過程也非常靈活,可以支持眾多的處理器和硬件平臺(tái)。最初,加載引導(dǎo)加載程序提供了一種簡(jiǎn)單的方法,不用任何花架子就可以引導(dǎo)Linux。LILO引導(dǎo)加載程序?qū)σ龑?dǎo)能力進(jìn)行了擴(kuò)充,但是它卻缺少文件系統(tǒng)的感知能力。最新一代的引導(dǎo)加載程序,例如GRUB,允許Linux 從一些文件系統(tǒng)(從Minix 到 Reise)上進(jìn)行引導(dǎo)。

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

    關(guān)注

    87

    文章

    11123

    瀏覽量

    207912
  • 計(jì)算機(jī)
    +關(guān)注

    關(guān)注

    19

    文章

    7174

    瀏覽量

    87157
  • 源代碼
    +關(guān)注

    關(guān)注

    96

    文章

    2942

    瀏覽量

    66444

原文標(biāo)題:從高級(jí)視角查看Linux引導(dǎo)過程,高手帶你揭開Linux過程內(nèi)幕

文章出處:【微信號(hào):gh_c472c2199c88,微信公眾號(hào):嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    嵌入式Linux引導(dǎo)過程是怎樣的?

    歡迎關(guān)注公眾號(hào),文章會(huì)同步發(fā)布在嵌入式客棧引言:本文簡(jiǎn)明扼要的介紹了嵌入式Linux引導(dǎo)過程,X86體系的引導(dǎo)過程以及幾種常見嵌入式處理器
    發(fā)表于 12-17 07:25

    LINUX系統(tǒng)引導(dǎo)和初始化-LINUX內(nèi)核解讀

    Linux 的系統(tǒng)引導(dǎo)和初始化 ----------Linux2.4.22內(nèi)核解讀之一 一、 系統(tǒng)引導(dǎo)和初始化概述 相關(guān)代碼(引導(dǎo)扇區(qū)的程序
    發(fā)表于 11-03 22:31 ?53次下載

    Linux開機(jī)引導(dǎo)和啟動(dòng)過程詳解

    。啟動(dòng)階段接管了剩余工作,直到操作系統(tǒng)進(jìn)入可操作狀態(tài)??傮w來說,Linux 的開機(jī)引導(dǎo)和啟動(dòng)過程是相當(dāng)容易理解,下文將分節(jié)對(duì)于不同步驟進(jìn)行詳細(xì)說明。BIOS 上電自檢(POST)引導(dǎo)
    發(fā)表于 04-02 14:46 ?442次閱讀

    簡(jiǎn)述Linux文本查看命令

    Linux 常用命令中,除了 cat 還有很多其他用于文本查看的命令。
    的頭像 發(fā)表于 08-11 11:17 ?3439次閱讀

    使用Linux命令lsof查看進(jìn)程打開和查看文件的說明

    linux命令 — lsof 查看進(jìn)程打開那些文件 或者 查看文件給那個(gè)進(jìn)程使用對(duì)調(diào)試文件有很好的幫助和精準(zhǔn)定位問題
    發(fā)表于 10-28 08:00 ?0次下載

    Linux服務(wù)的內(nèi)容如何查看

     ps是進(jìn)程查看命令,netstat是端口查看命令,在Linux系統(tǒng)中,服務(wù)一定是有進(jìn)程的,所以使用ps命令可以查看服務(wù)運(yùn)行情況,另外,Linux
    發(fā)表于 05-20 09:09 ?698次閱讀
    <b class='flag-5'>Linux</b>服務(wù)的內(nèi)容如何<b class='flag-5'>查看</b>

    linux的主機(jī)名如何查看

    linux如何查看主機(jī)名?
    發(fā)表于 06-15 08:59 ?5239次閱讀
    <b class='flag-5'>linux</b>的主機(jī)名如何<b class='flag-5'>查看</b>

    如何在Linux查看隱藏文件

    在windows可以查看隱藏的文件。在Linux中也可以查看隱藏文件且非常容易。要查看隱藏文件運(yùn)行`ls -a`命令即可。
    的頭像 發(fā)表于 01-04 17:31 ?1.5w次閱讀

    Linux程序被Killed,查看原因

    Linux程序被Killed,查看原因
    的頭像 發(fā)表于 01-11 10:17 ?2087次閱讀

    ARMv7安全引導(dǎo)過程

    一樣使用BootLoader引導(dǎo)Linux內(nèi)核和TEE OS。安全引導(dǎo)的啟動(dòng)流程如圖下所示。 安全引導(dǎo)的啟動(dòng)流程 系統(tǒng)啟動(dòng)
    的頭像 發(fā)表于 11-07 15:25 ?646次閱讀
    ARMv7安全<b class='flag-5'>引導(dǎo)</b>的<b class='flag-5'>過程</b>

    linux 查看網(wǎng)卡狀態(tài)是否開啟

    如何查看 Linux 網(wǎng)卡狀態(tài)是否開啟 在 Linux 系統(tǒng)中,我們可以使用一些命令查看網(wǎng)卡狀態(tài)是否開啟。本文將詳細(xì)介紹如何使用這些命令
    的頭像 發(fā)表于 11-17 10:31 ?2056次閱讀

    linux查看網(wǎng)卡是down還是up

    Linux系統(tǒng)上,可以通過多種方式查看網(wǎng)卡的狀態(tài)是否為down或up。下面將詳細(xì)介紹這些方法,并給出具體的步驟和示例。 ifconfig命令 ifconfig命令是Linux系統(tǒng)上
    的頭像 發(fā)表于 11-17 10:34 ?7216次閱讀

    python如何查看運(yùn)行過程

    常用的方法查看Python程序的運(yùn)行過程。 使用print語(yǔ)句輸出信息: 最簡(jiǎn)單的方法是在代碼中使用print語(yǔ)句輸出信息。我們可以在程序的關(guān)鍵位置插入一些print語(yǔ)句,以便在運(yùn)
    的頭像 發(fā)表于 11-22 11:13 ?1539次閱讀

    linux查看weblogic進(jìn)程

    Linux操作系統(tǒng)中,WebLogic是一種常用的Java應(yīng)用服務(wù)器,用于部署和管理企業(yè)級(jí)Java應(yīng)用程序。為了確保WebLogic服務(wù)器正常運(yùn)行,有時(shí)我們需要查看WebLogic進(jìn)程以了解其狀態(tài)
    的頭像 發(fā)表于 12-05 16:07 ?1501次閱讀

    linux怎么查看網(wǎng)卡的收光功率?

    linux怎么查看網(wǎng)卡的收光功率? 在Linux系統(tǒng)中,可以使用一些命令和工具查看網(wǎng)卡的收光功率。本文將介紹如何使用這些命令和工具
    的頭像 發(fā)表于 01-31 14:24 ?2634次閱讀