[3]. initramfs

markyang92·2022년 3월 8일
0

boot

목록 보기
5/6
post-thumbnail

initramfs

  • initramfs: 부트로더에 의해 RAM에 로드되는 파일시스템 이미지, 초기 램 파일 시스템
    • 압축된 cpio 아카이브
      • cpio: 오래된 Unix 아카이브. tar, zip과 비슷하지만, 복호화하기 쉬워 좀 더 적은 커널 코드를 요구한다.
    • initramfs를 지원하려면 커널CONFIG_BLK_DEV_INITRD로 구성해야한다.
    • Ramdisk는 만들기 쉽고 대용량 저장 장치 드라이버에 의존하지 않는다.
    • rootfs의 유지보수 모드로 사용할 수 있다.
    • 작은 Embedded System에서는 아예 rootfs로 사용할 수 있다.
    • 배포판에서는 주로 초기 사용자 공간으로 불리며, 사용된다.

  • BIOS/UEFIkernel이 소통하지 않기 때문에, rootfs 를 마운트 하기 위해
    디바이스에 대한 드라이버/파일 시스템가 필요하다.
    • 디바이스 드라이버를 배포판이 전부 담을 순 없기 때문에, '몇 개의 다른 유틸리티'와 함께 소규모의 커널 드라이버 모듈들을 아카이브로 모은다.
    • 다른 옵션으로는, 빌드 드라이버 모듈/lib/modules/*.ko파일로 두어, 런타임에서 시스템이 모듈 로드를 통해 제공할 수 있다.
      • 하지만 문제는, rootfs가 마운트 되기 전에, 그러한 드라이버들이 필요하다.
      • /lib/modules/rootfs 내부에 있기 때문에, 이들을 로드 할 수 없다.
  • 그래서! 대부분의 현대 배포판에서는 initramfs 이미지를 사용한다.
    • essential modules만 가진다.
    • 간단한 script
    • 간단한 필수 명령어들 (mount, fsck)
  • 부트로더는 커널을 실행하기 전에 initramfs메모리에 로딩한다.
    • 시작되면 커널은 컨텐츠를 읽고 임시 RAM 파일 시스템(initramfs)으로 보내 그 것을 /에 마운트 한다.
    • 그리고 initramfsinit으로 사용자 모드를 이전한다.
    • 이어서 initramfs 에 포함된 유틸리티들은 커널이 실제 부트 파일 시스템을 위해서 필수적인 드라이버 모듈을 로딩할 수 있게 해준다.
    • 마지막으로 유틸리티들은 실제 루트 파일 시스템을 마운트하고 진짜 init을 시작한다.

Embedded System에서의 ramfs

  • Rpi를 예로 들면, 과연 initramfs가 필요할까?
    • H/W는 고정
    • GPU는 변경되지 않음
    • pre-formatted image
    • rootfs는 항상 ext4
    • root device는 SD/USB
  • 만약 여기서 드라이버를 바꾸고 싶다면 initramfs를 사용해야 하겠지만, Pi같은 경우는 그냥 Pi 커널이 다 가지고 있다.
  • '커널'이 루트 파일을 마운트하는데 필요한 모든 드라이버들을 갖고 있다면 부트로더 설정에서 초기 RAM파일 시스템을 생략할 수 있다.
    • 성공한다면 초기 RAM 파일 시스템을 제거함으로써 부팅 시간을 줄일 수 있다. 보통 몇 초 정도다.
      • 부팅 시 (GRUB 메뉴 편집기에서 initrd라인을 제거하면된다.)
      • 최근에는 초기 RAM파일 시스템을 우회하는 것이 좀더 어려워 졌다. UUID에 의해마운트 같은 기능은 일반적인 배포판 커널에서 사용할 수 없기 때문이다.

initramfs 확인(grub)


부트 initramfs 만들기

3가지 방법이 있다.
1.단독형 cpio 아카이브: 유연성이 가장 크다. 커널과 램디스크를 마음대로 짜맞출 수 있다. 하지만 이 것은 두 파일을 다뤄야하고, 모든 부트로더가 분리된 램디스크를 로드하는 기능을 제공하지는 않는다.
2. 커널 이미지에 내장된 cpio 아카이브
3. 커널 빌드 시스템이 빌드의 일부로 처리하는 장치 테이블


1. 단독형 cpio 아카이브

  • 유연성이 가장 크다
  • 커널과 램디스크를 마음대로 짜맞출 수 있다
    • 하지만 이 것은 두 파일을 다뤄야하고, 모든 부트로더가 분리된 램디스크를 로드하는 기능을 제공하지는 않는다.
  1. 다음 명령으로 Target에 로드할 수 있도록 준비된 아카이브로 만들고, 압축하고, u-boot 헤더를 추가한다.
$ cd ~/rootfs
$ find . | cpio -H newc -ov --owner root:root > ../initramfs.cpio
$ cd ..
$ gzip initramfs.cpio
$ mkimage -A arm -O linux -T ramdisk -d initramfs.cpio.gz uRamdisk
  • uRamdisk파일의 최종 크기는 커널 모듈 없이 약 2.9MB이다.
    • 커널 zImage 파일 4.4MB를 더함
    • u-boot 440KB
      총 7.7MB 필요하다.
  • 이 것이 크다면 다음 사항을 고려하자.
  1. 필요 없는 드라이브와 기능을 제거해 커널을 작게 만든다.
  2. 필요 없는 유틸리티를 제거해 BusyBox를 작게만든다.
  3. gblic 대신 musl libcuClibc-ng를 사용한다.
  4. BusyBox를 정적 컴파일한다.

initramfs 부트

profile
pllpokko@alumni.kaist.ac.kr

0개의 댓글