Grub“不兼容的許可證”錯誤
前幾天,當它的鍵盤開始起作用時,我正在使用一台筆記型電腦作為普通台式機使用。鍵盤右側的大多數鍵完全停止工作,並且
Ctrl``u
出現了不應該出現的字元組合等組合鍵。退格鍵表現出最奇怪的行為;它以某種方式能夠導致 shell 提示符中的刪除字元。我無法乾淨地重新啟動電腦,所以我進行了硬關機。當我再次打開電腦時,我收到了來自 Grub 的這條消息:
GRUB loading. Welcome to GRUB! incompatible license Aborted. Press any key to exit.
我按下了任意鍵,Grub 回復了
Operating System Not Found.
按另一個鍵會使第一條消息再次出現。之後按另一個鍵會導致出現第二條消息……等等。
如果我讓筆記型電腦開機幾分鐘,它的風扇會顯著加速,就好像筆記型電腦正在執行 CPU 密集型程序一樣。
我從筆記型電腦中取出硬碟,將其安裝在伺服器上,然後環顧四周。我沒有看到任何奇怪的東西
/boot
。筆記型電腦正在執行 Arch Linux。該驅動器使用 GPT 進行分區。筆記型電腦可以與另一台機器的硬碟一起正常工作。並且其他機器不能與筆記型電腦的硬碟一起工作。
我不確定鍵盤問題是否與 Grub 問題直接相關。
什麼可能導致我遇到的問題?或者,我應該怎麼做才能找出或縮小潛在原因的範圍?
以防萬一它是相關的,這裡*(已刪除)*是一個 tarball,
/boot
這裡/etc/grub.d
是我的 Grub 配置:# # DO NOT EDIT THIS FILE # # It is automatically generated by grub-mkconfig using templates # from /etc/grub.d and settings from /etc/default/grub # ### BEGIN /etc/grub.d/00_header ### insmod part_gpt insmod part_msdos if [ -s $prefix/grubenv ]; then load_env fi set default="0" if [ x"${feature_menuentry_id}" = xy ]; then menuentry_id_option="--id" else menuentry_id_option="" fi export menuentry_id_option if [ "${prev_saved_entry}" ]; then set saved_entry="${prev_saved_entry}" save_env saved_entry set prev_saved_entry= save_env prev_saved_entry set boot_once=true fi function savedefault { if [ -z "${boot_once}" ]; then saved_entry="${chosen}" save_env saved_entry fi } function load_video { if [ x$feature_all_video_module = xy ]; then insmod all_video else insmod efi_gop insmod efi_uga insmod ieee1275_fb insmod vbe insmod vga insmod video_bochs insmod video_cirrus fi } if [ x$feature_default_font_path = xy ] ; then font=unicode else insmod part_gpt insmod ext2 set root='hd0,gpt1' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt1 --hint-efi=hd0,gpt1 --hint-baremetal=ahci0,gpt1 d44f2a2f-c369-456b-81f1-efa13f9caae2 else search --no-floppy --fs-uuid --set=root d44f2a2f-c369-456b-81f1-efa13f9caae2 fi font="/usr/share/grub/unicode.pf2" fi if loadfont $font ; then set gfxmode=auto load_video insmod gfxterm set locale_dir=$prefix/locale set lang=en_US insmod gettext fi terminal_input console terminal_output gfxterm set timeout=5 ### END /etc/grub.d/00_header ### ### BEGIN /etc/grub.d/10_linux ### menuentry 'Arch GNU/Linux, with Linux PARA kernel' --class arch --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-PARA kernel-true-d44f2a2f-c369-456b-81f1-efa13f9caae2' { load_video set gfxpayload=keep insmod gzio insmod part_gpt insmod ext2 set root='hd1,gpt1' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=root --hint-bios=hd1,gpt1 --hint-efi=hd1,gpt1 --hint-baremetal=ahci1,gpt1 b4fbf4f8-303c-49bd-a52f-6049e1623a26 else search --no-floppy --fs-uuid --set=root b4fbf4f8-303c-49bd-a52f-6049e1623a26 fi echo 'Loading Linux PARA kernel ...' linux /boot/vmlinuz-linux-PARA root=UUID=d44f2a2f-c369-456b-81f1-efa13f9caae2 ro quiet echo 'Loading initial ramdisk ...' initrd /boot/initramfs-linux-PARA.img } menuentry 'Arch GNU/Linux, with Linux core repo kernel' --class arch --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-core repo kernel-true-d44f2a2f-c369-456b-81f1-efa13f9caae2' { load_video set gfxpayload=keep insmod gzio insmod part_gpt insmod ext2 set root='hd1,gpt1' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=root --hint-bios=hd1,gpt1 --hint-efi=hd1,gpt1 --hint-baremetal=ahci1,gpt1 b4fbf4f8-303c-49bd-a52f-6049e1623a26 else search --no-floppy --fs-uuid --set=root b4fbf4f8-303c-49bd-a52f-6049e1623a26 fi echo 'Loading Linux core repo kernel ...' linux /boot/vmlinuz-linux root=UUID=d44f2a2f-c369-456b-81f1-efa13f9caae2 ro quiet echo 'Loading initial ramdisk ...' initrd /boot/initramfs-linux.img } menuentry 'Arch GNU/Linux, with Linux core repo kernel (Fallback initramfs)' --class arch --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-core repo kernel-fallback-d44f2a2f-c369-456b-81f1-efa13f9caae2' { load_video set gfxpayload=keep insmod gzio insmod part_gpt insmod ext2 set root='hd1,gpt1' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=root --hint-bios=hd1,gpt1 --hint-efi=hd1,gpt1 --hint-baremetal=ahci1,gpt1 b4fbf4f8-303c-49bd-a52f-6049e1623a26 else search --no-floppy --fs-uuid --set=root b4fbf4f8-303c-49bd-a52f-6049e1623a26 fi echo 'Loading Linux core repo kernel ...' linux /boot/vmlinuz-linux root=UUID=d44f2a2f-c369-456b-81f1-efa13f9caae2 ro quiet echo 'Loading initial ramdisk ...' initrd /boot/initramfs-linux-fallback.img } ### END /etc/grub.d/10_linux ### ### BEGIN /etc/grub.d/20_linux_xen ### ### END /etc/grub.d/20_linux_xen ### ### BEGIN /etc/grub.d/20_memtest86+ ### menuentry "Memory test (memtest86+)" --class memtest86 --class gnu --class tool { insmod part_gpt insmod ext2 set root='hd1,gpt1' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=root --hint-bios=hd1,gpt1 --hint-efi=hd1,gpt1 --hint-baremetal=ahci1,gpt1 b4fbf4f8-303c-49bd-a52f-6049e1623a26 else search --no-floppy --fs-uuid --set=root b4fbf4f8-303c-49bd-a52f-6049e1623a26 fi linux16 ($root)/boot/memtest86+/memtest.bin } ### END /etc/grub.d/20_memtest86+ ### ### BEGIN /etc/grub.d/30_os-prober ### ### END /etc/grub.d/30_os-prober ### ### BEGIN /etc/grub.d/40_custom ### # This file provides an easy way to add custom menu entries. Simply type the # menu entries you want to add after this comment. Be careful not to change # the 'exec tail' line above. ### END /etc/grub.d/40_custom ### ### BEGIN /etc/grub.d/41_custom ### if [ -f ${config_directory}/custom.cfg ]; then source ${config_directory}/custom.cfg elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then source $prefix/custom.cfg; fi ### END /etc/grub.d/41_custom ###
更新
昨晚安裝 LILO 後,電腦至少啟動了一次。今天早上啟動電腦時,我遇到了核心恐慌:
Initramfs unpacking failed: junk in compressed archive Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,1) Pid: 1, comm: swapper/0 Not tainted 3.8.7-1-ARCH #1 Call Trace: ...
這是核心恐慌的圖片。
更新 2
我重新安裝了 LILO,並且在啟動時不再收到核心崩潰。
更新2:
忘了你貼了焦油球。太糟糕了。無論如何,
.mod
使用以下程式碼對您的文件進行了測試,並且:./grum_lic_test32 evan_teitelman/boot/grub/i386-pc/*.mod
這產生了以下錯誤:
... bufio.mod License: LICENSE=GPLv3+ OK cacheinfo.mod License: LICENSE=NONE_FOUND ERR cat.mod License: LICENSE=GPLv3+ OK chain.mod License: LICENSE=GPLv3+ OK ...
但該文件與 Archlinux 下載的文件相同,因此應該不是問題。換句話說,不是原因。
另外,現在首先,請注意您已經安裝了 LILO,並且猜測該案例已關閉。如果不是,總是有關於 GPT 和 BIOS + 其他問題的問題。你是第一次安裝嗎?可能是在第一次安裝時涉及一些調整,重新安裝 GRUB 沒有修復。
***更新1:***好的。固定的。應該適用於 32 位和 64 位
ELF
。當
GRUB
進入載入模組的階段時,它會檢查ELF
每個模組的文件中嵌入的許可證。如果發現無效,則忽略該模組 - 並列印該特定錯誤。可能是一個或多個模組損壞。如果它是一個必不可少的模組,那麼一切都會變糟。說例如
part_gpt.mod
或part_msdos.mod
。接受的許可證是
GPLv2+
和。GPLv3``GPLv3+
當然也可能是其他原因;但其中之一可能是損壞的模組文件。
模組似乎是有效
ELF
文件,因為它們在許可證測試之前已經過驗證。如:如果ELF
測試失敗,則不執行許可證測試。我需要檢查各種模組的另一個問題,提取了該程式碼的一部分並將其製成快速許可證測試器。您可以測試每個
*.mod
文件/boot/grub/*
以查看哪些文件已損壞。此程式碼不會驗證
ELF
或其他任何內容。僅嘗試找到許可證字元串並進行檢查。此外,它僅在 i386/32 位下進行測試。從中提取它的原始程式碼也適用於 x86-64 - 但這裡有很多被剝離和破解,所以我不確定結果。如果它在 64 位下不起作用,它很可能只列印License: LICENSE=NONE_FOUND
.(如上面編輯中所述,我現在已經測試了 32 位和 64 位英特爾。)
作為一個單獨的測試,然後將執行以下操作:
xxd file.mod | grep -C1 LIC
不是最漂亮的程式碼——但作為一種快速而骯髒的檢查。
(如;你可以試試。)
編譯指令例如:
gcc -o grub_lic_test32 source.c # 32-bit variant gcc -o grub_lic_test64 source.c -DELF64 # 64-bit variant
跑:
./grub_lic_test32 /path/to/mods/*.mod
列印每個文件和許可證,例如:
./grub_lic_test32 tar.mod gettext.mod pxe.mod tar.mod License: LICENSE=GPLv1+ BAD gettext.mod License: LICENSE=GPLv3+ OK pxe.mod License: LICENSE=GPLv3+ OK
程式碼:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <errno.h> #ifdef ELF64 struct ELF_hdr { unsigned char dummy0[16]; uint32_t dummy1[6]; uint64_t sh_off; uint16_t dummy2[5]; uint16_t sh_entsize; uint16_t sh_num; uint16_t sh_strndx; }; struct ELF_sect_hdr { uint32_t sh_name; uint32_t dummy0[5]; uint64_t sh_offset; }; #else struct ELF_hdr { unsigned char dummy0[16]; uint32_t dummy1[4]; uint32_t sh_off; uint16_t dummy2[5]; uint16_t sh_entsize; uint16_t sh_num; uint16_t sh_strndx; }; struct ELF_sect_hdr { uint32_t sh_name; uint32_t dummy[3]; uint32_t sh_offset; }; #endif enum { ERR_FILE_OPEN = 1, ERR_FILE_READ, ERR_MEM, ERR_BAD_LICENSE, ERR_ELF_SECT_CORE_BREACH }; int file_size(FILE *fh, size_t *fs) { size_t cp; cp = ftell(fh); fseek(fh, 0, SEEK_END); *fs = ftell(fh); fseek(fh, cp, SEEK_SET); return 0; } static const char *valid_licenses[] = { "LICENSE=GPLv2+", "LICENSE=GPLv3", "LICENSE=GPLv3+", NULL }; int grub_check_license(struct ELF_hdr *e) { struct ELF_sect_hdr *s; const char *txt; const char *lic; unsigned i, j = 0; s = (struct ELF_sect_hdr *) ((char *) e + e->sh_off + e->sh_strndx * e->sh_entsize); txt = (char *) e + s->sh_offset; s = (struct ELF_sect_hdr *) ((char *) e + e->sh_off); for (i = 0; i < e->sh_num; ++i) { if (strcmp (txt + s->sh_name, ".module_license") == 0) { lic = (char*) e + s->sh_offset; if (j) fprintf(stdout, "%25s", ""); fprintf(stdout, "License: %-25s ", lic); for (j = 0; valid_licenses[j]; ++j) { if (!strcmp (lic, valid_licenses[j])) { fprintf(stdout, "OK\n"); return 0; } } fprintf(stdout, "BAD\n"); } s = (struct ELF_sect_hdr *) ((char *) s + e->sh_entsize); } if (!j) fprintf(stdout, "License: %-25s ERR\n", "LICENSE=NONE_FOUND"); return ERR_BAD_LICENSE; } int grub_check_module(void *buf, size_t size, int verbose) { struct ELF_hdr *e = buf; /* Make sure that every section is within the core. */ if (e->sh_off + e->sh_entsize * e->sh_num > size) { fprintf(stderr, "ERR: Sections outside core\n"); if (verbose) fprintf(stderr, " %*s: %u bytes\n" #ifdef ELF64 " %*s %u < %llu\n" " %*s: %llu\n" #else " %*s %u < %u\n" " %*s: %u\n" #endif " %*s: %u\n" " %*s: %u\n" , -25, "file-size", size, -25, "", size, e->sh_off + e->sh_entsize * e->sh_num, -25, "sector header offset", e->sh_off, -25, "sector header entry size", e->sh_entsize, -25, "sector header num", e->sh_num ); return ERR_ELF_SECT_CORE_BREACH; } return grub_check_license(e); } int grub_check_module_file(const char *fn, int verbose) { FILE *fh; void *buf; size_t fs; int eno; char *base_fn; if (!(base_fn = strrchr(fn, '/'))) base_fn = (char*)fn; else ++base_fn; fprintf(stderr, "%-25s ", base_fn); if (!(fh = fopen(fn, "rb"))) { fprintf(stderr, "ERR: Unable to open `%s'\n", fn); perror("fopen"); return ERR_FILE_OPEN; } file_size(fh, &fs); if (!(buf = malloc(fs))) { fprintf(stderr, "ERR: Memory.\n"); fclose(fh); return ERR_MEM; } if (fread(buf, 1, fs, fh) != fs) { fprintf(stderr, "ERR: Reading `%s'\n", fn); perror("fread"); free(buf); fclose(fh); return ERR_FILE_READ; } fclose(fh); eno = grub_check_module(buf, fs, verbose); free(buf); return eno; } int main(int argc, char *argv[]) { int i = 1; int eno = 0; int verbose = 0; if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'v') { verbose = 1; ++i; } if (argc - i < 1) { fprintf(stderr, "Usage: %s [-v] <FILE>[, FILE[, ...]]\n", argv[0]); return 1; } for (; i < argc; ++i) { eno |= grub_check_module_file(argv[i], verbose); if (eno == ERR_MEM) return eno; } return eno; }