지난 편에서는 initrd 없이 root=/dev/vda로 직접 부팅하는 구성으로 defconfig 커널의 베이스라인을 측정했다. 하지만 실제 임베디드/컨테이너 이미지에서는 initrd(정확히는 initramfs)를 쓰는 구성도 흔하다 — 루트 파일시스템 드라이버를 모듈로 빼두고 initramfs에서 필요한 것만 로드하는 유연성 때문이다. 문제는 이 유연성이 공짜가 아니라는 점이다. 이 글에서는 같은 커널을 initrd 구성으로 다시 부팅해 이미지 크기·RAM 사용량·부팅 시간을 지난 편 베이스라인과 직접 비교한다.
이 시리즈의 다른 글
- 메모리가 작은 시스템을 위한 커널 경량화 (1) — 측정 방법론과 베이스라인
- 메모리가 작은 시스템을 위한 커널 경량화 (3) — Kconfig 옵션으로 커널 이미지 줄이기
- 메모리가 작은 시스템을 위한 커널 경량화 (4) — 빌드 최적화와 initramfs 축소
- 메모리가 작은 시스템을 위한 커널 경량화 (5) — 커널 메모리 관리 옵션 검토
- 메모리가 작은 시스템을 위한 커널 경량화 (6) — 종합 비교와 메모리 한계 실증
테스트 환경
커널 바이너리(bzImage)는 지난 편과 완전히 동일하다. rootfs 구성만 바뀐다 — 지난 편은 ext4 디스크 이미지를 virtio-blk로 직접 마운트했고, 이번엔 busybox만 담은 cpio를 initramfs로 커널에 함께 로드한다.
| 항목 | 지난 편 (initrd 없음) | 이번 편 (initrd 사용) |
|---|---|---|
| 커널 | 동일한 bzImage (defconfig) | 동일한 bzImage (defconfig) |
| rootfs | ext4 64MB, -drive ... root=/dev/vda | busybox cpio.gz, -initrd |
| 필수 built-in 옵션 | CONFIG_VIRTIO_BLK, CONFIG_EXT4_FS | 없음 (모듈로도 가능) |
initrd로 부팅하기
init 스크립트는 지난 편과 동일하게 proc/sysfs를 마운트하고 측정값을 출력한 뒤 종료한다. 이번엔 -drive 없이 -initrd만 넘긴다.
qemu-system-x86_64 \
-kernel arch/x86/boot/bzImage \
-initrd initramfs-min.cpio.gz \
-append "console=ttyS0 quiet" \
-m 1024M \
-nographic \
-no-reboot===== free -m =====
total used free shared buff/cache available
Mem: 969 19 947 2 3 938
Swap: 0 0 0
===== /proc/meminfo (head) =====
MemTotal: 992240 kB
MemFree: 970144 kB
MemAvailable: 960780 kB
Buffers: 0 kB
Cached: 2052 kB
===== slab total =====
Slab: 6752 kB
SReclaimable: 784 kB
SUnreclaim: 5968 kB
===== boot done =====
[ 3.856575] reboot: Power down
비교 결과
| 항목 | initrd 없음 | initrd 사용 | 차이 |
|---|---|---|---|
| 부팅 페이로드 (부트로더가 사전 로드) | bzImage 14.8MB (rootfs는 디스크에서 필요 시 읽음) | bzImage 14.8MB + initramfs 1.06MB = 15.9MB (전부 사전 로드) | +1.06MB |
| 부팅 직후 used | 13 MB | 19 MB | +6 MB |
| shared (ramfs 상주분) | 0 MB | 2 MB | +2 MB |
| buff/cache | 3 MB (Buffers 108kB 포함, 블록 I/O 캐시) | 3 MB (Buffers 0kB, 블록 디바이스 자체가 없음) | – |
| Slab 총합 | 6.7 MB | 6.8 MB | +0.1 MB |
| 커널 타임스탬프 (userspace 도달) | 5.37초 | 3.86초 | -1.51초 |
부팅 시간은 오히려 initrd 쪽이 더 짧았다. virtio-blk PCI 프로브와 ext4 마운트에 걸리는 시간이 통째로 빠지기 때문이다. 대신 RAM은 initrd 쪽이 6MB 더 쓴다 — initramfs 콘텐츠가 ramfs로 마운트되기 때문에 페이지가 회수(reclaim) 대상이 아니라 그대로 상주한다.
주의사항
- initramfs는 ramfs 위에 풀리기 때문에
switch_root로 진짜 rootfs로 넘어가기 전까지 그 콘텐츠가 RAM에서 회수되지 않는다. 이 글은 initramfs를 최종 rootfs로 그대로 쓰는 경우만 측정했고, “initramfs에 모듈만 담아 부팅한 뒤 실제 rootfs로 switch_root하고 initramfs 메모리를 반납”하는 2단계 구성은 별도로 검증하지 않았다 — 이 경우 순간적으로는 initramfs+실제 rootfs 드라이버가 동시에 메모리에 있어야 하므로 위 표의 +6MB보다 일시적으로 더 커질 수 있다. - 부팅 시간 차이(-1.51초)는 QEMU의
virtio-blk프로브 오버헤드에 크게 좌우된 결과다. 실기기의 NVMe/eMMC처럼 훨씬 빠른 스토리지에서는 이 격차가 줄어들 수 있다. - initrd 구성에서는 지난 편에서 다룬 “블록 드라이버·파일시스템이 반드시 built-in이어야 한다”는 제약이 사라진다. 필요한 드라이버를 모듈로 두고 initramfs 안에
.ko와modprobe스크립트를 넣어두면 되기 때문인데, 이건 곧 vmlinux 자체 크기를 줄이는 데는 initrd 쪽이 유리할 수 있다는 뜻이다 — 다음 편에서 Kconfig 옵션을 정리할 때 이 트레이드오프를 다시 참고한다.
마무리
같은 커널로 두 가지 부팅 방식을 비교한 결과, initrd는 부팅이 더 빠른 대신 RAM을 더 쓰고, initrd 없이 직접 마운트하는 쪽은 RAM은 아끼지만 필수 드라이버를 전부 built-in으로 강제한다는 트레이드오프가 실측으로 확인됐다. 메모리가 빠듯한 시스템이라면 이 6MB(전체 RAM의 0.6% 수준이지만 128MB급 초저사양 보드에서는 5% 가까이 된다) 차이가 실제 선택 기준이 될 수 있다. 다음 편에서는 menuconfig/localmodconfig로 두 구성 모두에 공통으로 적용 가능한 Kconfig 옵션들을 정리하며 이미지 크기를 줄인다.