Tại sao tôi cần initramfs?


16

Tôi thấy rằng nếu tôi chọn jff hoặc sd làm hệ thống tệp (chứ không phải initramfs), kích thước kernel rất nhỏ (1,4 MB so với initramfs-3,4MB). Nó cho thấy rằng initramfs chiếm không gian rộng lớn. Vì vậy, id tôi hoàn toàn có thể loại bỏ nó Tôi sẽ có kernel rất nhỏ, đó là những gì tôi muốn.

Vì vậy, câu hỏi cơ bản xuất hiện trong tâm trí của tôi là: tại sao tôi cần initramfs? một hạt nhân linux không thể khởi động mà không có bất kỳ hệ thống tập tin ban đầu?

Ứng dụng cuối cùng của tôi sẽ chỉ thực hiện tính toán và giao tiếp - không có ý kiến ​​gì cả. Vì vậy, một hệ điều hành không có hệ thống tệp có ý nghĩa - ít nhất là cho ứng dụng của tôi.


2
Bạn không thể làm mà không có initramfs. Có thể thực hiện mà không cần tệp initramfs bổ sung, nhưng bất kể bạn làm gì, kernel bao gồm chính nó trống hay không. Vì vậy, tôi không hiểu câu hỏi của bạn - bạn đang nói về phân phối nào? Làm thế nào bạn xây dựng hạt nhân của bạn? Bạn có thể cung cấp tập tin kernel .config không? Đây là rất quan trọng. Tôi nghi ngờ bản phân phối của bạn đang biên dịch trực tiếp các initramfs của nó vào kernel - và do đó điền vào các initramfs trống mà nó chứa - nhưng tôi không thể biết dựa trên thông tin bạn đã cung cấp.
mikeerv

2
@mikeerv, rõ ràng là một initramfs tích hợp nhưng trống / không sử dụng không được tính.
psusi

Chà, @psusi các tài liệu kernel không đồng ý. Và tôi chỉ rất kiên quyết về điều đó bởi vì không cần phải có bất kỳ bí ẩn nào - chỉ là /root- đó là nó. Điều duy nhất nó làm khác là switch_rootnhưng ngay cả điều đó, với các biện pháp phòng ngừa thích hợp được thực hiện với các mô-đun hạt nhân được tải nhất định, có thể được thực hiện bất cứ lúc nào. Initramfs không gì khác hơn là một hình ảnh đĩa - tràn đầy hoặc không, nó ở đó. Và bạn không bao giờ thiếu nó - đó là gốc rễ của bạn. Nó không nên là một bí ẩn, là những gì tôi nghĩ, và tôi không thích tất cả những nhầm lẫn không cần thiết xung quanh nó.
mikeerv

2
@mikeerv, không, / root là thư mục chính cho người dùng root. Các rootfs là /, sau đó có root thực sự được gắn trên đầu của nó. Bạn chỉ đang tranh luận về ngữ nghĩa. Đối với mục đích của cuộc thảo luận này, không có initramfs có nghĩa là không có tệp trên đĩa, trình tải khởi động của bạn phải tải và chuyển đến kernel.
psusi

Đó là sự thật, tôi chỉ sử dụng / root cho rõ ràng, nhưng tôi sẽ cung cấp cho bạn cái đó. Nhưng không, chúng không phải là ngữ nghĩa, chúng là cơ chế cơ bản của nhân linux của bạn. Đây là những điều cơ bản. Hãy cố gắng để có được chúng đúng.
mikeerv

Câu trả lời:


10

Sự gia tăng kích thước của việc có một initramfs không phải do trình điều khiển ramfs (nó chỉ là một vài kB và dù sao cũng cần cho những thứ khác) mà là do chính initramfs. Các initramfs chứa các chương trình cần thiết để lắp ráp và gắn kết hệ thống tập tin gốc thực sự.

