본문으로 이동
  • 현재 모든 문서는 작성 중입니다. 보시는 데 불편함이 있더라도 양해 부탁드립니다.

운영체제 기본/x86-64 Linux의 BIOS 부팅/루트 파일시스템과 init 선택

~ldmsys

운영체제 기본 목차 · 부팅 목차

Linux v6.12의 PID 1은 초기 루트 파일시스템을 준비하고 kernel_init()에서 실행할 init 파일을 고른다. initramfs의 /init을 사용할지, 루트 장치를 마운트한 뒤 다른 경로를 찾을지는 이 단계에서 결정된다.

init을 실행하려면 먼저 그 파일이 있어야 한다

실행 파일을 열려면 경로 탐색을 시작할 루트 파일시스템이 필요하다. VFS는 루트에서 각 디렉터리 이름을 해석해 inode를 찾고 파일 연산에 연결한다. 경로와 마운트, 열린 파일 객체의 관계는 VFS와 파일 객체를 참고한다. 초기에는 rootfs가 있고, initramfs 아카이브의 파일들이 여기에 풀린다. init/initramfs.c의 populate_rootfs()는 비동기 작업을 등록하며, 그 작업이 내장 아카이브와 조건에 따라 외부 이미지를 푼다. wait_for_initramfs()는 이 작업이 끝나기 전에 init 파일에 접근하는 일을 막는다.[1]

초기 rootfs의 실행 후보(기본 /init)가 실행 접근 사전 검사를 통과하면 루트 장치를 찾고 마운트하는 처리를 초기 사용자 공간에 맡기는 경로로 간다. 이 검사에 실패하면 커널의 prepare_namespace() 경로가 장치 탐색을 기다리고 루트 장치를 해석해 마운트한다. 어느 경로를 택했는지에 따라 이후 실행 파일을 찾는 루트도 달라진다.[2][3]

rdinit=와 init=는 다른 단계에 적용된다

초기 rootfs의 실행 후보는 기본적으로 /init이며 rdinit=으로 바꾼다. kernel_init_freeable()은 이 경로를 init_eaccess()로 사전 검사한다. 검사에 실패하면 초기 후보를 해제하고 prepare_namespace()를 호출한다.[2]

그 뒤 kernel_init()은 다음 순서로 실행 후보를 선택한다.[2]

남아 있는 초기 후보(/init 또는 rdinit=) 실행
  성공 → 사용자 실행 이미지 준비 완료
  실패 → 다음 선택 단계

init=가 지정되었으면 실행
  성공 → 사용자 실행 이미지 준비 완료
  실패 → panic

CONFIG_DEFAULT_INIT가 비어 있지 않으면 실행 시도
/sbin/init → /etc/init → /bin/init → /bin/sh 순서로 시도
모두 실패 → panic

init=를 지정해도 초기 후보가 먼저 성공하면 그 경로가 선택된다. 또한 초기 후보가 사전 검사를 통과했지만 실제 exec에서 실패한 경우에는 prepare_namespace()를 다시 호출하지 않는다. 따라서 위 후보들을 항상 “최종 디스크 루트에서 차례로 찾는 이름”으로 해석할 수는 없다.[2]

선택한 파일의 실행은 공통 exec 경로로 이어진다

run_init_process()는 선택한 경로와 인자, 환경을 kernel_execve()에 전달한다. 파일의 형식을 판별하고 실행 이미지를 적재하는 일은 부팅 전용 ELF 로더가 아니라 공통 exec 경로가 맡는다. PID 1은 그대로 유지되고 실행 이미지가 교체된다.[2]

이후의 binfmt 핸들러 선택, ELF 세그먼트 매핑, 초기 스택과 사용자 모드 진입은 Linux의 ELF 로딩에서 다룬다. 일반 프로그램의 execve()와 PID 1의 첫 실행은 진입·복귀 경로가 다르지만, 실행 파일을 해석하는 공통 기반을 사용한다.

initramfs의 /init이 실제 루트를 준비한 뒤 다른 init으로 exec하는 것은 이후 사용자 공간의 처리다. 커널이 /init을 실행한 다음 반드시 /sbin/init도 실행하는 구조는 아니다.[4]

참고 문헌

  1. ↑ v6.12 init/initramfs.c, populate_rootfs, do_populate_rootfs, wait_for_initramfs.
  2. ↑ 2.0 2.1 2.2 2.3 2.4 v6.12 init/main.c, kernel_init_freeable, kernel_init.
  3. ↑ v6.12 init/do_mounts.c, prepare_namespace.
  4. ↑ Linux v6.12, ramfs-rootfs-initramfs.rst, What is initramfs? 절.