2021. 8. 23. 00:41ㆍLinux
이번 시간에는 부팅에 대해 공부 해 보겠습니다.
부팅이란? : 하드디스크 또는 SSD 등 보조기억장치로 운영체제를 불러 들이는 작업을 의미합니다.
즉 저희가 데스크탑에 전원을 키면 컴퓨터는 OS가 저장되어 있는 보조기억장치(HDD, SSD, USB 등)로 부터 OS(윈도우)를 가동시켜 사용자가 컴퓨터를 사용할 수 있도록 해주는 것입니다.
그럼 부팅 과정을 한번 알아보겠습니다.
부팅 과정은 크게 바이오스 과정, 부트 프로그램 과정, 커널 과정, init 프로세스 과정으로 총 4단계로 나뉩니다.
1. 바이오스(bios) 과정 : 시스템에 전원이 들어오면 ROM안에 있는 POST 프로그램이 시스템의 기본적인 하드웨어 이상 유무를 점검합니다. 여기서 기본적인 하드웨어란 CPU, RAM 등을 의미합니다.
메모리에는 크게 ROM과 RAM으로 구분합니다.
ROM(Read Only Memory) : 전원이 꺼져도 기록된 내용이 유지되는, 지워지지 않는 비휘발성 메모리입니다. 읽기 전용이기 때문에 기록 할 수는 없습니다
RAM(Random access memory) : 전원이 꺼지면 기록된 정보도 지워지는 휘발설 메모리입니다. 그렇기 때문에 컴퓨터의 주기억장치, 데이터의 임시 저장소등으로 사용됩니다.
POST(Power On Self Test) : 자체진단기능, 이 프로그램은 ROM에 저장되어 있으며 운영체제보다 먼저 실행됩니다. POST 과정에서 문제가 발생하면 시스템 시작이 중단되고 화면에 메시지가 표시됩니다. POST 과정이 이상 없이 진행 완료되면 OS가 들어있는 보조기억장치(HDD, SSD 등 부팅매체)에서 부트로더를 동작시킵니다.
2. 부트(boot) 로드 과정 : 부트로더가 동작, 즉 메모리에 적재되면 바이오스는 종료됩니다. 부트로더는 커널을 메모리상에 올려(적재시켜)서 시스템 제어권을 커널에게 넘겨주는 역할을 합니다. 리눅스에서 사용하는 부트로더는 LILO, GRUB, GRUB2 등이 있으며 현재 GRUB2를 사용합니다.
용어 정리 한번 하고 가겠습니다. 메모리에 올려둔다. 메모리에 적재시킨다. 는 모두 프로그램을 실행 시킨다는 의미입니다.
POST 과정이 이상 없이 진행 완료되면 OS가 들어있는 보조기억장치(HDD, SSD 등 부팅매체)에서 부트로더를 동작시킨다고 했습니다. 리눅스의 부트로더는 보조기억장치의 첫번째 섹터인 MBR에 저장되기 때문에 정확히는 MBR에 있는 부트로더를 동작시키는 것입니다.
MBR : 마스터 부트 레코드이며 부팅에 필요한 정보들이 있기 때문에 MBR을 읽어야 부트로더가 동작을 하고 부팅을 할 수 있게 됩니다.
GRUB : GRand Unified Bootloader
제가 사용하고 있는 CentOS 7 리눅스는 부트로더로 GRUB에서 버전업 된 GRUB2를 사용합니다. 이 둘의 큰 차이점은 버전업된 이후 설정 파일에서 셸 스크립트를 지원한다는 점입니다.
설정 파일 : /boot/grub2/grub.cfg
이 파일을 직접적으로 변경하는 것은 옳지 않습니다. 이 파일을 잘 못 건드리면 부팅 자체에 오류가 생길 수 도 있기 때문입니다
그럼 부트로더의 설정을 변경 하고 싶을 때는 어떻게 해야 할까요? 그럴때는 /etc/default/grub 파일과 /etc/grub.d 디렉터리에 있는 파일들을 수정 해주면 됩니다. 수정후 저장만 하면 변경된 내용이 적용이 안됩니다. 적용 시키기 위해서는 grub2-mkconfig -o 적용시킬 파일을 해주어야 합니다. 여기서는 적용시킬 파일이 부트로더의 설정 파일이기 때문에 grub2-mkconfig -o /boot/grub2/grub.cfg 해주면 됩니다.
/boot/grub2/grub.cfg 파일을 열어보면 두번째 줄에 DO NOT EDIT THIS FILE이라고 주석 처리 되어 있는 것을 볼 수 있습니다. 즉 이 파일을 수정하지 마세요 라는 말입니다. 그리고 파일 내용을 보면 셸 스크립트로 구성되어 있는 것을 볼 수 있습니다.
이제 사용자가 수정 할 수 있는 부트로더 파일들을 확인 해 보겠습니다.
1. /etc/default/grub
1.1 GRUB_TIMEOUT=5
시스템에 전원을 켰을 때 부팅되기 까지의 대기시간입니다. 대기시간 동안 직접 엔트리를 선택 할 수 있습니다. 키보드의 입력(enter)가 있을 경우 기다리지 않고 바로 부팅을 실행합니다. 5초후 부팅을 시작하겠다는 뜻입니다. -1은 자동으로 부팅이 안되고 사용자의 선택 까지 무한정 대기 하겠다는 것입니다.
1.2 GRUB_DISTRIBUTOR="$(sed 's, release . *$,,g' /etc/system-release)"
부트 엔트리명에 추가할 접두어입니다. 리눅스 시스템에 전원을 키면 다음과 같이 부트 엔트리를 선택할 수 있는 화면이 나옵니다.
엔트리명을 보면 접두사가 CentOS Linux 라고 적혀 있는 것을 볼 수 있습니다. 이것을 변경 할 수 있는 것입니다.
"$(sed 's, release.*$,,g' /etc/system-release)" 이게 무슨 뜻인지 알아보겠습니다.
SED(Stream Editor)는 sed라는 명령어로 원본 파일을 편집할 때 사용하는 에디터입니다. 파일을 편집 할 때 사용하는 에디터에 대해서는 vi, nano, gedit를 배운 적이 있습니다. 하지만 sed는 저희가 배운 평범한 에디터와는 다릅니다.
sed는 다른 에디터들과는 다르게 원본을 건드리지 않고 편집을 합니다. 즉 sed 를 통해 수정 후 저장을 해도 원본 파일에는 변화가 없다는 것입니다. (단 -i 옵션을 사용하면 원본 파일도 수정이 됩니다)
-i 옵션을 사용하지 않으면 원본 파일 수정도 안되는데 sed를 사용하는 이유가 궁금하실수 있습니다.
sed는 파일을 수정하는 에디터지만 수정한 내용을 stdout, 모니터에 출력합니다. 그렇기 때문에 사실상 파일의 특정 내용을 출력할 때 주로 사용한다고 생각하시면 됩니다.
그럼 이제 한번 확인 해 보겠습니다. "(sed 's, release.*,,g' /etc/system-release)"
s는 substitute(치환)의 약자이며 g는 global의 약자입니다. 보통 sed s/old/new/g 파일명 형식으로 사용합니다. 여기서 /는 구분자로 사용되며 구분을 위해 사용하기 때문에 꼭 / 일 필요가 없습니다.
즉 "(sed 's, release.*,,g' /etc/system-release)"는
- sed 's : 치환을 할 것입니다.
- ,(콤마) : 구분자는 ,(콤마)를 사용하겠습니다.
- release.* : release로 시작하는 내용이 old에 해당하고 ,, 즉 공백이 new에 해당합니다.
즉 release로 시작하는 내용을 공백으로 치환하겠다, 지우겠다라는 뜻입니다.
주의 release가 있는 행을 지우는 것이 아니라 release가 시작하는 release 포함 뒤의 내용들을 지운다는 뜻입니다.
예시)
your 앞의 내용은 그대로 출력되고 your포함 뒤의 내용들만 공백으로 치환이 된것을 볼 수 있습니다.
- /etc/system-release : 이 파일에 sed 치환 명령을 적용시키겠다는 것입니다.
이 파일에 release 포함 뒤의 내용들을 공백으로 치환하게 되면 다음과 같이 됩니다.
이것을 부트 엔트리의 접두어로 사용한다는 의미가 되는 것입니다.
1.3 GRUB_DEFAULT=saved
이전에 선택한 부트 엔트리를 기본적으로 계속 선택하겠다는 것입니다. 0으로 지정하면 첫 번째 엔트리가 선택됩니다.
1.4 GRUB_DISABLED_SUBMENU=true
서브 메뉴를 사용하지 않겠다는 것입니다.
1.5 GRUB_TERMINAL_OUTPUT="console"
grub 설정 화면을 어디로 나오게 할 것인지를 정하는 것입니다. console로 설정하면 모니터로 출력하겠다는 의미입니다.
1.6 GRUB_CMDLINE_LINUX="crashkernel=auto spectre_v2=retpoline rd. lvm. lv=centos/root rd. lvm. lv=centos/swap rhgb quiet"
부팅 할 경우 커널에 전달할 파라미터를 지정하는 부분입니다. 이 설정을 사용해서 단일 유저 모드인 복구 모드로 접속 할 수 있습니다. 또한 init=/bin/sh 을 추가해서 응급 복구용 터미널로 접속이 가능합니다.
1.7 GRUB_DISABLE_RECOVERY="true"
메뉴에서 복구와 관련된 부분을 비활성화 하겠다는 것입니다
이제 직접 이 파일 내용을 변경하여 확인 해 보겠습니다. 먼저 부팅 대기시간부터 변경 해보겠습니다.
이와 같이 기본 대기 시간은 5초인것을 알 수 있습니다. 이를 20초로 변경 해보겠습니다.
부팅 대기 시간이 20초로 변경된것을 볼 수 있습니다. 꼭 파일 내용을 수정후 grub2-mkconfig -o /boot/grub2/grub.cfg 명령어를 사용해서 수정된 내용을 적용시켜야 하는 점을 기억하고 있어야 합니다.
이번에는 root 비번을 잃어버렸을때 재지정 하는 방법에 대해 배워보겠습니다.
부팅대기 화면 즉 엔트리를 선택하는 화면을 자세히 보면 e를 사용해서 편집 모드로 들어갈 수 있는 것을 알 수 있습니다.
이 편집 모드에서 rhgb quiet부분을 init=/bin/sh으로 변경해 줄 것입니다.
근데 이 부분을 어디서 본거 같지 않습니까? 맞습니다. 저희가 아까 공부한 /etc/default/grub 파일의 1-6번째 내용이였습니다.
1.6 GRUB_CMDLINE_LINUX="crashkernel=auto spectre_v2=retpoline rd. lvm. lv=centos/root rd. lvm. lv=centos/swap rhgb quiet"
즉 이 파일 내용을 수정한후 재부팅을 하면 방금 편집 모드에서 수정후 부팅을 시작하는 것과 같은 효과를 얻을 수 있습니다.
이제 내용을 수정했으니 ctrl + x를 눌러 부팅을 계속 진행 하겠습니다.
부팅을 진행했더니 다음과 같은 모드로 들어왔습니다. 이 모드를 응급 복구 모드라고 합니다.
id를 확인 해보니 현재 root 계정으로 접속되어 있는 것을 알 수 있습니다. 이제 passwd 명령어로 root의 비번을 새로 지정해주면 됩니다.
하지만 에러가 났습니다. 왜일까요? 다시 아까 편집모드 화면을 보겠습니다.
자세히 보면 ro 라고 적힌 부분이 있습니다. crashkernel 바로 전에 있습니다. 이부분이 ro 즉 읽기 전용이라서 오류가 났던 것입니다. 해결 방법은 두가지 있습니다. 첫번째는 편집모드에서 ro를 rw로 변경 해주는 것입니다.
두번째는 remount 해주는 것입니다.
이제 정상적으로 root 비번이 업데이트 된것을 확인 할 수 있습니다.
하지만 이러한 root 비번 변경에는 문제가 있습니다. 아무 사용자나 이 방법을 사용해서 root 비번을 마음대로 변경 할 수 있다는 점입니다. 이를 방지 하기 위해 편집 모드로의 진입에 제한을 걸어야 합니다.
로그인을 걸어 아이디와 비번을 모르는 사용자는 편집 모드에 진입하지 못하도록 하는 것이 좋습니다.
이번에는 /etc/default/grub 파일이 아니라 다른 파일을 수정해야 합니다.
부트로더 설정을 변경하려면 /etc/default/grub 파일이나 /etc/grub.d 디렉터리에 있는 파일들을 수정해 주면 된다고 배웠습니다.
2. /etc/grub.d 디렉터리
이 파일들중 00_header 파일을 수정 할 것입니다. 이 파일의 제일 마지막 줄에 다음과 같은 내용을 추가하겠습니다.
* 00_header 파일 뿐만 아니라 /etc/grub.d 디렉터리에 있는 모든 파일을 수정후에는 grub2-mkconfig 명령어를 꼭 사용해줘야 적용이 됩니다.
cat<<EOF는 여러 줄을 쓸수 있게 해줍니다. EOF는 시작과 끝을 알리는 문자이며 꼭 EOF가 아닌 다른 문자를 사용해도 상관 없습니다. 마지막에 똑같이 써줘야 합니다.
예시를 보겠습니다.
위와 같이 입력한 내용을 바로 출력하지 않고 여러 줄을 한번에 입력했다가 EOF가 나오자 출력하는 것을 볼 수 있습니다.
위의 내용을 저장후 부트로더 설정 파일에 적용시키는 명령어 grub2-mkconfig -o /boot/grub2/grub.cfg 명령어를 친후 다시 편집 모드로 진입해보겠습니다.
편집 모드로 진입하려고 하자 아이디 비번을 입력하라는 메세지가 뜨고 아까 설정한 아이디 비번을 입력하자 편집모드로 접속 할 수 있었습니다.
3. 커널(kernel) 과정 : 커널이 메모리상에 적재되면 운영체제가 구동하기 시작합니다. 부트로더 과정에서 커널에 시스템 제어권을 넘겼기 때문에 이 과정부터는 실질적인 시스템 컨트롤은 커널이 전부 한다고 생각하시면 됩니다. 또한 사용자가 셸에 입력한 명령어들도 커널이 받아서 실행합니다. 그렇기 때문에 커널은 이 과정부터 항상 메모리에 적재 되어 있어야 합니다.
4. init 프로세스 과정 : 저번 시간에 배운 init 프로세스에 관한 과정입니다. init 프로세스는 커널에 의해 생성되는 첫 번째 프로세스이며 커널의 실행으로 운영체제가 하드웨어의 모든 기능을 제어하게 되었을때 init 프로세스가 실행됩니다.
init 프로세스는 모든 프로세스의 부모 프로세스이며 부팅 과정에서 사용자가 시스템을 사용할 수 있게 초기화 작업을 담당하는 프로세스입니다. init 프로세스가 실행되면서 여러 필요한 자식 프로세스가 생성되면서 동작을 하게 됩니다.
이상으로 부팅 과정과 부트로더 설정 파일을 다뤄보는 내용을 배워보았습니다. 다음 시간에는 파일시스템에 대해 배워보겠습니다.
다음 내용
'Linux' 카테고리의 다른 글
RAID - mdadm (0) | 2022.05.23 |
---|---|
커널 매개 변수 값 제어(sysctl) (0) | 2022.05.23 |
Linux - Run Level (0) | 2021.08.19 |
Linux - 프로세스 - 3 (데몬 프로세스) (0) | 2021.08.17 |
Linux - 프로세스 - 2 (종료, 종류, 제어) (0) | 2021.08.17 |