Initramfs làm cho nó dễ dàng hơn rất nhiều, và trong một số trường hợp có thể (ví dụ như được mã hóa /), để khởi động hệ thống. Chúng tôi khuyên bạn nên giữ nó trên phần cứng kiểu PC với nhiều thiết bị ngoại vi có thể cắm được. Mặt khác, rất có ý nghĩa để khởi động một thiết bị nhúng mà không có bất kỳ initramfs nào, với một kernel chỉ hỗ trợ cấu hình phần cứng cụ thể mà nó được tạo ra.

Hạt nhân tất nhiên cần phải khởi động vào một hệ thống tập tin: phải có một số cách để nó tải bất kỳ ứng dụng nào bạn muốn chạy. Nếu bạn không chạy bất cứ thứ gì, thì bạn cũng có thể tắt máy.

Nếu bạn không muốn sử dụng initramfs, chỉ cần nói với bộ tải khởi động của bạn không vượt qua. Tất nhiên, cũng không bao gồm một trong đầu ra của việc xây dựng kernel, làm thế nào điều này xảy ra nếu tất cả phụ thuộc vào kiến ​​trúc và bootloader: chẳng hạn, vmlinuxbzImagekhông bao gồm initramfs (tương ứng là kernel thô và nén ), nhưng uImage(đối với U-Boot) gói cả kernel và initramfs nếu có.

(Về mặt kỹ thuật, như các ghi chú mikeerv , luôn có một initramfs - nhưng theo mặc định, đó là một kho lưu trữ 134 byte trống rỗng. quá trình xây dựng của bạn và chứa các công cụ mà sau đó được sử dụng để gắn kết hệ thống tập tin gốc.)

Xin lưu ý, một initramfs có thể là một cách hợp lý để tạo ra một hệ thống ứng dụng duy nhất không có dữ liệu liên tục: đặt tất cả ứng dụng của bạn vào initramfs, khởi động nó và giữ nó. Điều này giúp tổ chức lưu trữ hoặc hình ảnh khởi động liên tục của bạn dễ dàng hơn (tất cả những gì bạn cần là kernel và initramfs, có thể được đóng gói). Tuy nhiên, có một số nhược điểm của phương pháp này: tất cả dữ liệu trong initramfs sẽ được lưu trữ trong RAM vĩnh viễn và bạn không thể dễ dàng sửa đổi các tệp trong ảnh khởi động, bạn phải xây dựng lại kho lưu trữ.


Nếu bạn đang sử dụng kernel linux 2.6 hoặc mới hơn, bạn có initramfs. Cho dù bạn có sử dụng hình ảnh initramfs thứ cấp hay không, theo thông lệ, là một vấn đề khác, nhưng initramfs không phải là tùy chọn.
mikeerv

2
@mikeerv Bạn có một cái, vâng. Nhưng một initramfs trống là đậu phộng. Nó không phải được sử dụng (yêu cầu nó chứa đủ các chương trình để gắn root thực sự, giúp tăng kích thước theo cách không đáng kể trong một hệ thống nhúng thông thường).
Gilles 'SO- đừng trở nên xấu xa'

Đậu phộng bắt buộc nào. Và tôi không biết khi tôi nói khác! Người hỏi đã yêu cầu thông tin về cách loại bỏ nó như một hệ thống tập tin - điều này là không thể.
mikeerv

Và vâng, nó phải được sử dụng - không có initramfs thì không có root. Không bao giờ.
mikeerv

8

Từ LFS :

Mục đích duy nhất của initramfs là gắn kết hệ thống tập tin gốc. Các initramfs là một tập hợp đầy đủ các thư mục mà bạn sẽ tìm thấy trên một hệ thống tập tin gốc bình thường. Nó được gói vào một kho lưu trữ cpio duy nhất và được nén bằng một trong nhiều thuật toán nén.

...

Chỉ có bốn lý do chính để có một initramfs trong môi trường LFS: tải rootfs từ mạng, tải nó từ một khối logic LVM, có một rootfs được mã hóa trong đó cần có mật khẩu hoặc để thuận tiện cho việc xác định rootfs là một NHÃN hoặc UUID. Bất cứ điều gì khác thường có nghĩa là kernel không được cấu hình đúng.

