Cấu hình, biên dịch và cài đặt kernel Linux tùy chỉnh


38

Tôi muốn thử sử dụng một kernel khác với kernel được cung cấp bởi distro của tôi - từ một nơi khác hoặc theo tùy chỉnh của tôi. Đây là khó khăn hay nguy hiểm?

Tôi bắt đầu từ đâu?

Câu trả lời:


51

Xây dựng kernel tùy chỉnh có thể tốn thời gian - chủ yếu là trong cấu hình, vì các máy tính hiện đại có thể thực hiện quá trình xây dựng trong vài phút - nhưng sẽ không nguy hiểm lắm nếu bạn giữ kernel hiện tại, đang hoạt động và đảm bảo rời khỏi đó như một tùy chọn thông qua bộ tải khởi động của bạn (xem bước # 6 bên dưới). Bằng cách này, nếu cái mới của bạn không hoạt động, bạn có thể khởi động lại cái cũ.

Trong các hướng dẫn sau, các đường dẫn bên trong cây nguồn có dạng [src]/whatever, [src]thư mục bạn đã cài đặt nguồn vào đâu, vd /usr/src/linux-3.13.3. Bạn có thể muốn thực hiện công cụ này su rootvì cây nguồn nên được bảo mật về quyền ghi (nó phải được sở hữu bởi root).

Mặc dù một số bước là tùy chọn, bạn vẫn nên đọc chúng vì chúng chứa thông tin cần thiết để hiểu phần còn lại của quy trình.

  1. Tải về và giải nén tarball nguồn.

    Đây là có sẵn từ kernel.org . Những cái mới nhất được liệt kê trên trang nhất, nhưng nếu bạn nhìn vào bên trong /pub/thư mục, bạn sẽ thấy một kho lưu trữ sẽ quay trở lại phiên bản 1.0. Trừ khi bạn có lý do đặc biệt để làm khác, tốt nhất bạn chỉ nên chọn "Ổn định mới nhất". Tại thời điểm viết bài này, đây là một tar.xztệp 74 MB .

    Sau khi tarball được tải xuống, bạn cần giải nén nó ở đâu đó. Nơi bình thường là trong /usr/src. Đặt tệp ở đó và:

    tar -xJf linux-X.X.X.tar.xz
    

    Lưu ý rằng các distro riêng lẻ thường khuyên bạn nên sử dụng một trong các gói nguồn của chúng thay vì cây vani. Điều này có chứa các bản vá cụ thể distro, có thể hoặc không quan trọng với bạn. Nó cũng sẽ khớp với kernel bao gồm các tiêu đề được sử dụng để biên dịch một số công cụ không gian người dùng, mặc dù chúng rất có thể giống hệt nhau.

    Trong hơn 15 năm xây dựng các hạt nhân tùy chỉnh (chủ yếu trên Fedora / Debian / Ubuntu), tôi chưa bao giờ gặp sự cố khi sử dụng nguồn vanilla 1 . Tuy nhiên, việc đó không thực sự tạo ra nhiều khác biệt, ngoài thực tế là nếu bạn muốn hạt nhân mới nhất tuyệt đối, bản phân phối của bạn có thể chưa được đóng gói. Vì vậy, cách an toàn nhất vẫn là sử dụng gói distro, nên cài đặt vào /usr/src. Tôi thích sự ổn định mới nhất để tôi có thể hoạt động như một con chuột lang trước khi nó được đưa vào các bản phát hành :)

  2. Bắt đầu với một cấu hình cơ bản [tùy chọn].

    Bạn không phải làm điều này - bạn có thể lặn ngay và tạo cấu hình từ đầu. Tuy nhiên, nếu bạn chưa bao giờ làm điều đó trước đây, mong đợi rất nhiều thử nghiệm và lỗi. Điều này cũng có nghĩa là phải đọc qua hầu hết các tùy chọn (có hàng trăm). Đặt cược tốt hơn là sử dụng cấu hình hiện tại của bạn, nếu có sẵn. Nếu bạn đã sử dụng gói nguồn distro, có lẽ nó đã chứa một [src]/.configtệp, vì vậy bạn có thể sử dụng gói đó. Nếu không, kiểm tra cho a /proc/config.gz. Đây là một tính năng tùy chọn được thêm vào kernel 2.6. Nếu nó tồn tại, sao chép nó vào cấp cao nhất của cây nguồn và gunzip -c config.gz > .config.

Nếu nó không tồn tại, có thể vì tùy chọn này được cấu hình dưới dạng một mô-đun. Hãy thử sudo modprobe configs, sau đó kiểm tra lại /procthư mục config.gz.

