Làm thế nào để Linux tải hình ảnh 'initrd'?


13

Tôi đã cố gắng để hiểu quá trình khởi động, nhưng chỉ có một điều đang diễn ra trong đầu tôi ..

Ngay khi nhân Linux đã được khởi động và hệ thống tệp gốc (/) được gắn kết, các chương trình có thể được chạy và các mô-đun hạt nhân tiếp theo có thể được tích hợp để cung cấp các chức năng bổ sung. Để gắn kết hệ thống tập tin gốc, phải đáp ứng một số điều kiện nhất định. Nhân cần các trình điều khiển tương ứng để truy cập vào thiết bị chứa hệ thống tệp gốc (đặc biệt là trình điều khiển SCSI). Nhân cũng phải chứa mã cần thiết để đọc hệ thống tệp (ext2, reiserfs, romfs, v.v.). Cũng có thể hình dung rằng hệ thống tập tin gốc đã được mã hóa. Trong trường hợp này, một mật khẩu là cần thiết để gắn kết hệ thống tập tin.

Ramdisk ban đầu (còn được gọi là initdisk hoặc initrd) giải quyết chính xác các vấn đề được mô tả ở trên. Nhân Linux cung cấp tùy chọn có một hệ thống tệp nhỏ được tải vào đĩa RAM và chạy các chương trình ở đó trước khi hệ thống tệp gốc thực sự được gắn kết. Việc tải initrd được xử lý bởi bộ tải khởi động (GRUB, LILO, v.v.). Bộ tải khởi động chỉ cần các thường trình BIOS để tải dữ liệu từ phương tiện khởi động. Nếu bộ tải khởi động có thể tải kernel, nó cũng có thể tải ramdisk ban đầu. Trình điều khiển đặc biệt là không cần thiết.

Nếu / boot không phải là một phân vùng khác, nhưng có trong phân vùng /, thì bộ tải khởi động không yêu cầu trình điều khiển SCSI, để truy cập hình ảnh 'initrd' và hình ảnh kernel? Nếu bạn có thể truy cập hình ảnh trực tiếp, vậy tại sao chính xác chúng ta cần trình điều khiển SCSI ??

Câu trả lời:


20

Nighpher, tôi sẽ cố gắng trả lời câu hỏi của bạn, nhưng để mô tả toàn diện hơn về quy trình khởi động, hãy thử bài viết của IBM .