...

Đối với hầu hết các bản phân phối, các mô-đun hạt nhân là lý do lớn nhất để có một initramfs. Trong một bản phân phối chung, có nhiều ẩn số như kiểu hệ thống tệp và bố trí đĩa. Theo một cách nào đó, điều này trái ngược với LFS nơi các khả năng và bố cục hệ thống được biết đến và một hạt nhân tùy chỉnh thường được xây dựng. Trong tình huống này, một initramfs hiếm khi cần thiết.

Một nguồn khác www.kernel.org

Bên cạnh đó, có rất nhiều hệ thống Linux giống như các bộ định tuyến không sử dụng initramfs.


1

Bạn cần một initramfs cho các thiết lập phức tạp hơn, chẳng hạn như khởi động mạng hoặc lvm hoặc đột kích, vì chúng yêu cầu một số tiện ích chế độ người dùng để định cấu hình quyền truy cập vào fs gốc. Đối với một phân vùng thông thường, đơn giản trên đĩa, miễn là bạn có trình điều khiển đĩa được tích hợp trong kernel và chỉ định đối số gốc bằng đường dẫn thiết bị thay vì UUID, thì bạn có thể thực hiện mà không cần initramfs. Tất nhiên, đường dẫn thiết bị có thể thay đổi, tùy thuộc vào thiết bị cắm và phát (tức là usb) mà bạn đã kết nối, hoặc thậm chí đơn giản là phương sai thời gian ngẫu nhiên, đó là lý do tại sao khá nhiều người sử dụng uuids và initramfs để đảm bảo độ tin cậy.


Điều này cũng không chính xác.
mikeerv

6
@mikeerv, bình luận của bạn là vô ích. Nếu bạn sẽ tuyên bố điều đó, bạn cần phải giải thích tại sao.
psusi

Tôi đã thực hiện, hay đúng hơn là, tài liệu kernel bao gồm 99% câu trả lời của tôi.
mikeerv

@mikeerv, đúng rồi. Tôi đang chạy Gentoo linux trong nhiều năm nay mà không có initramfs.
Tim

1

Đây là một câu hỏi cũ nhưng dường như vẫn chưa có câu trả lời được chấp nhận vì vậy tôi sẽ ném nó ra khỏi đó (tôi không phải là chuyên gia ở đây, tôi đang cố gắng tự mình tìm ra câu hỏi này.)

Từ https://www.kernel.org/doc/Documentation/early-userspace/README (tất cả các cách ở phía dưới cho biết nó chưa được cập nhật từ năm 2004.)

Kernel hiện có 3 cách để gắn hệ thống tập tin gốc:

a) tất cả các trình điều khiển thiết bị và hệ thống tập tin cần thiết được biên dịch vào kernel, không có initrd. init / main.c: init () sẽ gọi chuẩn bị_namespace () để gắn kết hệ thống tập tin gốc cuối cùng, dựa trên tùy chọn root = và init = để chạy một số nhị phân init khác được liệt kê ở cuối init / main.c: init ().

b) một số trình điều khiển thiết bị và hệ thống tập tin được xây dựng dưới dạng các mô-đun và được lưu trữ trong một initrd. Các initrd phải chứa một '/ linuxrc' nhị phân được cho là để tải các mô-đun trình điều khiển này. Cũng có thể gắn hệ thống tập tin gốc cuối cùng thông qua linuxrc và sử dụng tòa nhà p Pivot_root. Các initrd được gắn kết và được thực thi thông qua chuẩn bị_namespace ().

c) sử dụng initramfs. Cuộc gọi đến Chuẩn bị_namespace () phải được bỏ qua. Điều này có nghĩa là một nhị phân phải làm tất cả các công việc. Nhị phân đã nói có thể được lưu trữ vào initramfs thông qua sửa đổi usr / gen_init_cpio.c hoặc thông qua định dạng initrd mới, một kho lưu trữ cpio. Nó phải được gọi là "/ init". Nhị phân này chịu trách nhiệm thực hiện tất cả những điều mà Chuẩn bị_namespace () sẽ làm.