Cấu hình distro không lý tưởng lắm theo nghĩa là nó bao gồm hầu hết mọi trình điều khiển phần cứng có thể. Điều này không quan trọng đối với chức năng của kernel, vì chúng là các mô-đun và hầu hết chúng sẽ không bao giờ được sử dụng, nhưng nó làm tăng đáng kể thời gian cần thiết để xây dựng. Điều này cũng khó xử ở chỗ nó yêu cầu một initramfs để chứa các mô-đun cốt lõi nhất định (xem bước 4 dưới đây). Tuy nhiên, nó có lẽ là một điểm khởi đầu tốt hơn so với mặc định.

Lưu ý rằng các tùy chọn cấu hình thay đổi và thay đổi từ một phiên bản kernel sang phiên bản tiếp theo và khi bạn chạy một trong các make configchương trình bên dưới, .configtrước tiên bạn sẽ được phân tích cú pháp và cập nhật để phù hợp với phiên bản mới. Nếu cấu hình là từ một phiên bản cũ hơn nhiều, điều này có thể dẫn đến kết quả lạ, vì vậy hãy chú ý khi bạn thực hiện cấu hình. AFAIK nó sẽ không hoạt động theo cách khác (sử dụng cấu hình từ phiên bản mới hơn).

  1. Tạo một sự .configthôi thúc.

    [src]/.configlà một tệp văn bản được sử dụng để cấu hình kernel. Đừng chỉnh sửa tập tin này trực tiếp . Thay đổi tùy chọn thường không phải là vấn đề đơn giản để thay thế Ybằng một N, v.v; thường có một tập hợp các phụ thuộc lẫn nhau và khả năng phân nhánh. Thay vào đó, bạn muốn sử dụng một trong những mục tiêu cấu hình từ hạt nhân makefile (có nghĩa là, nhập make _____vào dòng lệnh từ thư mục đầu nguồn mức):

    • make configlà cơ bản nhất nhưng có lẽ không phù hợp với hầu hết khẩu vị của mọi người. Đó là một chuỗi các câu hỏi - rất nhiều câu hỏi - và nếu bạn đổi ý, bạn phải bắt đầu lại.

    • make oldconfiggiống như make configngoại trừ, nếu bạn đã có .configtừ phiên bản trước, sẽ bỏ qua các câu hỏi ngoại trừ những câu hỏi liên quan đến các tùy chọn mới. Vẫn có thể có rất nhiều trong số đó và hầu hết trong số họ sẽ không liên quan đến bạn một lần nữa, tôi không khuyên bạn nên điều đó.

    • make menuconfiglà phương pháp ưa thích của tôi (và tôi nghĩ rằng hầu hết những người khác). Nó xây dựng và thực thi giao diện TUI (các menu màu sẽ hoạt động trên thiết bị đầu cuối). Điều này đòi hỏi bạn phải có -devgói cài đặt ncurses. Nó khá tự giải thích, ngoại trừ các seach có thể truy cập thông qua /; "trợ giúp" F1 cung cấp một lời giải thích cho tùy chọn hiện tại. Có một phiên bản thay thế make nconfig, với một vài tính năng bổ sung, trong đó F2 "syminfo" tương đương với F1 của menuconfig.

    • make xconfiglà một giao diện GUI đầy đủ. Điều này đòi hỏi qmake-devgói cho Qt được cài đặt, một lần nữa, đây là một chương trình được biên dịch và xây dựng. Nếu bạn không sử dụng những thứ này trước đây, đó có thể là một bản tải xuống đáng kể. Lý do tôi thích menuconfigphiên bản GUI là hệ thống phân cấp tùy chọn được trình bày bằng cách sử dụng các màn hình kế tiếp nhau trong phiên bản trước nhưng giống như accordion mở sau.

    Một trong những điều đầu tiên bạn nên (nhưng không phải) làm là thêm chuỗi "Phiên bản cục bộ" (trong Cài đặt chung ). Lý do cho điều này được đề cập trong # 5 dưới đây.

    "Labyrinthine" là một cách hay để mô tả hệ thống phân cấp tùy chọn và việc đi sâu vào chi tiết với nó cũng vượt ra ngoài phạm vi của một câu hỏi và trả lời như thế này. Nếu bạn muốn ngồi xuống và trải qua mọi thứ, hãy dành ra hàng giờ . Greg Kroah-Hartman (nhà phát triển lâu năm cho kernel linux) có một cuốn sách trực tuyến miễn phí về kernel (xem Tài liệu tham khảo bên dưới) có chứa một chương về cấu hình , mặc dù nó được viết vào năm 2006. Lời khuyên của tôi là bắt đầu với một cơ sở hợp lý từ kernel distro hiện tại của bạn (theo # 2) và sau đó đi qua nó và bỏ chọn tất cả những thứ bạn biết bạn không cần. Bạn cũng có thể muốn thay đổi một số tùy chọn "mô-đun" thành "tích hợp", điều này đưa chúng ta đến điểm tiếp theo của tôi ...

  2. Giới thiệu initramfs[tùy chọn]

    "Initramfs" là một hệ thống tệp nén được tích hợp vào kernel và / hoặc được tải khi khởi động. Mục đích chính của nó là bao gồm các mô-đun mà kernel sẽ cần trước khi nó có thể truy cập vào các mô-đun trong /lib/moduleshệ thống tập tin gốc - ví dụ: trình điều khiển cho thiết bị chứa hệ thống tập tin đó. Các bản phân phối luôn sử dụng một phần vì các trình điều khiển không tương thích lẫn nhau và do đó không thể được tích hợp vào kernel. Thay vào đó, những cái phù hợp với hệ thống hiện tại được chọn từ bên trong initramfs.

    Điều này hoạt động tốt và không đại diện cho bất kỳ loại bất lợi nào, nhưng nó có thể là một biến chứng không cần thiết khi xây dựng hạt nhân của riêng bạn. 2 Điều thú vị là, nếu bạn không sử dụng initramfs, bạn cần đảm bảo các trình điều khiển cho hệ thống tập tin gốc của bạn (và thiết bị được bật) được tích hợp vào kernel. Trong đó menuconfig, đây là sự khác biệt giữa Mtùy chọn (= mô-đun) và tùy chọn *(= tích hợp). Nếu bạn không hiểu điều này, hệ thống sẽ bị lỗi sớm trong quá trình khởi động. Vì vậy, ví dụ, nếu bạn có ổ cứng SATA và hệ thống tập tin gốc ext4, bạn cần trình điều khiển cho những tích hợp sẵn. [Nếu bất cứ ai có thể nghĩ về bất cứ điều gì khác là phải có, hãy để lại nhận xét và tôi sẽ kết hợp điều đó ở đây].

    Nếu bạn muốn sử dụng một initramfs, bạn sẽ phải chọn các tùy chọn phù hợp trong Cài đặt chung . Có một hướng dẫn bộ xương để tạo ra một được xây dựng vào hạt nhân trong [src]/Documentation/filesystems/ramfs-rootfs-initramfs.txt, nhưng lưu ý rằng các distro không làm điều này; họ sử dụng một tập tin cpio được nén bên ngoài. Tuy nhiên, tài liệu đó có chứa một cuộc thảo luận về những gì nên đi trong initramfs(xem "Nội dung của initramfs").

  3. Xây dựng và cài đặt kernel.

    Bước tiếp theo là dễ dàng. Để tạo kernel, chỉ cần chạy maketrong [src]thư mục. Nếu bạn đang sử dụng hệ thống đa lõi, bạn có thể thêm -j Nđể tăng tốc mọi thứ, Nsố lượng lõi bạn muốn dành + 1. Không có testhoặc không có check. Khi đã xong, bạn có thể make modules. Trên một hộp nhanh, tất cả điều này sẽ mất <10 phút.

    Nếu mọi việc suôn sẻ , make INSTALL_MOD_STRIP=1 modules_install. Điều này sẽ tạo một thư mục /lib/moduleskhớp với số phiên bản của kernel cộng với chuỗi "Phiên bản cục bộ" được đề cập trong bước 3, nếu có. Nếu bạn không sử dụng chuỗi "Phiên bản cục bộ", hãy cẩn thận nếu bạn đã có hạt nhân của cùng một phiên bản mà bạn phụ thuộc , bởi vì các mô-đun này sẽ thay thế các mô-đun đó. 3 INSTALL_MOD_STRIP=1 là tùy chọn, cho ý nghĩa xem tại đây .

    Sau đó, bạn có thể make installcài đặt kernel vào một vị trí mặc định. Tuy nhiên, khuyến nghị của tôi là tự làm để đảm bảo không có tệp nào bị ghi đè. Nhìn vào [src]/arch/[ARCH]/bootmột file có tên bzImage4 , nơi [ARCH]x86nếu bạn đang ở trên một x86 hoặc máy x86-64 (và cái gì khác nếu bạn đang ở trên một cái gì đó khác). Sao chép nó vào /bootvà đổi tên nó thành một cái gì đó cụ thể và nhiều thông tin hơn (nó không thành vấn đề gì). Làm điều tương tự với [src]/System.map, nhưng đổi tên nó theo sơ đồ sau:

    System.map-[VERSION]
    

    Dưới đây, [VERSION]chính xác giống như tên của thư mục trong /lib/modulestạo ra bởimake modules_install , trong đó sẽ bao gồm các "phiên bản địa phương" chuỗi, ví dụ System.map-3.13.3-mykernel.

  4. Cấu hình bộ tải khởi động GRUB 2.

    Nếu bạn không sử dụng grub(phần lớn người dùng máy tính để bàn linux), điều này rõ ràng không áp dụng cho bạn. Bạn nên có một /etc/grub.d/40_customtập tin không có nhiều trong đó. Nếu không, tạo nó thuộc sở hữu của root và chmod 755(nó phải được thực thi). Thêm vào đó:

    menuentry 'My new kernel, or whatever' {
        set root='hd0,1'
        linux /boot/[name-of-kernel] root=/dev/sda1 [other kernel options]
    }
    

    Nếu bạn đang sử dụng initramfs, bạn cũng nên có một dòng cuối cùng initrd /path/to/initramfs. Coi chừng set root=đường dây. Ví dụ giả định grub đã được cài đặt vào phân vùng đầu tiên của ổ cứng đầu tiên (hd0,1). Nếu bạn có nhiều ổ đĩa, bạn có thể muốn sử dụng UUID phân vùng thay thế và thay thế dòng đó bằng:

        search --no-floppy --fs-uuid --set=root [the UUID of the partition]
    

    Trừ khi grub không có trong hệ thống tập tin gốc của bạn, điều này cũng sẽ tương ứng với root=chỉ thị trên linuxdòng, biểu thị hệ thống tập tin gốc của bạn (một với /sbin/init/lib/modules). Phiên bản UUID đó là root=UUID=[the UUID].

    Bạn có thể nhìn vào hiện tại của bạn /boot/grub2/grub.cfgđể tìm manh mối về tên thiết bị. Đây là một hướng dẫn ngắn gọn để làm như vậy dưới grub 2. Một khi bạn hài lòng, hãy chạy grub2-mkconfig -o /boot/grub2/grub.cfg(nhưng sao lưu hiện tại của bạn grub.cfgtrước). Sau đó, bạn có thể muốn chỉnh sửa tệp đó và di chuyển mục nhập của bạn lên đầu. Nó vẫn nên chứa một danh sách cho kernel cũ (đang chạy) của bạn và distro của bạn có thể có một cơ chế sao chép tự động một mục nhập cho kernel mới (vì nó được tìm thấy trong /boot; Fedora thực hiện điều này, do đó, sử dụng một tiêu đề riêng biệt với menuentrylà ý tưởng tốt). Bạn có thể loại bỏ nó sau nếu mọi việc suôn sẻ.

    Bạn cũng có thể chỉ cần chèn trực tiếp menuentryvào grub.cfg, nhưng một số bản phân phối sẽ ghi đè lên phần này khi kernel của chúng được cập nhật (trong khi sử dụng /etc/grub.d/sẽ giữ cho nó được tích hợp).

    Đó là nó. Tất cả bạn cần làm bây giờ là khởi động lại. Nếu nó không hoạt động, hãy thử và suy ra vấn đề từ đầu ra màn hình, khởi động lại chọn một nhân cũ và quay lại bước 3 (ngoại trừ sử dụng cái .configbạn đã có và điều chỉnh nó). Nó có thể là một ý tưởng tốt để make clean(hoặc make mrproper) giữa các lần thử nhưng hãy chắc chắn rằng bạn sao chép [src]/.configvào một số bản sao lưu trước, vì điều đó sẽ bị xóa. Điều này giúp đảm bảo rằng các đối tượng được sử dụng trong quá trình xây dựng không bị cũ.

  5. Về tiêu đề hạt nhân et. al.

    Một điều bạn có thể nên làm là symlink ( ln -s -i) /lib/modules/X.X.X/source/lib/modules/X.X.X/buildvào /usr/srcthư mục chứa cây nguồn (giữ nguyên). Điều này là cần thiết để một số công cụ không gian người dùng (và trình cài đặt trình điều khiển bên thứ ba) có thể truy cập nguồn cho kernel đang chạy.

    Một vấn đề liên quan đến vấn đề này là .hcác tập tin /usr/include, v.v ... Những thay đổi này rất chậm và tương thích ngược . Bạn có hai lựa chọn:

    • Để lại những cái được sử dụng bởi distro của bạn. Nếu bạn cập nhật toàn bộ hệ thống thường xuyên, bản phân phối sẽ cài đặt những cái mới theo định kỳ, vì vậy đây là tùy chọn "ít rắc rối nhất".

    • Sử dụng make headers_install.

    Vì chúng tương thích ngược (có nghĩa là "một chương trình được xây dựng dựa trên thư viện C sử dụng các tiêu đề kernel cũ hơn nên chạy trên kernel mới hơn"), bạn không cần phải quá bận tâm về điều này. Vấn đề tiềm năng duy nhất là nếu bạn xây dựng hạt nhân tùy chỉnh và giữ nó trong một thời gian, trong thời gian đó, bản phân phối cập nhật gói "tiêu đề hạt nhân" lên phiên bản mới hơn so với sử dụng để xây dựng hạt nhân của bạn hóa ra có một số không tương thích (chỉ áp dụng cho phần mềm sau đó được biên dịch từ nguồn).

Tài liệu tham khảo

Dưới đây là một số tài nguyên:

  • [src]/README bao gồm một hướng dẫn ngắn gọn để xây dựng và cài đặt.

  • Thư mục [src]/Documentationchứa nhiều thông tin có thể hữu ích trong cấu hình.

  • Phần lớn cuốn sách Linux Kernel in a Nutshell của Greg KH (có sẵn miễn phí dưới dạng một loạt các tệp PDF) xoay quanh việc xây dựng kernel.

  • Grub 2 có một hướng dẫn trực tuyến .


1. "Vanilla" dùng để chỉ nguồn chính thức, không bị biến đổi như được tìm thấy tại kernel.org. Hầu hết các distro lấy nguồn vani này và thêm một số tùy chỉnh nhỏ.

2. Lưu ý rằng có những trường hợp yêu cầu initramfs vì cần một số không gian người dùng để gắn hệ thống tập tin gốc - ví dụ: nếu nó được mã hóa hoặc trải rộng trên một mảng RAID phức tạp.

3. Tuy nhiên, nó sẽ không xóa các mô-đun đã có nếu bạn không xây dựng chúng, điều đó có nghĩa là bạn có thể thêm một mô-đun sau bằng cách sửa đổi cấu hình của mình và chạy make modules_installlại. Lưu ý rằng việc xây dựng một số mô-đun có thể yêu cầu thay đổi chính hạt nhân, trong trường hợp đó bạn cũng phải thay thế hạt nhân. Bạn sẽ có thể biết khi bạn cố gắng sử dụng modprobeđể chèn mô-đun.

4. Tập tin này có thể được đặt tên khác nếu bạn sử dụng tùy chọn nén không chuẩn. Tôi không chắc tất cả các khả năng là gì.


3
Nâng cao. Bạn có thể muốn thêm vào một đề cập localmodconfigvà các công cụ như streamline_config.pltập lệnh; một cách tiếp cận hữu ích để làm việc từ thiết lập hiện tại của bạn ...
jasonwryan

1
Điều này có lẽ đủ chi tiết để trở thành một câu hỏi loại kinh điển theo sáng kiến ​​của @ terdon. Xem xét việc cung cấp một câu trả lời cho câu hỏi của anh ấy trên meta. Hoặc tôi có thể, nếu bạn thích. Có vẻ như điều này có thể là ý định, vì dù sao bạn cũng đã đặt câu hỏi. Bao gồm các phương pháp phân phối cụ thể để xây dựng các gói nhị phân cũng sẽ hữu ích, tôi nghĩ vậy.
Faheem Mitha

1
FYI: initramfsđược cho là sẽ được sử dụng gần như luôn luôn. Ví dụ: thiết lập rootfs trên LVM + RAID thường yêu cầu một. Root được mã hóa chắc chắn làm. Ngay cả các thiết lập RAID khá phức tạp cũng có. Việc lắp ráp tự động trong nhân của các mảng thậm chí tầm thường thực sự không được chấp nhận ...
derobert

2
@derobert: Điều đó đặt ra câu hỏi rằng "hầu như luôn luôn" linux đang được sử dụng để chạy máy chủ doanh nghiệp. Quan điểm của tôi initramfslà nếu bạn không cần sử dụng một cái, bạn không cần phải làm và điều này đơn giản hóa quy trình. Dù sao, tôi đã thêm một chú thích về fs gốc được mã hóa, v.v.
goldilocks

Vui lòng bao gồm chi tiết về chức năng efi-stub của EFI và linux.
IW16
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.