Ok, tôi giả sử rằng bạn đang sử dụng GRUB hoặc GRUB2 làm bộ tải khởi động để giải thích. Trước hết, khi BIOS truy cập vào đĩa của bạn để tải bộ tải khởi động, nó sử dụng các thói quen tích hợp sẵn để truy cập đĩa, được lưu trữ trong ngắt 13h nổi tiếng. Bootloader (và kernel ở giai đoạn thiết lập) sử dụng các thường trình đó khi chúng truy cập đĩa. Lưu ý rằng BIOS chạy ở chế độ xử lý ở chế độ thực (16 bit), do đó, nó không thể xử lý nhiều hơn 2 ^ 20 byte RAM (2 ^ 20 chứ không phải 2 ^ 16 vì mỗi địa chỉ trong chế độ thực bao gồm phân đoạn_address * 16 + offset , trong đó cả địa chỉ phân đoạn và phần bù là 16 bit, hãy xem http://en.wikipedia.org/wiki/X86_memory_seributionation ). Do đó, các thói quen này không thể truy cập nhiều hơn 1 MiB RAM, đây là một hạn chế nghiêm ngặt và bất tiện lớn.

BIOS tải mã bộ tải khởi động ngay từ MBR - 512 byte đầu tiên của đĩa của bạn và thực thi nó. Nếu bạn đang sử dụng GRUB, mã đó là GRUB giai đoạn 1. Mã đó tải GRUB giai đoạn 1.5, được đặt trong 32 KiB đầu tiên của không gian đĩa, được gọi là vùng tương thích DOS hoặc từ một địa chỉ cố định của hệ thống tệp. Không cần hiểu hệ thống tệp để thực hiện việc này, vì ngay cả giai đoạn 1.5 nằm trong hệ thống tệp, đó là mã "thô" và có thể được tải trực tiếp vào RAM và được thực thi: http://www.pixelbeat.org/ tài liệu / đĩa / . Tải giai đoạn1.5 từ đĩa vào RAM sử dụng các thói quen truy cập đĩa BIOS.

nhập mô tả hình ảnh ở đây

Stage1.5 chứa các tiện ích hệ thống tập tin, để nó có thể đọc giai đoạn 2 từ hệ thống tập tin (tốt, nó vẫn sử dụng BIOS 13h để đọc từ đĩa sang RAM, nhưng bây giờ nó có thể giải mã thông tin hệ thống tập tin về inodes, v.v. đĩa). Các BIOS cũ hơn có thể không thể truy cập toàn bộ HD do các giới hạn trong chế độ địa chỉ đĩa của chúng - chúng có thể sử dụng hệ thống Xi lanh-Đầu-Khu vực, không thể xử lý nhiều hơn 8 GiB không gian đĩa đầu tiên: http: //en.wikipedia. org / wiki / Xi lanh-đầu-ngành .

Stage2 tải kernel vào RAM (một lần nữa, sử dụng các tiện ích đĩa BIOS). Nếu đó là kernel 2.6+, nó cũng có initramfs được biên dịch bên trong, do đó không cần tải nó. Nếu đó là kernel cũ hơn, bootloader cũng tải hình ảnh initrd độc lập vào bộ nhớ, để kernel có thể gắn kết nó và lấy trình điều khiển để gắn hệ thống tập tin thực từ đĩa.

Vấn đề là kernel (và ramdisk) nặng hơn 1 MiB, do đó để tải chúng vào RAM, bạn phải tải kernel lên 1 MiB đầu tiên, sau đó chuyển sang chế độ được bảo vệ (32 bit), di chuyển kernel đã tải sang bộ nhớ cao (miễn phí 1 MiB đầu tiên cho chế độ thực), sau đó quay lại chế độ thực (16 bit) một lần nữa, đưa ramdisk từ đĩa sang 1 MiB đầu tiên (nếu đó là một initrd riêng và kernel cũ hơn), có thể chuyển sang chế độ được bảo vệ (32 bit), đặt nó ở nơi nó thuộc về, có thể quay lại chế độ thực (hoặc không: /programming/4821911/does-grub-switch-to-protected-mode ) và thực thi mã hạt nhân. Cảnh báo: Tôi không hoàn toàn chắc chắn về tính kỹ lưỡng và chính xác của phần mô tả này.

Bây giờ, khi cuối cùng bạn chạy kernel, bạn đã có nó và ramdisk được tải vào RAM bằng bootloader , vì vậy kernel có thể sử dụng các tiện ích đĩa từ ramdisk để gắn kết hệ thống tập tin gốc thực của bạn và xoay trục gốc vào nó. Trình điều khiển ramfs có mặt trong kernel, vì vậy nó có thể hiểu nội dung của initramfs, tất nhiên.


Bootlader không thể tải kernel trong chunk, thay vì nhảy vào chế độ được bảo vệ ?? Và nhu cầu giải phóng 1 MB đó là gì .. (Xin lỗi .. không thể hiểu điều đó ..)
rpthms

Nhu cầu giải phóng 1MiB đầu tiên như sau: bootloader chỉ có thể truy cập ổ cứng của bạn ở chế độ thực, khiến nó truy cập nó bằng các tiện ích BIOS, ở chế độ thực (chúng hoạt động trên các đối số 16 bit và sử dụng các hoạt động 16 bit). Chế độ thực không thấy RAM nào ngoại trừ 1 MiB đầu tiên. Nhưng bạn cần tải kernel + initramfs vào RAM và chúng chiếm ~ 5 không gian MiB trong RAM. Những tiện ích BIOS đó sẽ không thể ép 5 MiB vào 1 MiB đầu tiên. Vì vậy, bootloader phải sao chép chúng từ đĩa sang 1 MiB đầu tiên, sau đó chuyển sang chế độ được bảo vệ và chuyển chúng từ RAM 1Mb đầu tiên sang RAM cao hơn. Bây giờ có rõ ràng hơn không? :)
Boris Burkov