Để duy trì khả năng tương thích ngược, nhị phân / init sẽ chỉ chạy nếu đi qua kho lưu trữ cpio initramfs. Nếu đây không phải là trường hợp, init / main.c: init () sẽ chạy chuẩn bị_namespace () để gắn gốc cuối cùng và thực thi một trong các nhị phân init được xác định trước.

Đối với những gì nó có giá trị, tôi tin rằng các thiết bị / bản phân phối như Raspberry Pi, v.v. không sử dụng initramfs; trong một số trường hợp, các hạt nhân là trên phân vùng root (gắn bằng bootloader trong đó có fs cần thiết mô-đun.) Trong trường hợp khác, nơi mà hạt nhân là ví dụ về một /bootphân vùng, initramfs trên phân vùng tương tự có thể được truy cập trực tiếp trước khi gắn các rootfs như những người khác đã nêu.

Trong một số trường hợp, initramfs có thể được xây dựng trong cùng một tệp với kernel nhưng điều này không phải lúc nào cũng đúng. (a) dường như nói rõ rằng trong một số trường hợp, initramfs là không cần thiết.


0

Tôi thấy giải thích sau rõ ràng hơn,

initramfslà một hệ thống tập tin gốc được nhúng vào kernel và được tải ở giai đoạn đầu của quá trình khởi động. Nó là sự kế thừa của initrd. Nó cung cấp không gian người dùng sớm có thể thực hiện những điều mà kernel không thể tự làm một cách dễ dàng trong quá trình khởi động.

Sử dụng initramfs là tùy chọn. Theo mặc định, kernel khởi tạo phần cứng bằng trình điều khiển tích hợp, gắn kết phân vùng gốc đã chỉ định, tải hệ thống init của bản phân phối Linux đã cài đặt. Hệ thống init sau đó tải các mô-đun bổ sung và khởi động các dịch vụ cho đến khi cuối cùng cho phép bạn đăng nhập. Đây là một hành vi mặc định tốt và đủ cho nhiều người dùng. initramfs dành cho người dùng có yêu cầu nâng cao; cho những người dùng cần thực hiện mọi việc càng sớm càng tốt, ngay cả trước khi phân vùng gốc được gắn kết.

Dưới đây là một số ví dụ về những gì bạn có thể làm với initramfs:

  • Gắn kết phân vùng gốc (đối với các phân vùng được mã hóa, logic và đặc biệt khác);
  • Cung cấp một vỏ cứu hộ tối giản (nếu có sự cố);
  • Tùy chỉnh quy trình khởi động (ví dụ: in thông báo chào mừng, khởi động, v.v.);
  • Tải các mô-đun (ví dụ trình điều khiển bên thứ ba);
  • Bất cứ điều gì hạt nhân không thể làm (miễn là bạn có thể làm điều đó trong không gian người dùng, ví dụ: bằng cách thực hiện các lệnh). Nếu bạn không có yêu cầu nâng cao, bạn không cần initramfs.

-1

Bất kể bạn làm gì, bạn có initramfs. Không có gì làm mà không có nó - đó là hệ thống tập tin duy nhất áp đặt cho bạn. Từ kernel.org :

Rootfs là gì?

Rootfslà một phiên bản đặc biệt của ramfs(hoặc tmpfs, nếu được bật), luôn có trong 2.6 hệ thống. Bạn không thể ngắt kết nốirootfs vì lý do tương tự bạn không thể giết tiến trình init; thay vì có mã đặc biệt để kiểm tra và xử lý một danh sách trống, hạt nhân nhỏ hơn và đơn giản hơn để đảm bảo các danh sách nhất định không thể trở nên trống rỗng.

Hầu hết các hệ thống chỉ gắn kết hệ thống tập tin khác rootfsvà bỏ qua nó. Lượng không gian mà một bản ramfs trống chiếm rất ít.

