리눅스는 어떻게 ‘initrd’이미지를로드합니까? 루트 파일 시스템을 마운트하려면

부팅 과정을 이해하려고 노력했지만 머리 위로 넘어가는 것은 한 가지뿐입니다.

Linux 커널이 부팅되고 루트 파일 시스템 (/)이 마운트되면 프로그램을 실행할 수 있으며 추가 커널 모듈을 통합하여 추가 기능을 제공 할 수 있습니다. 루트 파일 시스템을 마운트하려면 특정 조건이 충족되어야합니다. 커널은 루트 파일 시스템이있는 장치 (특히 SCSI 드라이버)에 액세스하려면 해당 드라이버가 필요합니다. 커널은 파일 시스템을 읽는 데 필요한 코드 (ext2, reiserfs, romfs 등)도 포함해야합니다. 루트 파일 시스템이 이미 암호화되어 있다고 생각할 수도 있습니다. 이 경우 파일 시스템을 마운트하려면 비밀번호가 필요합니다.

초기 램 디스크 (initdisk 또는 initrd라고도 함)는 위에서 설명한 문제를 정확하게 해결합니다. Linux 커널은 작은 파일 시스템을 RAM 디스크에로드하고 실제 루트 파일 시스템이 마운트되기 전에 프로그램을 실행하는 옵션을 제공합니다. initrd의 로딩은 부트 로더 (GRUB, LILO 등)에 의해 처리됩니다. 부트 로더는 부트 매체에서 데이터를로드하기 위해 BIOS 루틴 만 필요합니다. 부트 로더가 커널을로드 할 수 있으면 초기 램 디스크도로드 할 수 있습니다. 특별한 드라이버는 필요하지 않습니다.

/ boot가 다른 파티션이 아니지만 / 파티션에있는 경우 부트 로더에 ‘initrd’이미지와 커널 이미지에 액세스하기 위해 SCSI 드라이버가 필요하지 않습니까? 이미지에 직접 액세스 할 수 있다면 왜 정확히 SCSI 드라이버가 필요합니까 ??



답변

Nighpher, 귀하의 질문에 답변하려고 노력할 것입니다. 그러나 부트 프로세스에 대한보다 포괄적 인 설명은 IBM 기사를 참조하십시오 .

그래, 설명을 위해 GRUB 또는 GRUB2를 부트 로더로 사용하고 있다고 가정합니다. 먼저 BIOS가 디스크에 액세스하여 부트 로더를로드 할 때 유명한 13 시간 인터럽트에 저장된 디스크 액세스를위한 내장 루틴을 사용합니다. 부트 로더 (및 설정 단계의 커널)는 디스크에 액세스 할 때 이러한 루틴을 사용합니다. BIOS는 프로세서의 실제 모드 (16 비트) 모드에서 실행되므로 2 ^ 20 바이트 이상의 RAM을 주소 지정할 수 없습니다 (실제 모드의 각 주소는 segment_address * 16 + offset으로 구성되므로 2 ^ 20은 2 ^ 16이 아닙니다) 세그먼트 주소와 오프셋이 모두 16 비트 인 경우 http://en.wikipedia.org/wiki/X86_memory_segmentation을 참조하십시오 . 따라서 이러한 루틴은 1MiB 이상의 RAM에 액세스 할 수 없으며 이는 엄격한 제한과 큰 불편입니다.

BIOS는 디스크의 첫 512 바이트 인 MBR에서 바로 부트 로더 코드를로드하여 실행합니다. GRUB을 사용하는 경우 해당 코드는 GRUB 단계 1입니다.이 코드는 GRUB 단계 1.5를로드합니다.이 단계는 DOS 호환성 영역이라고하는 디스크 공간의 첫 32KB에 또는 파일 시스템의 고정 주소에서 시작합니다. 파일 시스템을 이해할 필요가 없습니다. 심지어 1.5 단계는 파일 시스템에 있으며 “원시”코드이며 RAM에 직접로드하여 실행할 수 있습니다. http://www.pixelbeat.org/ docs / disk / . 디스크에서 RAM으로 stage1.5를로드하면 BIOS 디스크 액세스 루틴이 사용됩니다.

