리눅스 부팅 멈춤 증상 해결법 한 가지
First Published at
8/10/2023 5:33:04 AM
Last Edited at
8/29/2023 4:22:52 AM
nomodeset 옵션으로 리눅스 부팅이 멈추는 증상을 해결해봅니다.
“
본 글은 리눅스 커널 6.1 기준으로 작성되었습니다.
리눅스를 처음 설치, 혹은 업데이트했을 때 부팅이 멈춰버리는 경우를 경험해보셨을 것입니다. 이번 글에서는 이를 해결할 수 있는 방법 중 한가지를 소개해드리려 합니다.
#
nomodeset
이란?
“
The newest kernels have moved the video mode setting into the kernel. So all the programming of the hardware specific clock rates and registers on the video card happen in the kernel rather than in the X driver when the X server starts.. This makes it possible to have high resolution nice looking splash (boot) screens and flicker free transitions from boot splash to login screen. Unfortunately, on some cards this doesnt work properly and you end up with a black screen. Adding the nomodeset parameter instructs the kernel to not load video drivers and use BIOS modes instead until X is loaded.
— https://ubuntuforums.org/showthread.php?t=1613132
txt
linux/Documentation/admin-guide/kernel-parameters.txt
nomodeset Disable kernel modesetting. Most systems' firmwaresets up a display mode and provides framebuffer memoryfor output. With nomodeset, DRM and fbdev drivers willnot load if they could possibly displace the pre-initialized output. Only the system framebuffer willbe available for use. The respective drivers will notperform display-mode changes or accelerated rendering.
리눅스에서는 비디오 모드 세팅 역할을 커널이 가지고 있습니다. 그래서 그래픽 드라이버 대신 커널이 그래픽카드 제어를 담당합니다. 이렇게 하면 고해상도 부팅 스크린(splash)을 구현할 수 있고, 부팅 스크린에서 로그온 화면으로 넘어가는 과정을 깜빡임 없이 부드럽게 진행할 수 있습니다. 하지만 일부 그래픽카드에서는 제대로 작동하지 않는 문제가 있는데, 부팅이 도중에 멈춰버리기도 합니다.
grub
1
cat /etc/default/grub···
3
# info -f grub -n 'Simple configuration'4
5
GRUB_DEFAULT="nomodeset"6
···
nomodeset
옵션을 grub
부트로더에 옵션으로 주면 이 역할을 X
가 완전히 로드될 때까지 그래픽 드라이버가 로드되지 않도록 커널에 지시합니다.#
nomodeset
의 전달 경로
C
linux/drivers/gpu/drm/drm_nomodeset.c
1
// SPDX-License-Identifier: GPL-2.02
3
#include <linux/module.h>4
#include <linux/types.h>5
6
static bool drm_nomodeset;7
8
bool drm_firmware_drivers_only(void)9
{10
return drm_nomodeset;11
}12
EXPORT_SYMBOL(drm_firmware_drivers_only);13
14
static int __init disable_modeset(char *str)15
{16
drm_nomodeset = true;17
18
pr_warn("Booted with the nomodeset parameter. Only the system framebuffer will be available\n");19
20
return 1;21
}22
23
/* Disable kernel modesetting */24
__setup("nomodeset", disable_modeset);
nomodeset
설정 값이 어떻게 실제로 적용되는지를 간단히 살펴보겠습니다.drm_nomoeset.c
를 보면 6라인에 static bool
타입 변수 drm_nomodeset
이 존재합니다. 그리고 24라인의 __setup("nomodeset", disable_modeset)
매크로는 부트로더가 넘겨준 부팅 parameter 중 nomodeset
가 존재할 경우 14라인의 disable_modeset()
함수를 실행하도록 지시합니다. disable_nomodeset()
함수는 앞선 static 변수 drm_nomodeset
의 값을 true
로 설정합니다.“
DRM이란 Direct Rendering Manager의 약자로 GPU와의 인터페이스 역할을 하며 리눅스 서브시스템(subsystem) 중 하나입니다.
그래픽 드라이버는 이
drm_nomodeset
의 값을 8라인의 drm_firmware_drivers_only()
함수를 통해 참조합니다.C
linux/drivers/gpu/drm/radeon/radeon_drv.c
···
147
int radeon_modeset = -1;
···
630
static int __init radeon_module_init(void)631
{632
if (drm_firmware_drivers_only() && radeon_modeset == -1)633
radeon_modeset = 0;634
635
if (radeon_modeset == 0)636
return -EINVAL;637
638
DRM_INFO("radeon kernel modesetting enabled.\n");639
radeon_register_atpx_handler();640
641
return pci_register_driver(&radeon_kms_pci_driver);642
}
···
651
module_init(radeon_module_init);···
이번 글에서는 라데온 드라이버를 예로 들어보겠습니다. 147라인에서
radeon_modeset
의 값은 -1
로 지정되어 있는 상태입니다. 632라인에서 drm_firmware_drivers_only()
함수를 호출합니다. 만약 nomodeset
옵션이 붙여져 있었다면, 이 함수가 true
를 반환할 것입니다. 이때 radeon_nomodeset
의 값이 0
이 되므로, 635라인에 의해 651라인이 지시했던 드라이버 로드 과정을 종료시켜버립니다. 651라인의 module_init()
매크로는 커널 모듈을 등록하는 역할이었습니다.#
nomodeset
옵션을 이용해 리눅스 설치하기
nomodeset
옵션을 붙이면 부팅 과정이 끝날 때까지 그래픽 드라이버 사용이 중지됩니다. 따라서 호환성 문제가 있을 때 유용하게 사용할 수 있습니다. 이번에는 실제로 nomodeset
옵션을 사용해보겠습니다.#
설치 미디어로 부팅
설치 미디어로 부팅을 시도하면 위와 같이 GRUB 부트로더가 나타날 것입니다. 여기서 Try or Install Ubuntu (Server) 옵션에 커서를 위치시킨 뒤,
e
키를 누릅니다.그러면 위와 같이 부팅 파라미터를 세팅할 수 있는 화면이 나타납니다.
여기서
linux
가 적혀있는 라인으로 간 뒤, ---
을 없애고 nomodeset
으로 대체합니다. 그 후 Ctrl + x
나 F10
을 눌러 해당 설정으로 부팅합니다.이제 자유롭게 리눅스 설치를 진행합니다.
#
설치 완료 후 첫 부팅
이제 시스템에 따라 재부팅 후 먹통이 되는 경우가 있을 것입니다.
메인보드 로고, 혹은 POST가 뜬 직후
Esc
를 누르거나 Shift
를 누르고 있으세요.“
시스템에 따라
Esc
를 누르면 UEFI Setup으로 진입할 수 있습니다. 이 때는 UEFI Setup에서 Boot Override 기능을 이용해 재부팅하여 다시 시도하거나, Shift
를 사용하세요.이제 시스템에 정식으로 설치된 GRUB이 나타납니다. 여기서 Ubuntu에 커서를 맞춘 뒤 마찬가지로
e
키를 누르세요.
여기서도 마찬가지로
linux
가 있는 라인을 찾습니다.이제 마지막 파라미터 뒤에
nomodeset
파라미터를 붙입니다. 마찬가지로 Ctrl + x
나 F10
을 눌러 부팅을 진행합니다.정상적으로 부팅이 진행되는 모습입니다.
이제 GRUB 세팅을 바꿀 차례입니다.
Bash
$ sudo nano /etc/default/grub
여기서 손 볼 것은
GRUB_CMDLINE_LINUX_DEFAULT
부분입니다.GRUB_CMDLINE_LINUX_DEFAULT
의 맨 마지막에 nomodeset
을 붙여주세요.이후 저장하고 빠져나옵니다.
Bash
$ sudo update-grub
이제 GRUB 설정을 업데이트합니다.
여기까지입니다. 이제 기본적으로 부팅 시에 아무 것도 건들지 않아도
nomodeset
옵션이 붙은 채로 부팅이 진행될 것입니다.