1
Toàn bộ giai đoạn 1 / 1.5 / 2 là di sản grub.
psusi

1
@CMCDragonkai Có, bootloader giai đoạn 2 nằm trong hệ thống tập tin (cụ thể là trong /bootphân vùng). Kernel không được tải tại thời điểm này - đó là giai đoạn1.5, người đang truy cập vào giai đoạn 2 trong /boothệ thống tệp (ví dụ như trong /boot/grubtệp) thông qua trình điều khiển hệ thống tệp tối giản của nó. Kernel cũng sẽ có thể đọc từ /bootphân vùng, nhưng nó sẽ xảy ra sau đó, sau khi thực thi mã grub2 và tải kernel và sau khi kernel đọc initramfs. Bạn đang nói về init.shinitramfs? Nó nằm trong /bootphân vùng ổ cứng của bạn, sau đó, giai đoạn 2 của grub đặt nó vào RAM và Kernel đọc nó từ RAM.
Boris Burkov

1
Ban đầu phải là một tập tin riêng biệt. Initramfs mới hơn có thể được liên kết với hạt nhân, nhưng nó không phải là - nó cũng có thể được nạp như một tập tin riêng biệt bởi bootloader. Vì tệp initramfs được định nghĩa là một chuỗi lưu trữ cpio, một số bộ tải khởi động (ví dụ iPXE) thậm chí cho phép nhiều tệp initramfs, lần lượt sẽ được tải vào bộ nhớ. Ngoài ra, một số bản phân phối Linux sử dụng tên tệp kiểu initrd để tương thích ngược, mặc dù công nghệ thực tế được sử dụng hiện là initramfs.
telcoM

1

Tôi tin rằng, nó nắm rõ những tính năng cụ thể của bộ tải khởi động hỗ trợ. Ví dụ. nó không phải biết hệ thống tập tin cụ thể của phân vùng (boot + root) kết hợp của bạn. Trong trường hợp đó, bạn chỉ cần tạo một phân vùng khởi động riêng trong điều kiện nó hoạt động với bộ tải khởi động của bạn và bất kỳ sự phức tạp nào khác về cách gắn phân vùng gốc của bạn được để lại trên kernel và hình ảnh initrd được khởi động từ phân vùng khởi động. Bootloader biết cách truy cập các thiết bị SCSI (và các thiết bị khác nữa, tùy thuộc vào bộ tải khởi động nào được sử dụng) bằng cách sử dụng trình điều khiển riêng của nó hoặc bằng cách sử dụng các thường trình BIOS. Hơn nữa, nó biết cách đọc một số hệ thống tập tin, v.v.

Hãy xem xét ví dụ. Cách khởi động của UEFI, trong đó phần mềm UEFI thực sự đã biết cách truy cập phân vùng EFI, đọc nó và tải kernel linux từ đó mà không cần bộ tải khởi động trung gian. Trong trường hợp đó, hình ảnh linux sống tách biệt với phân vùng gốc và phần sụn UEFI không phải biết tất cả các hệ thống tập tin kỳ lạ để truy cập nó. Tôi tin rằng việc tách hình ảnh "boot" khỏi phân vùng "root" có ý nghĩa lớn. Nếu không phải vì bất cứ điều gì khác thì đây là điều cần thiết khi thiết lập mã hóa hệ thống tập tin gốc.


0

Chỉ dành cho bản ghi, nếu bộ tải khởi động không tải initrd thì đáng để kiểm tra bộ tải khởi động khác; Tôi vừa gặp phải một tình huống như thế này khi LILO âm thầm bỏ qua một initrd được chỉ định đúng có kích thước trung bình (<4Mb; root ext4 đơn trên SSD SATA; GPT) và GRUB 2.00 đã thành công.

Quá trình khởi động kết thúc nhanh chóng với một điển hình

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.