Linux에서 "initrd" 이미지를 로드하는 방법은 무엇입니까?

Linux에서 "initrd" 이미지를 로드하는 방법은 무엇입니까?

스타트업 과정을 이해하려고 노력했는데, 딱 한 가지 상상을 초월하는 게 있네요...

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

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

/boot가 다른 파티션은 아니지만 / 파티션 내에 존재하는 경우 부트로더가 "initrd" 이미지와 커널 이미지에 액세스하려면 SCSI 드라이버가 필요하지 않습니까? 이미지에 직접 액세스할 수 있다면 SCSI 드라이버가 필요한 이유는 무엇입니까?

답변1

Nighpher, 귀하의 질문에 답변해 드리겠습니다. 하지만 시작 프로세스에 대한 더 완전한 설명을 보려면 다음을 시도하십시오.이 기사의 출처는 IBM입니다..

좋아요, 해석을 위한 부트 로더로 GRUB 또는 GRUB2를 사용하고 있다고 가정합니다. 첫째, BIOS가 부트 로더를 로드하기 위해 디스크에 액세스할 때 유명한 13h 인터럽트에 저장된 디스크 액세스용 내장 루틴을 활용합니다. 부트로더(및 설정 중 커널)는 디스크에 액세스할 때 이러한 루틴을 사용합니다. BIOS는 프로세서의 리얼 모드(16비트 모드)에서 실행되므로 2^20바이트 이상의 RAM(2^16이 아닌 2^20, 리얼 모드의 각 주소는 모두 세그먼트 주소로 구성됨)을 주소 지정할 수 없습니다. *) 16 + 오프셋, 여기서 세그먼트 주소와 오프셋은 모두 16비트입니다. 참조Wikipedia의 "x86 메모리 분할"). 따라서 이러한 루틴은 1MiB 이상의 RAM에 액세스할 수 없으며 이는 심각한 제한이자 큰 불편입니다.

BIOS는 MBR(디스크의 처음 512바이트)에서 직접 부트로더 코드를 로드하고 실행합니다. GRUB를 사용하는 경우 이 코드는 GRUB 1단계입니다. 이 코드는 디스크 공간의 처음 32KiB(DOS 호환성 영역이라고 함) 또는 파일 시스템의 고정 주소에 있는 GRUB 단계 1.5를 로드합니다. 이를 수행하는 데 파일 시스템 구조에 대한 지식이 필요하지 않습니다. 1.5단계가 파일 시스템에 있더라도 "원시" 코드이고 RAM에 직접 로드되어 실행될 수 있기 때문입니다. Pixelbeat.org의 "PC용 GRUB 세부정보", 아래 이미지의 출처입니다. 디스크에서 RAM으로의 1.5단계 로딩은 BIOS 디스크 액세스 루틴을 활용합니다.

여기에 이미지 설명을 입력하세요.

1.5단계에는 파일 시스템 유틸리티가 포함되어 있어 파일 시스템에서 2단계를 읽을 수 있습니다(음, 여전히 BIOS 13h를 사용하여 디스크에서 RAM으로 읽지만 이제는 inode 등에 대한 파일 시스템 정보를 해독하고 디스크에서 원시 코드를 가져올 수 있습니다). 이전 BIOS는 디스크 주소 지정 모드의 제한으로 인해 전체 HD에 액세스하지 못할 수 있습니다. 즉, 스티그마 섹터 시스템을 사용할 수 있으며 디스크 공간의 처음 8GiB 이상을 주소 지정할 수 없습니다.http://en.wikipedia.org/wiki/Cylinder-head-sector.

두 번째 단계커널 로드RAM에 씁니다(다시 BIOS 디스크 유틸리티를 사용하여). 2.6+ 커널인 경우 initramfs도 컴파일하므로 로드할 필요가 없습니다. 오래된 커널인 경우 부트로더는 별도의 initrd 이미지를 메모리에 로드하여 커널이 이를 마운트하고 디스크에서 실제 파일 시스템을 마운트하기 위한 드라이버를 가져올 수 있도록 합니다.

문제는 커널(및 램디스크)의 무게가 1MiB를 초과하므로 이를 RAM에 로드하려면 커널을 처음 1MiB에 로드한 다음 보호 모드(32비트)로 점프하고 로드된 커널을 높은 위치로 이동해야 한다는 것입니다. 메모리(리얼 모드에서 첫 번째 1MiB 확보), 그런 다음 다시 리얼(16비트) 모드로 전환하여 디스크에서 첫 번째 1MiB(별도의 initrd 및 이전 커널인 경우)로 램디스크를 가져옵니다. 아마도 그럴 것입니다. 다시 보호(32비트) 모드로 전환하고 원래 위치에 둔 다음 리얼 모드로 돌아갈 수도 있습니다.https://stackoverflow.com/questions/4821911/does-grub-switch-to-protected-mode) 커널 코드를 실행합니다. 경고: 이 설명 부분의 완전성이나 정확성이 확실하지 않습니다.

지금,최종적으로 커널을 실행하면 커널이 이미 있고 부트로더를 통해 램디스크가 RAM에 로드됩니다., 따라서 커널은 ramdisk의 디스크 유틸리티를 사용하여 실제 루트 파일 시스템을 마운트하고 루트를 여기에 전송할 수 있습니다. ramfs 드라이버는 커널에 존재하므로 당연히 initramfs의 내용을 이해합니다.

답변2

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

예를 들어 고려해보세요. UEFI 부팅을 사용하면 실제로 UEFI 펌웨어는 EFI 파티션에 액세스하고 이를 읽고 중간 부트 로더 없이 거기에서 Linux 커널을 로드하는 방법을 이미 알고 있습니다. 이 경우 Linux 이미지는 루트 파티션과 분리되어 있으며 UEFI 펌웨어는 이에 액세스하기 위해 모든 외부 파일 시스템을 알 필요가 없습니다. 저는 "부팅" 이미지를 "루트" 파티션에서 분리하는 것이 합리적이라고 생각합니다. 다른 이유가 없다면 루트 파일 시스템 암호화를 설정할 때 이 작업이 필요합니다.

답변3

기록을 위해 부트로더가 이 작업을 수행하는 경우아니요initrd를 로드하는 것은 다른 부트로더를 테스트해 볼 가치가 있습니다.이것LILO가 올바르게 지정된 중간 크기 initrd(<4Mb, SATA SSD의 단일 ext4 rootfs, GPT)를 자동으로 무시하고 GRUB 2.00이 성공하는 경우.

시작 프로세스는 일반적인 절차로 빠르게 종료됩니다.

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)

관련 정보