Nếu * CONFIG_TMPFS * được bật, rootfssẽ sử dụng tmpfsthay vì ramfstheo mặc định. Để buộc ramfs, thêm "rootfstype=ramfs"vào dòng lệnh kernel.

Initramfs là gì?

Tất cả các nhân Linux Linux chứa một"cpio"kho lưu trữ định dạng đượcnén, được trích xuất rootfskhi kernel khởi động. Sau khi giải nén, kiểm tra hạt nhân để xem nếurootfscó chứa một tập tin"init" , và nếu như vậy nó thực thi nó như PID 1. Nếu tìm thấy, nàyinitquá trình chịu trách nhiệm về việc đưa hệ thống phần còn lại của con đường lên, bao gồm định vị và gắn các thiết bị gốc thực ( nếu có). Nếurootfskhông chứainitchương trình sau khicpiolưu trữnhúngđược trích xuất vào nó, kernel sẽ chuyển sang mã cũ hơn để xác định vị trí và gắn kết phân vùng gốc, sau đó thực hiện một số biến thể trong/sbin/initsố đó.

Tất cả điều này khác với initrd cũ theo nhiều cách:

  • Các initrd cũ luôn là một tệp riêng biệt, trong khi kho lưu trữ initramfs được liên kết với hình ảnh hạt nhân linux. (Thư mục linux - * / usr được dành để tạo kho lưu trữ này trong quá trình xây dựng.)

  • Tệp initrd cũ là một hình ảnh hệ thống tập tin được nén (ở một số định dạng tệp, chẳng hạn như ext2, cần một trình điều khiển được tích hợp trong kernel), trong khi kho lưu trữ initramfs mới là một kho lưu trữ cpio được nén (như chỉ đơn giản là tar, xem cpio (1) và Tài liệu / không gian người dùng sớm / bộ đệm-format.txt). Mã trích xuất cpio của kernel không chỉ cực kỳ nhỏ mà còn là __init văn bản và dữ liệu có thể bị loại bỏ trong quá trình khởi động.

  • Chương trình được chạy bởi initrd cũ (được gọi là / initrd, không phải / init) đã thực hiện một số thiết lập và sau đó quay trở lại kernel, trong khi chương trình init từ initramfs dự kiến ​​sẽ không quay trở lại kernel. (Nếu / init cần tắt điều khiển, nó có thể vượt qua / với một thiết bị gốc mới và thực hiện một chương trình init khác. Xem tiện ích switch_root, bên dưới.)

  • Khi chuyển đổi một thiết bị gốc khác, initrd sẽ p Pivot_root và sau đó vượt qua ramdisk. Nhưng initramfs là rootfs: bạn không thể root pfs_root, cũng không ngắt kết nối nó. Thay vào đó, hãy xóa mọi thứ ra khỏi rootfs để giải phóng không gian (find -xdev / -exec rm '{}' ';'), vượt qua rootfs bằng root mới (cd / newmount; mount --move. /; Chroot.), đính kèm stdin / stdout / stderr vào new / dev / console và thực thi init mới.

Vì đây là một quá trình khó khăn đáng chú ý (và liên quan đến việc xóa các lệnh trước khi bạn có thể chạy chúng), gói klibc đã giới thiệu một chương trình trợ giúp (utils / run_init.c) để làm tất cả điều này cho bạn. Hầu hết các gói khác (như busybox) đã đặt tên cho lệnh này là "switch_root".

Khởi tạo dân cư:

Quá trình xây dựng kernel 2.6 luôn tạo ra một kho lưu trữ initramfs định dạng được nén và liên kết nó với tệp nhị phân kernel. Theo mặc định, kho lưu trữ này trống (tiêu thụ 134 byte trên x86).

