Grub '호환되지 않는 라이센스' 오류

Grub '호환되지 않는 라이센스' 오류

얼마 전 일반 데스크톱용으로 노트북을 사용하고 있었는데 키보드가 작동하기 시작했습니다. 키보드 오른쪽에 있는 대부분의 키가 완전히 작동을 멈췄고, Ctrlu나타나서는 안되는 문자가 나타나게 하는 등의 키 조합이 나타났습니다. 백스페이스 키가 가장 이상한 동작을 보였습니다. 어떻게든 쉘 프롬프트에서 삭제 문자를 발생시킬 수 있었습니다.

컴퓨터를 깔끔하게 재부팅할 수 없어 강제 종료를 했습니다. 컴퓨터를 다시 켰을 때 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를 다시 설치했는데 부팅 시 더 이상 커널 패닉이 발생하지 않습니다.

답변1

업데이트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+.GPLv3GPLv3+

물론 다른 이유일 수도 있습니다. 하지만 그 중 하나가 모듈 파일이 손상되었을 수 있습니다.

ELF모듈은 라이센스 테스트 전에 유효성이 검증되므로 유효한 파일인 것 같습니다 . 예: ELF테스트 실패 시 라이센스 테스트가 실행되지 않습니다.

다양한 사항을 확인해야 하는 모듈에 또 다른 문제가 있었고 해당 코드의 일부를 추출하여 빠른 라이센스 테스터로 만들었습니다. 각 *.mod파일을 테스트하여 /boot/grub/*어떤 파일이 손상되었는지 확인할 수 있습니다.

이 코드는 유효성을 검사 ELF하거나 다른 어떤 것도 수행하지 않습니다. 라이센스 문자열을 찾아서 확인하십시오. 또한 i386/32비트에서만 테스트되었습니다. 추출된 원래 코드는 x86-64에서도 작동했지만 여기서는 많은 부분이 제거되고 해킹되었기 때문에 결과가 확실하지 않습니다. 64비트에서 작동하지 않으면 License: LICENSE=NONE_FOUND.

(위의 편집에서 언급했듯이 이제 Intel 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;
}

답변2

ubuntugeek.com에서 다음 제목의 이 스레드를 살펴보세요.Boot-Repair – 자주 발생하는 부팅 문제를 해결하는 간단한 도구. 이 도구는 HDD의 문제점을 복구하는 데 도움이 될 수 있습니다. 기능 목록을 보면 이 방법이 손을 더럽히지 않고 부팅 파티션을 복구할 수 있는 가장 쉬운 방법인 것 같습니다.

    부팅 복구의 ss

관련 정보