Stage1.5에는 파일 시스템 유틸리티가 포함되어 있기 때문에 파일 시스템에서 stage2를 읽을 수 있습니다 (물론 BIOS 13h를 사용하여 디스크에서 RAM으로 읽지 만 이제는 inode에 대한 파일 시스템 정보를 해독하여 원시 코드를 가져올 수 있음) 디스크). 구형 BIOS는 디스크 주소 지정 모드의 제한으로 인해 전체 HD에 액세스하지 못할 수 있습니다. 실린더 헤드 섹터 시스템을 사용하여 처음 8GiB 이상의 디스크 공간을 처리 할 수 ​​없습니다 ( http : //en.wikipedia). 조직 / 위키 / 실린더 헤드 부문 .

Stage2는 커널 을 RAM으로 로드합니다 (BIOS 디스크 유틸리티 사용). 커널 2.6 이상인 경우 initramfs도 컴파일되어 있으므로로드 할 필요가 없습니다. 이전 커널 인 경우 bootloader는 독립형 initrd 이미지를 메모리에로드하여 커널이이를 마운트하고 디스크에서 실제 파일 시스템을 마운트하기위한 드라이버를 얻을 수 있도록합니다.

문제는 커널 (및 램 디스크)의 무게가 1 MiB 이상이므로 RAM에로드하려면 커널을 먼저 1 MiB로로드 한 다음 보호 모드 (32 비트)로 점프하고로드 된 커널을 높은 메모리로 이동해야합니다 (무료) 실제 모드의 경우 첫 번째 1MiB), 다시 실제 (16 비트) 모드로 돌아가 디스크에서 첫 번째 1MiB (별도의 initrd 및 이전 커널 인 경우)로 램 디스크를 가져 오면 보호 된 (32 비트) 모드로 다시 전환 될 수 있습니다. 해당 위치에 넣고 가능하면 실제 모드로 돌아가거나 /programming/4821911/does-grub-switch-to-protected-mode로 돌아가 커널 코드를 실행하십시오. 경고 :이 부분 설명의 철저 성과 정확성에 대해 완전히 확신하지는 못합니다.

이제 커널을 마지막으로 실행할 때 이미 bootloader가 RAM과 RAM을 RAM에로드 했으므로 커널은 ramdisk의 디스크 유틸리티를 사용하여 실제 루트 파일 시스템을 마운트하고 루트를 피벗 할 수 있습니다. ramfs 드라이버는 커널에 있으므로 initramfs의 내용을 이해할 수 있습니다.


답변

특정 부트 로더가 지원하는 기능으로 요약됩니다. 예 : 결합 된 (부트 + 루트) 파티션의 특정 파일 시스템을 알 필요가 없습니다. 이 경우 부트 로더에서 작동하는 별도의 부트 파티션을 만들고 루트 파티션을 마운트하는 방법의 다른 복잡성은 커널과 부트 파티션에서 부팅 된 initrd 이미지에 남아 있습니다. Bootloader는 자체 드라이버를 사용하거나 BIOS 루틴을 사용하여 SCSI 장치 (및 사용 된 부트 로더에 따라 다른 장치)에 액세스하는 방법을 알고 있습니다. 또한 일부 파일 시스템 등을 읽는 방법을 알고 있습니다.

예를 들어보십시오. UEFI 부팅 방법. 실제로 UEFI 펌웨어는 EFI 파티션에 액세스하는 방법을 이미 알고 있으며 중간 부트 로더없이 Linux 커널을로드하고로드합니다. 이 경우 리눅스 이미지는 루트 파티션과 분리되어 존재하며 UEFI 펌웨어는 모든 이국적인 파일 시스템을 알 필요가 없습니다. “루트”파티션에서 “부팅”이미지를 분리하는 것이 큰 의미가 있다고 생각합니다. 다른 파일이 아닌 경우 루트 파일 시스템 암호화를 설정할 때 필요합니다.


답변

부트 로더가 initrd를로드 하지 않으면 다른 부트 로더를 테스트하는 것이 좋습니다. 내가 같은 상황에 단지 달아했습니다 와 GRUB 2.00 성공 LILO가 자동으로 적절하게 중간 크기의 initrd를 지정 (;은 SATA SSD에 단일 ext4에의 rootfs GPT <4MB의)을 무시했다.

부팅 과정은 전형적인

RAMDISK: Couldn't find valid RAM disk image starting at 0.
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,3)