Tùy chọn cấu hình CONFIG_INITRAMFS_SOURCE (trong Cài đặt chung trong menuconfig và sống trong usr / Kconfig) có thể được sử dụng để chỉ định nguồn cho kho lưu trữ initramfs, sẽ tự động được tích hợp vào nhị phân kết quả. Tùy chọn này có thể trỏ đến một kho lưu trữ cpio đã được nén, một thư mục chứa các tệp sẽ được lưu trữ hoặc một đặc tả tệp văn bản, ví dụ như sau:

  dir /dev 755 0 0
  nod /dev/console 644 0 0 c 5 1
  nod /dev/loop0 644 0 0 b 7 0
  dir /bin 755 1000 1000
  slink /bin/sh busybox 777 0 0
  file /bin/busybox initramfs/busybox 755 0 0
  dir /proc 755 0 0
  dir /sys 755 0 0
  dir /mnt 755 0 0
  file /init initramfs/init.sh 755 0 0

Chạy "usr / gen_init_cpio" (sau khi xây dựng kernel) để nhận thông báo sử dụng ghi lại định dạng tệp ở trên.

Một lợi thế của tệp cấu hình là không cần truy cập root để đặt quyền hoặc tạo các nút thiết bị trong kho lưu trữ mới. (Lưu ý rằng hai mục nhập "tệp" ví dụ này sẽ tìm thấy các tệp có tên "init.sh" và "busybox" trong thư mục có tên "initramfs", trong thư mục linux-2.6. *. Xem Tài liệu / không gian người dùng sớm / README để biết biết thêm chi tiết.)

Hạt nhân không phụ thuộc vào các công cụ cpio bên ngoài. Nếu bạn chỉ định một thư mục thay vì tệp cấu hình, cơ sở hạ tầng xây dựng của kernel sẽ tạo một tệp cấu hình từ thư mục đó (usr / Makefile gọi scripts / gen_initramfs_list.sh) và tiến hành đóng gói thư mục đó bằng tệp cấu hình (bằng cách cung cấp cho nó usr / gen_init_cpio, được tạo từ usr / gen_init_cpio.c). Mã tạo cpio thời gian xây dựng của kernel hoàn toàn khép kín và trình trích xuất thời gian khởi động của kernel cũng (rõ ràng) là khép kín.


1
Bạn có thể khởi động mà không cần initramfs. Câu trả lời của bạn thể hiện trên giá trị của initramfs, nhưng điều đó không áp dụng cho các hệ thống nhúng thông thường và ngay cả trên máy tính để bàn hoặc máy chủ nơi khuyến nghị sử dụng initramfs, điều đó không bắt buộc.
Gilles 'SO- đừng trở nên xấu xa'

@Gilles - không bạn không thể. Bất kể bạn làm gì, bạn đều có initramfs. Nó được biên dịch vào kernel - ngay bây giờ, kernel của bạn, kernel của tôi, tất cả kernel của chúng tôi. Đọc tài liệu kernel - toàn bộ bài viết của tôi là một bản sao-dán. Bạn không chính xác. Làm thế nào bạn có thể tranh chấp các tài liệu chính thức?
mikeerv

1
Tôi không tranh chấp tài liệu chính thức, tôi tranh luận về kết luận mà bạn rút ra từ đó. Bạn đang đọc tài liệu giải thích cách sử dụng initramfs. Không nơi nào nói rằng initramfs phải được sử dụng.
Gilles 'SO- đừng trở nên xấu xa'

@Gilles Nếu điều này là không đủ: " Tôi có thể làm tốt hơn. Trên đây là một tìm kiếm web 2 hoặc 3 phút.
mikeerv

3
Tôi đã đọc tài liệu. Tôi làm điều này để kiếm sống. Đó không phải là vấn đề quan điểm. Luôn có một initramfs, nhưng nó không nhất thiết được sử dụng để khởi động. Tôi không thể tìm thấy một lời giải thích hợp lý về cấu trúc hạt nhân cho trường hợp đó, có lẽ bởi vì đó là trường hợp kinh điển được cho là không đảm bảo giải thích. Logic chính là trong do_mounts.c- cụ thể prepare_namespace, trong đó saved_root_nameđi kèm với root=đối số dòng lệnh.
Gilles 'SO- đừng trở nên xấu xa'
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.