全攻略:從Loader/Maskrom模式到串口調(diào)試與OTA部署)
1. 項(xiàng)目緣起一次看似簡(jiǎn)單的固件升級(jí)最近在折騰一塊基于瑞芯微RV1126芯片的開(kāi)發(fā)板核心任務(wù)是給它升級(jí)固件。這聽(tīng)起來(lái)是個(gè)常規(guī)操作對(duì)吧無(wú)非就是找個(gè)燒錄工具選好鏡像點(diǎn)一下“升級(jí)”按鈕。但實(shí)際情況是從準(zhǔn)備鏡像、選擇升級(jí)模式到處理升級(jí)過(guò)程中的各種“幺蛾子”每一步都可能藏著坑。RV1126作為一款面向視覺(jué)AI應(yīng)用的SoC其固件升級(jí)流程相比一些簡(jiǎn)單的MCU要復(fù)雜得多它涉及到Bootloader、分區(qū)表、內(nèi)核、文件系統(tǒng)等多個(gè)層面的協(xié)同工作。我這次的目標(biāo)不僅僅是把新固件刷進(jìn)去更是要徹底搞清楚整個(gè)升級(jí)鏈路的來(lái)龍去脈以及當(dāng)升級(jí)失敗時(shí)如何通過(guò)有限的調(diào)試手段比如串口快速定位問(wèn)題。如果你也在玩RV1126、RK3568或者其他Rockchip平臺(tái)的設(shè)備并且對(duì)“燒寫鏡像”、“OTA升級(jí)”、“串口調(diào)試”這些關(guān)鍵詞感到既熟悉又頭疼那么我踩過(guò)的這些坑和總結(jié)的經(jīng)驗(yàn)或許能幫你省下不少折騰的時(shí)間。2. 升級(jí)前的“戰(zhàn)備”工作工具與環(huán)境梳理在動(dòng)手升級(jí)之前把工具和環(huán)境理順了能避免至少一半的莫名其妙的問(wèn)題。很多人一上來(lái)就急著連板子、開(kāi)軟件結(jié)果卡在第一步。2.1 核心工具三件套燒寫、調(diào)試與鏡像對(duì)于Rockchip平臺(tái)尤其是RV1126下面這三個(gè)工具是你的必備武器RKDevTool / Upgrade Tool這是瑞芯微官方的燒錄工具。不同芯片型號(hào)、不同版本的工具可能存在兼容性問(wèn)題。一個(gè)常見(jiàn)的坑是你從某個(gè)論壇下載的“通用版”工具可能根本不識(shí)別你的RV1126板子。我的經(jīng)驗(yàn)是優(yōu)先從板卡供應(yīng)商或方案商那里獲取配套的工具。如果找不到可以去Rockchip的官方Wiki或開(kāi)發(fā)者社區(qū)尋找對(duì)應(yīng)芯片型號(hào)的專用版本。工具界面通常有“Loader”和“Maskrom”兩種燒錄模式這個(gè)我們后面會(huì)詳細(xì)講。串口調(diào)試助手這是你的“眼睛”和“嘴巴”。在升級(jí)過(guò)程中尤其是當(dāng)系統(tǒng)無(wú)法正常啟動(dòng)時(shí)串口是獲取Bootloader和內(nèi)核日志的唯一通道。sscom、xcom、putty、minicom都可以。關(guān)鍵參數(shù)就三個(gè)波特率RV1126通常為1500000、數(shù)據(jù)位8、停止位1、無(wú)校驗(yàn)。這里有個(gè)細(xì)節(jié)一定要確保串口線的驅(qū)動(dòng)正確安裝并且在設(shè)備管理器中確認(rèn)了正確的COM口號(hào)。我遇到過(guò)無(wú)數(shù)次因?yàn)镃OM口選錯(cuò)導(dǎo)致看著一片空白的終端發(fā)呆的情況。固件鏡像文件通常是一個(gè).img文件或者由多個(gè)分區(qū)鏡像打包而成的update.img。你需要確認(rèn)這個(gè)鏡像是否與你的硬件版本如DDR型號(hào)、PMIC配置完全匹配。用不匹配的鏡像輕則功能異常重則直接“變磚”。在拿到鏡像后可以嘗試用7zip或binwalk工具簡(jiǎn)單查看一下內(nèi)部結(jié)構(gòu)確認(rèn)它包含boot.img、rootfs.img等關(guān)鍵分區(qū)。2.2 系統(tǒng)環(huán)境與驅(qū)動(dòng)確認(rèn)如果你的工作機(jī)是Windows那么DriverAssitant驅(qū)動(dòng)助手這個(gè)工具必須安裝。它包含了Rockchip芯片進(jìn)入升級(jí)模式Maskrom或Loader時(shí)所需的USB驅(qū)動(dòng)。安裝后最好在設(shè)備管理器中手動(dòng)檢查一下當(dāng)板子進(jìn)入升級(jí)模式并連接USB后是否會(huì)正確識(shí)別為“Rockchip USB Device”或類似的設(shè)備。如果是Linux環(huán)境進(jìn)行升級(jí)則需要配置udev規(guī)則讓普通用戶也能訪問(wèn)USB設(shè)備并且使用rkdeveloptool等命令行工具進(jìn)行操作。這部分的坑在于權(quán)限和工具鏈的版本匹配。注意在連接板子之前先打開(kāi)串口調(diào)試助手并設(shè)置好參數(shù)然后再給板子上電。這樣你才能捕獲到最完整的啟動(dòng)日志從Bootloader的第一行輸出開(kāi)始看起。這是判斷板子狀態(tài)的第一手資料。3. 深入RV1126的升級(jí)模式Loader與Maskrom的區(qū)別這是理解Rockchip平臺(tái)升級(jí)的關(guān)鍵。很多升級(jí)失敗根源就在于模式?jīng)]選對(duì)。3.1 Loader模式常態(tài)化的升級(jí)入口當(dāng)RV1126板子里的Bootloader通常是U-Boot正常運(yùn)行時(shí)并且這個(gè)U-Boot支持rockusb或rkusb命令時(shí)就可以進(jìn)入Loader模式。如何進(jìn)入通常有兩種方式在串口終端中在U-Boot的倒計(jì)時(shí)階段按下任意鍵打斷自動(dòng)啟動(dòng)然后輸入命令rkusb或rockusb。板子上可能有專門的“升級(jí)鍵”Recovery鍵在板上電瞬間按住此鍵U-Boot會(huì)檢測(cè)到并自動(dòng)進(jìn)入Loader模式。表現(xiàn)進(jìn)入Loader模式后串口可能會(huì)輸出Enter rockusb mode之類的提示同時(shí)Windows電腦會(huì)識(shí)別到一個(gè)新的USB設(shè)備。此時(shí)在RKDevTool中設(shè)備列表會(huì)顯示為一個(gè)“發(fā)現(xiàn)一個(gè)LOADER設(shè)備”。特點(diǎn)Loader模式依賴于板載Bootloader的正常工作。如果Bootloader本身?yè)p壞了這個(gè)模式就進(jìn)不去了。3.2 Maskrom模式救磚的終極手段Maskrom是芯片內(nèi)部固化的一段只讀啟動(dòng)代碼。當(dāng)系統(tǒng)檢測(cè)不到任何有效的可啟動(dòng)設(shè)備如eMMC、SPI Flash為空或損壞時(shí)或者通過(guò)特殊引腳強(qiáng)制觸發(fā)時(shí)芯片會(huì)自動(dòng) fallback 到 Maskrom 模式。如何進(jìn)入這是重點(diǎn)也是硬件操作。短路Flash找到板載eMMC或SPI Flash芯片的數(shù)據(jù)引腳通常是D0或CLK在上電瞬間將其與地GND短接。這模擬了Flash無(wú)法識(shí)別的狀態(tài)迫使芯片進(jìn)入Maskrom。這是最通用的方法但需要一定的硬件動(dòng)手能力并要查詢你板子的原理圖。專用測(cè)試點(diǎn)有些開(kāi)發(fā)板會(huì)設(shè)計(jì)一個(gè)標(biāo)記為“Maskrom”或“M”的測(cè)試點(diǎn)將其在上電瞬間與地短接即可。按鍵組合極少數(shù)板子可能有通過(guò)按住多個(gè)按鍵上電的方式觸發(fā)。表現(xiàn)進(jìn)入Maskrom模式后芯片會(huì)等待主機(jī)通過(guò)USB發(fā)送下載指令。在RKDevTool中設(shè)備會(huì)顯示為“發(fā)現(xiàn)一個(gè)MASKROM設(shè)備”。特點(diǎn)這是最底層的模式不依賴任何外部存儲(chǔ)器的代碼。只要芯片本身沒(méi)壞就能通過(guò)Maskrom模式重新燒寫B(tài)ootloader從而實(shí)現(xiàn)“救磚”。3.3 模式選擇與實(shí)戰(zhàn)策略理解了這兩種模式你的升級(jí)策略就清晰了常規(guī)升級(jí)板子能正常啟動(dòng)到U-Boot或系統(tǒng) - 優(yōu)先嘗試進(jìn)入Loader模式進(jìn)行升級(jí)。這種方式最安全、最方便。救磚/首次燒錄板子無(wú)法啟動(dòng)、Flash為空、或升級(jí)中途失敗導(dǎo)致Bootloader損壞 - 必須使用Maskrom模式。我遇到的一個(gè)典型場(chǎng)景是在Loader模式下升級(jí)中途因?yàn)閁SB線松動(dòng)或電源波動(dòng)導(dǎo)致升級(jí)中斷結(jié)果Bootloader被寫壞了一半。此時(shí)板子既無(wú)法正常啟動(dòng)也無(wú)法再次進(jìn)入Loader模式。唯一的辦法就是拆開(kāi)機(jī)殼找到Flash引腳用鑷子短接進(jìn)入Maskrom模式重新燒寫完整的固件。4. 固件鏡像的構(gòu)成與燒寫流程拆解知道怎么連接板子了我們?cè)賮?lái)看看要燒寫的“固件”到底是什么。一個(gè)完整的RV1126升級(jí)鏡像通常不是單一文件而是一個(gè)遵循特定格式的包。4.1 標(biāo)準(zhǔn)update.img的解析使用RKDevTool燒寫時(shí)我們常選擇一個(gè)update.img文件。這個(gè)文件其實(shí)是一個(gè)容器里面打包了多個(gè)分區(qū)鏡像和一份分區(qū)表信息。你可以使用Rockchip提供的afptool和img_unpack工具對(duì)其進(jìn)行解包# 假設(shè)在Linux環(huán)境下 ./afptool -unpack update.img update/ ./img_unpack update.img rockimg/解包后你可能會(huì)看到如下關(guān)鍵組件parameter.txt分區(qū)表文件。這是升級(jí)的“地圖”定義了eMMC上各個(gè)分區(qū)如bootrootfsuserdata的起始位置、大小和名稱。升級(jí)前務(wù)必確認(rèn)此分區(qū)表與板子原有分區(qū)布局兼容否則可能導(dǎo)致數(shù)據(jù)錯(cuò)亂。boot.img包含內(nèi)核kernel.img和設(shè)備樹(shù)resource.img或dtb等。負(fù)責(zé)啟動(dòng)Linux系統(tǒng)。rootfs.img根文件系統(tǒng)包含了操作系統(tǒng)的基礎(chǔ)命令、庫(kù)和你的應(yīng)用程序。misc.img用于OTA升級(jí)時(shí)傳遞狀態(tài)信息的分區(qū)。userdata.img用戶數(shù)據(jù)分區(qū)。4.2 RKDevTool燒寫步驟詳解在RKDevTool中燒寫流程是這樣的工具讀取update.img中的parameter.txt。根據(jù)分區(qū)表將boot.img、rootfs.img等逐個(gè)通過(guò)USB傳輸?shù)桨宥说腂ootloaderLoader模式或Maskrom。Bootloader/Maskrom程序?qū)⑦@些鏡像寫入eMMC對(duì)應(yīng)的物理地址。這里有一個(gè)至關(guān)重要的選項(xiàng)“擦除Flash”和“擦除IDB”。擦除Flash會(huì)清空整個(gè)存儲(chǔ)設(shè)備eMMC的所有數(shù)據(jù)。相當(dāng)于格式化整個(gè)硬盤。擦除IDBIDB是存儲(chǔ)在Flash前幾個(gè)塊的信息塊包含了Bootloader和分區(qū)表信息。擦除IDB會(huì)破壞Bootloader和分區(qū)表。實(shí)操心得首次燒錄或徹底重刷可以勾選“擦除Flash”確保一個(gè)干凈的狀態(tài)。常規(guī)升級(jí)千萬(wàn)不要勾選“擦除Flash”特別是你的userdata分區(qū)里有重要數(shù)據(jù)時(shí)。標(biāo)準(zhǔn)的升級(jí)流程只會(huì)覆蓋boot、rootfs等系統(tǒng)分區(qū)保留userdata分區(qū)。RKDevTool在加載update.img后通常默認(rèn)只勾選需要更新的分區(qū)如bootrootfs這是安全的。“擦除IDB”要慎用只有在分區(qū)表?yè)p壞或需要徹底更換Bootloader類型如從舊版U-Boot換成新版時(shí)才使用。誤操作會(huì)導(dǎo)致板子無(wú)法啟動(dòng)必須進(jìn)Maskrom。4.3 命令行燒寫更底層的控制在Linux主機(jī)上你可以使用rkdeveloptool進(jìn)行更靈活的燒寫。這對(duì)于自動(dòng)化腳本或深入了解流程非常有幫助。# 1. 查看連接的設(shè)備 rkdeveloptool ld # 輸出示例DevNo1 Vid0x2207,Pid0x350b,LocationID106 Maskrom # 2. 下載并運(yùn)行Loader用于Maskrom模式初始化 rkdeveloptool db rkbin/RK1126_Loader.bin # 3. 燒寫整個(gè)update.img rkdeveloptool wl 0 update.img # 4. 或者分別燒寫各個(gè)分區(qū)更靈活 rkdeveloptool ppt # 查看分區(qū)信息 rkdeveloptool wl boot boot.img rkdeveloptool wl rootfs rootfs.img命令行工具讓你對(duì)每個(gè)步驟都有清晰的控制當(dāng)圖形化工具出錯(cuò)時(shí)命令行輸出的錯(cuò)誤信息往往更直接。5. 串口調(diào)試當(dāng)升級(jí)出錯(cuò)時(shí)你的診斷利器升級(jí)過(guò)程很少一帆風(fēng)順。當(dāng)RKDevTool卡住、報(bào)錯(cuò)或者燒寫成功后板子依然無(wú)法啟動(dòng)時(shí)串口調(diào)試終端就是你的救命稻草。你需要學(xué)會(huì)解讀這些日志。5.1 Bootloader啟動(dòng)日志分析上電后串口最先輸出的是BootloaderU-Boot的信息。健康的日志鏈?zhǔn)沁@樣的U-Boot 2017.09 (Mar 01 2023 - 10:00:00 0800) Model: Rockchip RV1126 Evaluation Board DRAM: 1 GiB MMC: dwmmcffc50000: 1, dwmmcffc60000: 0 In: serial Out: serial Err: serial ... Hit any key to stop autoboot: 3如果在這里就卡住了比如DRAM初始化失敗那可能是DDR配置不對(duì)鏡像與板子硬件不匹配或者板子硬件有問(wèn)題。5.2 內(nèi)核啟動(dòng)日志與常見(jiàn)故障Bootloader之后會(huì)將控制權(quán)交給內(nèi)核。內(nèi)核啟動(dòng)日志非常詳細(xì)能暴露大部分問(wèn)題[ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 4.19.111 (buildserver) ... [ 0.000000] Machine model: Rockchip RV1126 Evaluation Board ... [ 1.234567] dwmmc_ffc50000: voltage-ranges unspecified [ 1.234568] dwmmc_ffc50000: 1, dwmmc_ffc60000: 0 [ 1.567890] mmc0: new high speed SDHC card at address aaaa [ 1.567891] mmcblk0: mmc0:aaaa SL32G 29.7 GiB ... [ 2.345678] VFS: Mounted root (ext4 filesystem) on device 179:2. [ 2.345679] devtmpfs: mounted [ 2.456789] Freeing unused kernel memory: 1024K [ 2.456790] Run /sbin/init as init process常見(jiàn)錯(cuò)誤及排查方向卡在Starting kernel ...之后沒(méi)有任何輸出最可能的原因設(shè)備樹(shù)dtb錯(cuò)誤。Bootloader加載了錯(cuò)誤的內(nèi)核或設(shè)備樹(shù)文件導(dǎo)致內(nèi)核無(wú)法識(shí)別硬件而崩潰。解決方法檢查boot.img中的設(shè)備樹(shù)是否與你的板型完全匹配。回退到已知正常的舊版本鏡像進(jìn)行對(duì)比。內(nèi)核恐慌Kernel Panic[ 3.000000] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)原因內(nèi)核找不到根文件系統(tǒng)。可能是rootfs鏡像損壞、分區(qū)表錯(cuò)誤導(dǎo)致根文件系統(tǒng)分區(qū)位置不對(duì)、或者內(nèi)核缺少對(duì)應(yīng)的文件系統(tǒng)驅(qū)動(dòng)如ext4。排查首先確認(rèn)parameter.txt中rootfs分區(qū)的名稱和編號(hào)是否正確。在U-Boot中使用mmc part或part list mmc 0命令查看實(shí)際分區(qū)表。確認(rèn)內(nèi)核配置包含了對(duì)應(yīng)的文件系統(tǒng)支持。MMC/SD卡初始化失敗[ 1.500000] dwmmc_ffc50000: error -110 whilst initialising MMC card原因存儲(chǔ)設(shè)備初始化失敗。可能是eMMC芯片虛焊、損壞或者內(nèi)核驅(qū)動(dòng)中的時(shí)序配置如dwmmc節(jié)點(diǎn)的clock-frequency與硬件不匹配。排查檢查硬件連接。對(duì)比正常板子的內(nèi)核設(shè)備樹(shù)中MMC控制器的配置。5.3 文件系統(tǒng)掛載失敗與Init進(jìn)程問(wèn)題即使內(nèi)核啟動(dòng)成功也可能在掛載根文件系統(tǒng)或啟動(dòng)第一個(gè)用戶進(jìn)程init時(shí)失敗。[ 2.500000] List of all partitions: [ 2.500001] ... (分區(qū)列表正常) ... [ 2.500002] VFS: Cannot open root device mmcblk0p5 or unknown-block(0,0): error -6 [ 2.500003] Please append a correct root boot option; here are the available partitions: ...這明確指出了根設(shè)備mmcblk0p5無(wú)法打開(kāi)。你需要檢查U-Boot的bootargs環(huán)境變量中root參數(shù)指定的設(shè)備是否正確例如root/dev/mmcblk0p5。對(duì)應(yīng)的分區(qū)這里是第5分區(qū)是否存在且包含有效的文件系統(tǒng)鏡像。如果掛載成功但最后卡在Run /sbin/init as init process然后沒(méi)有下文通常是根文件系統(tǒng)里的/sbin/init鏈接通常指向systemd或busybox損壞或者文件系統(tǒng)本身不完整。這通常意味著rootfs.img在制作或燒寫過(guò)程中出了問(wèn)題。6. OTA升級(jí)遠(yuǎn)程部署的關(guān)鍵機(jī)制對(duì)于量產(chǎn)設(shè)備我們不可能每次都拆機(jī)短接用USB升級(jí)。OTAOver-The-Air升級(jí)是必須的。RV1126的OTA升級(jí)核心是recovery系統(tǒng)。6.1 Recovery系統(tǒng)與A/B分區(qū)一種常見(jiàn)的OTA方案是使用recovery分區(qū)。當(dāng)系統(tǒng)需要升級(jí)時(shí)會(huì)重啟進(jìn)入recovery分區(qū)一個(gè)精簡(jiǎn)的Linux系統(tǒng)由recovery來(lái)完成對(duì)主系統(tǒng)分區(qū)boot,system,vendor等的更新。 Rockchip也支持A/B分區(qū)無(wú)縫更新方案即有兩套完整的系統(tǒng)分區(qū)A槽和B槽當(dāng)前運(yùn)行A槽后臺(tái)更新B槽下次啟動(dòng)時(shí)從B槽啟動(dòng)。這需要Bootloader如U-Boot和系統(tǒng)Android Things或某些Linux發(fā)行版的支持。6.2 制作OTA升級(jí)包OTA升級(jí)包ota_update.zip或update.zip不同于完整的update.img。它通常是一個(gè)差分包或全量包只包含需要更新的分區(qū)鏡像并附帶一個(gè)升級(jí)腳本updater-script用于Android兼容的recovery或自定義的更新邏輯。 制作OTA包通常需要使用SDK中的編譯腳本例如build.sh或mkupdate.sh它會(huì)根據(jù)版本差異生成對(duì)應(yīng)的包。6.3 OTA升級(jí)流程與調(diào)試下載設(shè)備從服務(wù)器下載OTA升級(jí)包到緩存分區(qū)如cache或數(shù)據(jù)分區(qū)。驗(yàn)證驗(yàn)證包的簽名和完整性防止被篡改。進(jìn)入Recovery系統(tǒng)重啟Bootloader根據(jù)升級(jí)標(biāo)志常存儲(chǔ)在misc分區(qū)決定啟動(dòng)到recovery系統(tǒng)。安裝更新recovery系統(tǒng)解壓升級(jí)包根據(jù)腳本擦寫對(duì)應(yīng)的系統(tǒng)分區(qū)。重啟更新完成后清除升級(jí)標(biāo)志重啟進(jìn)入主系統(tǒng)。調(diào)試OTA的難點(diǎn)在于更新過(guò)程發(fā)生在recovery里而recovery的串口日志可能和主系統(tǒng)不同或者根本沒(méi)有輸出。你需要確保recovery鏡像本身包含了串口驅(qū)動(dòng)和輸出功能。在recovery的初始化腳本如init.rc中確保console被正確設(shè)置到串口。仔細(xì)檢查升級(jí)腳本的邏輯確保分區(qū)掛載、文件拷貝、權(quán)限設(shè)置的每一步都正確。我遇到過(guò)一個(gè)典型的OTA失敗案例升級(jí)包制作時(shí)文件路徑使用了絕對(duì)路徑/system/bin/app但recovery環(huán)境下/system可能并未掛載導(dǎo)致文件拷貝失敗。正確的做法是在腳本中先掛載system分區(qū)到某個(gè)臨時(shí)目錄如/tmp/system再進(jìn)行操作。7. 進(jìn)階排查當(dāng)基礎(chǔ)手段都失效時(shí)如果串口沒(méi)有任何輸出或者輸出亂碼問(wèn)題就更底層了。7.1 串口無(wú)輸出排查硬件連接TX/RX線是否接反串口板如USB轉(zhuǎn)TTL的電壓是否是3.3VRV1126通常是3.3V電平地線是否接好波特率嘗試最常見(jiàn)的1500000也試試115200。有些Bootloader早期階段可能用低速波特率。Bootloader損壞如果完全無(wú)輸出且確認(rèn)串口硬件和設(shè)置無(wú)誤那很可能是Bootloader代碼區(qū)域IDB完全損壞。此時(shí)必須嘗試Maskrom模式。7.2 使用示波器或邏輯分析儀對(duì)于更棘手的啟動(dòng)問(wèn)題比如DDR無(wú)法初始化軟件日志無(wú)能為力。這時(shí)需要硬件工具。測(cè)量時(shí)鐘和電源用示波器檢查核心電壓如VDD_LOGIC、DDR電壓是否穩(wěn)定且在正確范圍內(nèi)。檢查主晶振是否起振。抓取eMMC引腳波形在啟動(dòng)瞬間用邏輯分析儀抓取eMMC的CLK和CMD線波形看Bootloader是否在嘗試讀取Flash。如果沒(méi)有讀寫活動(dòng)說(shuō)明芯片可能沒(méi)跑起來(lái)或者BootROMMaskrom在更早階段就失敗了。7.3 利用TrustZone調(diào)試輸出如果有RV1126的Arm Cortex-A7核心通常運(yùn)行在非安全世界Linux而安全世界TrustZone可能運(yùn)行著OP-TEE等安全OS。有些調(diào)試信息可能會(huì)輸出到安全世界的UART上而這個(gè)UART可能和Linux使用的不是同一個(gè)物理串口。如果你的板子有多個(gè)UART接口可以嘗試連接其他UART引腳看看是否有不同的輸出。這需要查閱芯片的TRM技術(shù)參考手冊(cè)和板子的原理圖。整個(gè)RV1126的升級(jí)調(diào)試是一個(gè)從軟件到硬件、從上層應(yīng)用到底層硬件的全鏈路認(rèn)知過(guò)程。最深刻的體會(huì)就是日志是你的第一線索理解流程是你分析線索的地圖而硬件操作如Maskrom是你最后的保障。每次升級(jí)前做好備份確認(rèn)鏡像匹配理解你每一步操作的意義這樣才能在遇到問(wèn)題時(shí)從容不迫一步步縮小范圍最終找到那個(gè)搗鬼的“小妖精”。