Linux v6.18.37 · early userspace

Linux 초기 루트에서 실제 루트로 넘어가는 과정

initramfs 해제, 마운트 전환, PID 1의 프로그램 교체는 서로 다른 단계입니다.

처음의 rootfs와 initramfs

Linux v6.18.37의 초기 rootfs는 ramfs 또는 tmpfs 기반입니다. initramfs는 그 안에 풀리는 cpio 아카이브이고, 전통적인 initrd는 RAM 블록 장치에 파일시스템 이미지를 두는 방식입니다. 파일 이름에 initrd가 들어 있다고 해서 실제 형식까지 판단하지 않습니다.

init/main.c의 kernel_init_freeable은 아카이브 준비를 기다린 뒤 초기 사용자 프로그램의 접근 조건을 검사합니다. 기본 /init 또는 rdinit=으로 지정한 경로가 이 검사를 통과하면 초기 사용자 공간이 이후 준비를 맡습니다. 실패하면 ramdisk_execute_command를 지우고 prepare_namespace를 호출합니다. 이 접근 검사를 통과했다고 해서 뒤의 exec가 성공하는 것은 아닙니다.

chroot, pivot_root, switch_root는 같은 연산이 아닙니다

chroot는 경로 탐색의 루트를 바꾸지만 마운트 트리의 루트를 교체하거나 옛 파일시스템을 회수하는 연산은 아닙니다. pivot_root는 마운트 네임스페이스의 루트를 바꾸고 옛 루트를 put_old 아래로 옮깁니다. 권한뿐 아니라 새 루트의 마운트 지점 여부, put_old의 위치, 공유 마운트 전파 조건도 맞아야 합니다.

v6.18.37의 pivot_root 구현은 부모 마운트가 없는 절대 루트를 거부합니다. 이 버전의 초기 rootfs에 대한 제한을 모든 임시 파일시스템이나 앞으로의 커널 버전에 그대로 일반화하면 안 됩니다. initrd인지 initramfs인지만 보고 명령을 기계적으로 고르지 않습니다.

util-linux의 switch_root는 새 루트로 필요한 가상 파일시스템 마운트를 옮기고 새 init을 실행하는 사용자 공간 도구입니다. 기존 루트의 내용을 재귀적으로 지우므로 일반 셸에서 시험 삼아 실행할 명령이 아닙니다. 이 글은 실행 절차가 아니라 상태 전환을 설명합니다.

새 루트가 보인다고 해서 PID 1이 실행되는 것은 아닙니다

마운트에 성공해도 init의 실행 형식, 인터프리터, 동적 로더와 라이브러리가 새 루트에 없으면 프로그램 전환은 실패할 수 있습니다. run_init_process가 남기는 실행 시도 로그와 kernel_execve의 결과를 구분하고, 실패 코드와 실제 대상 경로를 함께 확인합니다.

exec는 현재 태스크의 실행 이미지를 바꾸므로 기존 PID를 유지합니다. PID 1에서 새 init을 시작하는 흐름과 자식 프로세스를 만들어 같은 파일을 실행하는 흐름은 같지 않습니다. 옛 루트를 참조하는 작업 디렉터리, 열린 파일과 남은 마운트도 별도로 확인해야 합니다.

각 단계의 성공 증거를 따로 확인합니다
  1. 아카이브 준비

    초기 rootfs의 파일과 실행 대상

  2. 마운트 전환

    새 루트와 마운트 관계

  3. 프로그램 전환

    기존 PID 1에서 exec 성공

출처와 연결

init 프로그램 실행 코드