Linux在啟動過程中會出現一些故障,導致系統無法正常啟動,本文列舉了幾個應用單用戶模式、GRUB命令操作、Linux救援模式的典型故障修復案例幫助讀者了解此類問題的解決。
u-boot內核移植出現問題
## Booting kernel from Legacy Image at 30000000 。。。
Image Name: Linux-3.4.2
Created: 2014-10-15 3:14:05 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2486120 Bytes = 2.4 MiB
Load Address: 30108000
Entry Point: 30108000
Verifying Checksum 。。。 Bad Data CRC
ERROR: can‘t get kernel image!
原因:
分區設置不對,實際內核大小為2.4M,但是我的分區設為2M。
mtdparts=mtdparts=rookie_wei-nand:256k(bootloader),128k(params),2m(kernel),-(rootfs)
解決辦法;
辦法一:(不推薦,每次啟動都得設置)
set mtdparts “mtdparts=rookie_wei-nand:256k(bootloader),128k(params),4m(kernel),-(rootfs)”
辦法二:
在u-boot源碼是設置,使內核分區為4m
一、單用戶模式
Linux提供了單用戶模式(類似Windows安全模式),可以在最小環境中進行系統維護。在單用戶模式(運行級別1)中,Linux引導進入根shell,網絡被禁用,只有少數進程運行。單用戶模式可以用來修改文件系統損壞、還原配置文件、移動用戶數據等。
以下列舉了幾個單用戶模式修復系統故障的典型案例:
案例:硬盤扇區錯亂
在啟動過程中最容易遇到的問題就是硬盤可能有壞道或扇區錯亂(數據損壞)的情況,這種情況多由于異常斷電、不正常關機導致。
此種問題發生,在系統啟動的時候,屏幕會顯示:
Press root password or ctrl+D:
此時輸入root密碼系統自動進入單用戶模式,輸入“fsck -y /dev/hda6”(fsck為文件系統檢測修復命令,“-y”設定檢測到錯誤自動修復,/dev/hda6為發生錯誤的硬盤分區,請依據具體情況更改此參數),系統修復完成后,用命令“reboot”重新啟動即可。
二、GRUB引導故障排除
有時Linux啟動后會直接進入GRUB命令行界面(只有“grub》”提示符),此時很多用戶就選擇了重新安裝GRUB 甚至重新安裝系統。其實一般而言此故障的原因最常見的有兩個:一是GRUB配置文件中選項設置錯誤;二是GRUB配置文件丟失(還有少數原因,如內核文件或鏡像文件損壞、丟失,/boot目錄誤刪除等),如果是第一種情況,可以首先通過GRUB命令引導系統后修復;若是第二種情況,則要使用Linux救援模式修復了(本文后續有描述)。
首先,我們需要了解GRUB啟動系統的引導過程,grub.conf文件中主要的配置選項如下(注意,GRUB配置文件為/boot/grub/grub.conf,/etc/grub.conf只是此文件的軟鏈接):
title Fedora Core (2.6.18-1.2798.fc6)
root (hd0,0)
kernel /boot/vmlinuz-2.6.18-1.2798.fc6 ro root=LABEL=/ rhgb quiet
initrd /boot/initrd-2.6.18-1.2798.fc6.img
其中“title”段指定了GRUB引導的系統;“root”段指定了/boot分區所在的位置;“kernel”段指定了內核文件所在位置,內核加載時權限屬性為只讀(“ro”)以及指定根分區所在位置(root=LABEL=/);initrd指定了鏡像文件所在位置。所以GRUB在引導時順序為首先加載/boot分區,然后依次載入內核與鏡像文件。
案例:“title Fedora Core (2.6.18-1.2798.fc6)”段被誤刪除
此時,系統啟動后會自動進入“GRUB》”命令行,為排除故障我們可以依次做如下操作:
1、查找/boot/grub/grub.conf文件所在分區
GRUB》 find /boot/grub/grub.conf
(hd0,0)
2、查看grub.conf文件錯誤
GRUB》cat (hd0,0)/boot/grub/grub.conf
建議系統安裝設置好后,要將grub.conf文件備份,如果有備份文件如grub.conf.bak,則此時可以查看備份文件,與當前文件比較,發現錯誤:
GRUB》cat (hd0,0)/boot/grub/grub.conf.bak
3、確認錯誤后,先通過命令行方式完成GRUB引導,進入系統后再行修復grub.conf文件錯誤:
1)指定/boot分區
root (hd0,0)
2)指定內核加載
kernel /boot/vmlinuz-2.6.18-1.2798.fc6 ro root=LABEL=/ rhgb quiet
3)指定鏡像文件所在位置
initrd /boot/initrd-2.6.18-1.2798.fc6.img
提示:GRUB支持tab鍵命令補全功能
4、從/boot分區啟動
boot (hd0,0)
命令行模式可以在GRUB菜單模式中通過按“c”鍵調用,也可以用于測試新編譯的內核(設置kernel、initrd引導新內核及鏡像文件)。增加對GRUB引導以及Linux系統引導知識的了解將對此類故障排除大有幫助。
三、Linux救援模式應用
當系統連單用戶模式都無法進入時或出現GRUB命令行也不能解決的引導問題,我們就需要使用Linux救援模式來進行故障排除了。步驟如下:
1、將Linux安裝光盤(如果使用CD光盤,則放入第一張引導光盤)放入光驅,設置固件 CMOS/BIOS為光盤引導,當Linux安裝畫面出現后,在“boot:”提示符后輸入“linux rescue”回車進入救援模式。(想了解救援模式詳細信息,還可以按F5鍵查看)
2、系統會檢測硬件,引導光盤上的Linux環境,依次提示你選擇救援模式下使用 的語言(建議選擇默認的英文即可,根據筆者測試,部分Linux系統選擇中文會出現亂碼);鍵盤設置用默認的“us”就好;網絡設置可以根據需要,大部分 故障修復不需要網絡連接,可不進行此項設置,選擇“No”。
3、接下來系統將試圖查找根分區,出現以下提示:
默認在救援模式,硬盤的根分區將掛載到光盤Linux環境的/mnt /sysimage目錄下,默認選項“continue”表示掛載權限為讀寫;“Read-only”為只讀,如果出現檢測失敗可以選擇“skip”跳 過。此處,因為要對系統進行修復,所以需要有讀寫權限,一般選擇默認選項“continue”。
進入下一步后,系統提示執行“chroot /mnt/sysimage”命令,可以將根目錄掛載到我們硬盤系統的根目錄中去。
案例:雙系統啟動修復
當我們安裝雙系統環境,先安裝Linux再安裝Windows;或者已經安裝好雙系統環境的Windows 損壞,在重新安裝Windows后,保存GRUB的MBR(Master Boot Record,主引導記錄)會被Windows系統的自舉程序NTLDR所覆蓋,造成Linux系統無法引導。
1、如果要恢復雙系統引導,首先用上述方法進入救援模式,執行chroot命令如下:
sh-3.1# chroot /mnt/sysimage
2、將根目錄切換到硬盤系統的根目錄中,然后執行grub-install命令重新安裝GRUB:
sh-3.1#grub-install /dev/hda
“/dev/hda”為硬盤名稱,如使用SCSI硬盤或Linux安裝在第二塊IDE硬盤,此項設置要做相應調整。
3、然后依次執行exit命令,退出chroot模式及救援模式(執行兩次exit命令):
sh-3.1# exit
sh-3.1# exit
系統重啟后,將恢復GRUB引導的雙系統啟動。
uboot無法啟動linux內核
1、u-boot中的命令行參數中console設定有問題,對2.6的內核應該使用ttySAC0,而不是ttyS0。更改為“console=ttySAC0”就可以解決問題。
2、u-boot中FCLK與kernel時鐘頻率不一致。kernel的FCLK為200MHz,但是uboot的默認值是202.8MHz。(vivi默認的也是200MHz,所以vivi不會出現這個問題。)這樣修改uboot的時鐘頻率設定就可以解決問題。
但是這兩個方案并不適合我這種情況。經過分析和讀bootm的源代碼,現在提出兩點額外考慮的地方:
1、如果你在配置文件中不定義tag list的成員,那么默認情況下bootm是不會傳遞命令行參數的。也就是說,如果你uboot環境變量中設定了正確的bootargs,但是配置文件中沒有設置,這時就會出現問題。為了使用上的方便,你至少應該在頭文件中定義:
/* tag list choosing */
#define CONFIG_CMDLINE_TAG
//#define CONFIG_SETUP_MEMORY_TAGS
這樣就可以保證你在命令行狀態下修改環境變量bootargs后,可以傳遞進內核。同時也就避免了重新編譯uboot。
2、我在使用中發現,如果在bootargs中沒有指定mem的大小,那么CONFIG_SETUP_MEMORY_TAGS也是需要設定的。我就是因為bootargs沒有設定mem,所以導致出現上述的情況。現在我的bootargs為:
bootargs=noinitrd root=/dev/mtdblock3 console=ttySAC0,115200 mem=64M
在這種情況下,使用go和bootm都可以正常引導內核。
綜上可知,在tag list的設定上,一定要考慮CONFIG_CMDLINE_TAG和內存兩個部分,否則的話,可能出現上述無法引導內核的問題。
評論
查看更多