리눅스는 어떻게 'initrd'이미지를로드합니까?


13

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

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

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

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

답변:


20

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의 내용을 이해할 수 있습니다.


bootlader가 보호 모드로 뛰어 드는 대신 커널을 덩어리로로드 할 수 없습니까? 그리고 1 MB .. 것을 확보의 필요성 것입니다 (죄송합니다 .. 그것을 이해하지 수는 ..)
rpthms

첫 번째 1MiB를 해제 할 필요는 다음과 같습니다. 부트 로더는 실제 모드에서만 하드 드라이브에 액세스하여 실제 모드 인 BIOS 유틸리티를 사용하여 하드 드라이브에 액세스 할 수 있습니다 (16 비트 인수에서 작동하고 16 비트 작업 사용). 리얼 모드는 처음 1MiB를 제외하고는 어떤 RAM도 보이지 않습니다. 그러나 kernel + initramfs를 RAM에로드해야하고 RAM에 ~ 5MiB 공간이 필요합니다. 해당 BIOS 유틸리티는 처음 1MiB에 5MiB를 넣을 수 없습니다. 따라서 부트 로더는 디스크에서 첫 번째 1MiB로 복사 한 다음 보호 모드로 이동하여 첫 번째 1Mb RAM에서 상위 RAM으로 이동해야합니다. 지금 더 명확합니까? :)
Boris Burkov

1
1 / 1.5 / 2 단계 전체가 그루브 레거시입니다.
psusi

1
@CMCDragonkai 예, stage2 부트 로더는 파일 시스템 (즉, /boot파티션)에 있습니다. 커널은이 시점에서로드되지 않습니다 . 최소한의 파일 시스템 드라이버를 통해 파일 /boot시스템 (예 : /boot/grub파일)의 stage2에 액세스하는 grub의 stage1.5 입니다. 커널은 /boot파티션에서도 읽을 수 있지만, grub2 코드를 실행하고 커널을로드 한 후 커널이 initramfs를 읽은 후에 나중에 발생합니다. 당신은 init.shinitramfs에 대해 말하고 있습니까? 그것은 /boot하드 드라이브의 파티션에 상주하고 , grub의 stage2는 그것을 RAM에 넣고 커널은 RAM에서 그것을 읽습니다.
Boris Burkov

1
Initrd 별도의 파일이어야했습니다. 더 새로운 다시 initramfs가 될 수있다 커널에 연결,하지만하지 않습니다 해야 - 또한 부트 로더에 의해 별도의 파일로로드 할 수 있습니다. initramfs 파일은 일련의 cpio 아카이브로 정의되므로 일부 부트 로더 (예 : iPXE)는 여러 개의 initramfs 파일을 허용하기도 합니다.이 파일은 차례로 메모리에로드됩니다. 또한 일부 Linux 배포판에서는 이전 기술과의 호환성을 위해 initrd 스타일 파일 이름을 사용하지만 실제 사용되는 기술은 이제 initramfs입니다.
telcoM

1

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

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


0

부트 로더가 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.