Initramfs/HOWTO
상당히 많은 시스템이 부팅을 제대로 수행하려면 initramfs를 필요로 합니다. 이 안내서에서는 initramfs의 개념을 파헤치고, 어떻게 제대로 만드는지 어떻게 initramfs 인스턴스를 관리하는지 다루도록 하겠습니다.
initramfs 개념
도입부
대부분의 사용자는 initramfs 시스템을 신경쓰지 않습니다. 사용자들은 단순한 파티션 구조와, (암호화된 파일 시스템같이)낯설지 않은 드라이버 또는 설정을 사용하기 때문에 리눅스 커널은 시스템에서 init
바이너리로 제어권을 넘길 수 있습니다. 다만 대부분의 시스템에서 initramfs는 거의 필수나 다름 없습니다.
리눅스 부팅 과정
리눅스 커널이 (부트로더에서 불러오고 난 후의)시스템에 제어권을 넘기면, 메모리 구조와 드라이버를 가능한대로 준비하는 것입니다. 그 다음 시스템을 더 많이 준비하는 작업을 하는 (보통 init
) 프로그램으로 제어권을 넘기며, 부팅 과정의 마지막에는 모든 필요한 서비스가 동작하는지 확인하며 사용자가 로그온 할 수 있게 처리합니다. init
프로그램 실행으로 이러한 과정을 처리하는데, 다른 서비스 중에, 더 많은 요소를 불러올 udev
데몬은 감지한 장치를 기반으로 시스템을 준비합니다. udev
를 실행하면, 아직 마운트 안된 모든 남아있는 파일 시스템을 마운트하며, 나머지 서비스를 시작합니다.
모든 필요한 파일과 도구가 같은 파일 시스템에 존재하는 시스템에서, init
프로그램은 훨씬 더 많은 부팅 과정을 완벽하게 제어합니다만, 여러가지 파일 시스템을 정의했을 경우(또는 좀 더 낯선 방식의 설치요소를 올려두었다면), 좀 더 복잡해질 수 있습니다:
- /usr 파티션이 다른 파일 시스템에 있을 경우, /usr에 있는 도구와 드라이버는 /usr를 사용할 수 있기 전에는 사용할 수 없습니다. 이들 도구가 /usr을 사용할 수 있게 하는 과정이 필요하다면, 시스템을 부팅할 수 없습니다.
- 루트 시스템을 암호화하면, 리눅스 커널이
init
프로그램을 찾을 수 없어, 시스템을 부팅할 수 없게 됩니다.
이 문제를 해결하는 방법으로 오래전부터 initrd(초기 루트 장치)를 사용하는 방법이 있습니다.
초기 루트 디스크
initrd는 루트 파일 시스템의 init
프로그램으로 제어권을 넘기기 전에 필요한 파일 시스템을 마운트하는데 필수적인 도구와 스크립트를 포함하고 있는 메모리 기반 디스크 구조(램디스크)입니다. 리눅스 커널은 이 루트 디스크에서 시스템을 준비하는 설정 스크립트(보통 linuxrc
라고 하지만 필수적인 요소는 아닙니다)를 실행하고 실제 루트 파일 시스템으로 전환한 후 init
을 실행합니다.
비록 initrd 방식이 필요한 그 전부 자체겠지만, 몇가지 문제가 있긴 합니다:
- 완전히 구색을 갖춘 블록 장치이며 전체 파일 시스템에 대한 오버헤드를 필요로 하고, 고정 크기를 지니고 있습니다. 작은 inintrd를 사용하면 모든 필요한 스크립트를 넣을 수 없고 너무 크게 잡으면, 메모리를 쓸데 없이 많이 사용하게 됩니다.
- 실제 장치이기 때문에, 리눅스 커널의 캐시 메모리를 소모하며, 메모리 및 파일 관리 방식(페이징)을 사용하는 중에 메모리 소모 동작이 잘못될 수도 있습니다.
이 (아마도 말하기 힘든) 문제를 해결하기 위해 initramfs가 만들어졌습니다.
초기 램 파일 시스템
initramfs는 tmpfs(유연한 크기의, 메모리 기반 경량 파일 시스템) 기반의 초기 램 파일 시스템이며 분할 블록 장치를 사용하지 않습니다(그래서 캐싱을 사용하지 않으며 먼저 언급한 모든 오버헤드를 없앴습니다). initrd처럼, 실제 루트 파일 시스템의 init
바이너리를 호출하기 전에 파일 시스템을 마운트하는데 필요한 도구와 스크립트를 넣습니다. 이러한 도구는 추상 레이어, 논리 볼륨 관리자, 소프트웨어 RAID, 파일 시스템 로더 기반 블루투스 드라이버 등에서(암호화된 파일 시스템을) 복호화할 수 있습니다.
initramfs의 내용은 cpio 아카이브를 만들면서 마련합니다. cpio
는 오래된(검증된) 파일 아카이빙 솔루션입니다(그리고 결과 아카이브 파일을 cpio 파일 이라고 합니다). 이걸 분명하게 tar
와 견주어볼 수 있습니다. 여기서 cpio
를 선택한 이유는 (코드 기반) 구현이 비교적 쉬웠고, (tar
라 할 수 없던)장치 파일을 지원(및 유지)해주었습니다.
모든 파일, 도구, 라이브러리, 환경 설정(가능한 경우) 등을 cpio 아카이브에 놓습니다. 이 아카이브는 gzip 유틸리티를 활용하여 압축하며 리눅스 커널 부분에 저장합니다. 부트로더는 부팅 시간에 이 아카이브를 제공하여 커널이 initramfs가 필요함을 알도록 해줍니다.
initramfs를 커널이 감지하고 나면 tmpfs 파일 시스템을 만들고, 내용을 이 파일 시스템에 추출한 다음, tmpfs 파일 시스템의 루트에 위치한 init 스크립트를 실행합니다. 그 다음 이 스크립트로 실제 루트 파일 시스템을 마운트하고(다음 마운트를 확실하게 한 다음에는, 추가 모듈을 불러온다든지 하는 식으로, 암호화된 추상 레이어 같은 요소를 준비합니다) 이와 같이 다른 파일 시스템(/usr 또는 /var)을 활성화합니다.
루트 파일 시스템과 다른 실제 파일 시스템을 마운트 하고 나면 initramfs의 init 스크립트는 실제 루트 시스템으로 전환하고, 실제 루트 시스템의 /sbin/init을 호출하여 부팅 과정을 계속 진행합니다.
initramfs 만들기
도입부 및 부트로더 설정
initramfs를 만들려면 어떤 추가 드라이버, 스크립트, 도구가 시스템에 필요한지 알아야 하며 이 점이 중욯바니다. 예를 들어 LVM을 사용한다면, initramfs에 LVM 도구 지원이 필요합니다. 이와 같이 소프트웨어 RAID를 사용한다면 mdadm 등이 필요합니다.
The root disk and root filesystem needs to be accessible
In practice, this usually means CONFIG_SATA_AHCI or CONFIG_BLK_DEV_NVME (for the disk), and CONFIG_EXT4_FS (the filesystem) should ideally be built-in [=y] to the kernel; otherwise having these as modules [=m] will require these modules to be loaded by the initramfs first so booting can continue.
If LVM is used, then LVM tools will be needed in the initramfs.
If software RAID is used, mdadm utilities will be needed, or DMRAID, etc... ZFS and BTRFS would also require consideration here.
시스템의 initramfs(압축된 cpio</ctt> 아카이브)를 만드는데 도움을 줄 몇가지 도구가 있긴 합니다만, 완전한 제어를 목적으로 개인/개별적인 initramfs를 쉽게 만들 수 있습니다.
이를 만들고 나면, 사용할 initramfs에 사용 정보를 알릴 부트로더 설정을 건드려야 합니다. 예를 들어 /boot/initramfs-3.2.2-gentoo-r5에 initramfs 파일을 저장했다면, /boot/grub/grub.conf 설정은 다음과 같습니다.
Usually this is done by re-generating the config file grub-mkconfig -o /boot/grub/grub.cfg
For instance, if the initramfs file is stored as /boot/initramfs-5.15.32-gentoo-r1.img, then afterwards, the GRUB configuration in /boot/grub/grub.cfg would look somewhat like the following:
title Gentoo Linux 3.2.2-r5
root (hd0,0)
kernel /boot/kernel-3.2.2-gentoo-r5
initrd /boot/initramfs-3.2.2-gentoo-r5
genkernel 사용하기
젠투 커널 빌드 유틸리티인 genkernel는 커널 설정 및 빌드에 genkernel을 사용하지 못하더라도 initramfs를 만드는데 사용할 수 있습니다.
initramfs를 만드는데 genkernel
을 사용하려면, 필요한 모든 드라이버와 /와 /usr 파일 시스템을 마운트 하는 코드를 커널에 (모듈로서가 아니라) 포함시킬 것을 권장합니다. 그러면, 다음과 같이 genkernel을 호출하십시오:
If modules are required in the initramfs, call genkernel as follows:
root #
genkernel --install --no-ramdisk-modules initramfs
시스템에 따라, 다음과 같이 하나 이상의 옵션 추가가 필요할 수도 있습니다:
옵션 | 설명 |
---|---|
--disklabel
|
/etc/fstab 의 LABEL= 설정 지원 추가
|
--dmraid
|
가짜 하드웨어 RAID 지원 추가 |
--firmware
|
시스템에 있는 펌웨어 코드 추가 |
--gpg
|
GnuPG 지원 추가 |
--iscsi
|
iSCSI 지원 추가 |
--luks
|
luks 암호화 컨테이너 지원 추가 |
--lvm
|
LVM 지원 추가 |
--mdadm
|
소프트웨어 RAID 지원 추가 |
--multipath
|
SAN용 다중 입출력 접근 지원 추가 |
--zfs
|
ZFS 지원 추가 |
실행이 끝나면, 결과 initramfs파일은 /boot에 들어갑니다.
Dracut 활용하기
dracut 유틸리티는 initramfs 파일을 관리하는 단순한 목적으로 만들었습니다. 어떤 지원을 넣을지 여부는 상당히 모듈화된 접근 방식으로 진행합니다.
필요한 (또는 필요하지 않은) 모듈을 설정(또는 해제)해볼 것을 권장합니다. 그런 다음, 시스템에 유틸리티를 설치하려면 emerge dracut을 실행하십시오.
root #
emerge --ask sys-kernel/dracut
다음 단계는 /etc/dracut.conf를 편집하여 dracut
을 설정하는 것입니다. 설정 파일에서 주석으로 적어놓은 바와 같이, 필요한 곳에 언급한 각각의 모듈에 대한 지원을 추가할 수 있습니다.
설정이 끝나면, dracut을 호출하여 다음처럼 initramfs를 만드십시오:
root #
dracut
결과 이미지는 /etc/dracut.conf의 설정을 기반으로 하여 일반 시스템 부팅을 지원합니다. 또한 (기존의 시스템에 필요한 도구, 드라이버 등을 감지하기 위해 dracut
이 어떤 동작을 수행해야 하는지) 시스템에 특별히 맞춰 initramfs를 만들도록 옵션을 조정할 수 있습니다. 커널에 빌드한 (코드와 드라이버) 지원(모듈 아님)이 필요하다는 점을 안다면, --no-kernel 옵션을 추가할 수도 있습니다:
root #
dracut --host-only --no-kernel
더 많은 정보는 dracut과 dracut.cmdline 맨페이지를 확인하십시오:
user $
man dracut
user $
man dracut.cmdline
추가 참조
외부 자료
- 리눅스 커널 문서의 ramfs-rootfs-initramfs.txt