얼마 전 일반 데스크톱용으로 노트북을 사용하고 있었는데 키보드가 작동하기 시작했습니다. 키보드 오른쪽에 있는 대부분의 키가 완전히 작동을 멈췄고, 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+
.GPLv3
GPLv3+
물론 다른 이유일 수도 있습니다. 하지만 그 중 하나가 모듈 파일이 손상되었을 수 있습니다.
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의 문제점을 복구하는 데 도움이 될 수 있습니다. 기능 목록을 보면 이 방법이 손을 더럽히지 않고 부팅 파티션을 복구할 수 있는 가장 쉬운 방법인 것 같습니다.