2013年7月22日 星期一

GRUB2 的除錯訊息

GRUB2 的除錯很麻煩,因為有些問題只會在特定硬體上發生,所以無法使用其它軟體模擬的方式進行,不過還好 GRUB2 本身就內建一個除錯訊息的環境變數就叫做 debug

在 Debian/Ubuntu 底下可以直接修改 /boot/grub/grub.cfg 在最前面加上 set debug=all 就可以在執行 GRUB2 時將所有的除錯訊息都列印在電腦螢幕上面,不過更好的方式是在 /etc/grub.d/ 底下建立一個 shell script 來 echo 出 set debug=all

只是這種作法只能使用在 GRUB2 去硬碟上面讀取 /boot/grub/grub.cfg 之後的除錯訊息,另外就是除錯訊息本身太多太雜,反而會有一種見林不見樹的感覺。

所以這個時候可以使用一些小技巧將 debug 訊息的分類 (category) 都找出來,然後去掉不想要的部份再使用在 debug 參數設定上面。

例如我們可以在 GRUB2 的原始碼裡面執行以下指令:

~/grub2-1.99$ grep grub_dprintf * -Irh | sed 's/[[:space:]]\+//g' | grep '^grub_dprintf("' | cut -d '"' -f 2 | sort -u | grep -v scripting | grep -v lexer | xargs echo | sed 's/ /,/g'
acpi,affs,ata,atkeyb,badram,bsd,btrfs,datetime,devalias,deviceiter,disk,drivemap,efi,efidisk,efiemu,elf,expand,fat,fb,fs,gettext,gpt,hostdisk,keystatus,linux,loader,memdisk,mmap,modules,multiboot_loader,ohci,partition,play,raid,reiserfs,reiserfs_blocktype,reiserfs_tree,relocator,scsi,uhci,usb,usb_keyboard,usbms,video,xnu,zfs

( 截取的方法也有很多可以參考此噗的討論 )

上面的指令將 scripting 跟 lexer 這兩個最囉唆的分類給去掉了,所以 GRUB2 的設定變成 set debug=acpi,affs,ata,atkeyb,badram,bsd,btrfs,datetime,devalias,deviceiter,disk,drivemap,efi,efidisk,efiemu,elf,expand,fat,fb,fs,gettext,gpt,hostdisk,keystatus,linux,loader,memdisk,mmap,modules,multiboot_loader,ohci,partition,play,raid,reiserfs,reiserfs_blocktype,reiserfs_tree,relocator,scsi,uhci,usb,usb_keyboard,usbms,video,xnu,zfs 就可以少掉很多訊息了。

另外就是去修改 GRUB2 原始碼加上自己的除錯訊息,像是:

grub_dprintf ("debug", "Your debug messages here\n");

然後重編 GRUB2 再安裝到系統上,再使用 set debug=debug 或是加到原本那一串長長的清單後面。

最後,linux 這個分類算是從 GRUB2 進入 Linux kernel 最重要的點,所以可以使用 set debug=linux 就可以看出系統是停在 GRUB2 裡面還是死在 Linux kernel 裡面。

還有最後的最後就是要將 /etc/default/grub 裡面的 GRUB_TERMINAL=console 打開,再執行 update-grub 才會有比較容易閱讀的除錯訊息,當然也許會有一些 Side Effect 的產生。

2019/12/19 補充:或是修改 grub-common 的 /etc/grub.d/40_custom 在最後加上 set debug=linux 再執行 sudo update-grub 就不用每次安裝更新 kernel 時,還要去編輯 /boot/grub/grub.cfg

沒有留言: