Biên dịch Linux kernel - conmale 4part

Màu nền
Font chữ
Font size
Chiều cao dòng

Biên dịch Linux kernel

Hướng dẫn chi tiết các bước trong quá trình tái biên dịch Linux kernel cho kernel 2.4.x và 2.6.x.

Tổng lược về Linux kernel và những yếu tố cần chuẩn bị.

<hnd viết riêng cho vninformatics.com>

Compile Linux Kernel

1. Tổng quan về Linux kernel trên phương diện tái biên dịch

1.1 Linux kernel và vấn đề tái biên dịch:

Linux kernel là một "modern kernel", nặng tính modular. Từ kernel phiên bản 2.6.x trở đi, có rất nhiều chức năng và mở rộng được đưa vào kernel. Với tinh thần "compile kernel", một yếu tố chính yếu và quan trọng nhất cần ghi nhận đó là tính phân bộ (modularity) của Linux kernel.

Đối với người dùng bình thường, tính modularity này cho phép chọn lựa cách biên dịch các drivers kernel theo dạng modules hay theo dạng biên dịch trực tiếp vào kernel. Thông thường, kernel build configuration cho phép ba chọn lựa: Y, M và N cho mỗi "driver" trong kernel configuration. Có những "driver" không thể compile như một module vì nó phải được load and link trực tiếp ngay khi kernel khởi động. Cũng có những "driver" cho phép chọn như một module và được load trong khi và sau khi kernel được boot. Điểm chính yếu cần nắm bắt trong giới hạn chủ đề "compile Linux kernel" là hiểu rõ tại sao phải chọn M (cho module), Y (cho compile trực tiếp) và N (không dùng) các drivers này.

- Biên dịch trực tiếp vào kernel có nghĩa là các "drivers" này dù có được dùng hay không vẫn được load lên khi kernel khởi tác và tất nhiên nó sẽ chiếm một phần memory. Lợi điểm chính của chọn lựa này là một khi "drivers" đã được compile vào kernel thì không còn phải quan ngại đến tính trung thực của kernel và các driver nữa. Các hệ thống làm việc đòi hỏi tính bảo mật cao không dùng modules mà compile thẳng vào kernel để tránh trường hợp các modules không tin cậy "bị" cài vào kernel lúc nào đó trong quá trình hoạt động của máy. Lợi điểm kế tiếp của chọn lựa này là tính hiệu xuất (rất nhỏ), khi cần driver thì đã có sẵn và không cần ứng tải nữa.

- Biên dịch như các modules cho kernel có nghĩa là chỉ khi nào cần dùng các "drivers" này mới được ứng tải. Lợi điểm của chọn lựa này nổi bật ở khía cạnh xử dụng memory và tài nguyên trên máy. Với lựa chọn này, bạn có thể tạo nên một kernel cực nhỏ và dễ dàng di chuyển cho nhiều mục đích khác nhau. Lợi điểm kế tiếp là khả năng tái biên dịch chỉ một hoặc một số modules nào đó (cần cập nhật chẳng hạn). Tất nhiên để thực hiện chuyện này thì phải thoả mãn tất cả những đòi hỏi về dependency cho system.

1.2 Tóm tắt các bước biên dịch (dành cho những kẻ thiếu kiên nhẫn )

Biên dịch Linux kernel rất đơn giản nếu như đã hiểu rõ các quy trình và các bước thực hiện. Sau đây là các lệnh cần thiết, giả định bạn đã có trọn bộ các công cụ để biên dịch và các công cụ này đúng phiên bản:

1. $ cd /usr/src # chuyển vào thư mục /usr/src, nơi thông thường chứa mã nguồn để biên dịch kernel

2. $ wget http://www.kernel.org/pub/linux/kern...>.tar.bz2 (<KERNEL_SRC> là phiên bản kernel cần biên dịch, ví dụ ở đây tải mã nguồn được nén ở dạng bz2)

3. $ gpg --verify <KERNEL_SRC>.tar.bz2.sign <KERNEL_SRC>.tar.bz2 (xác thực chữ ký và thực tính của mã nguồn)

4. $ bzip2 -dc <KERNEL_SRC>.tar.bz2 | tar xvf - (xả nén gói chứa mã nguồn)

5. $ make xconfig (dùng GUI để điều chỉnh các chọn lựa cho kernel build configuration và lưu trữ configuration)

6. $ make dep clean bzImage (tập họp lệnh để tạo dependencies và includes, tiếp theo là dọn dẹp các objects không cần thiết và kernel image ở dạng nén)

7. $ make modules (biên dịch các modules đã được chọn lựa)

8. $ su (chuyển sang chế độ super user cho lệnh tiếp theo)

9. # make modules_install (cài các modules vào /lib/modules/<KERNERL_SRC>, chỉ có super user mới có thể thực hiện lệnh này)

10. # make install (cài kernel vào máy, bước này bao gồm quy trình cài các hồ sơ cần thiết vào thư mục /boot)

Bước thứ 10 có thể thay thế bằng một loạt thao tác bằng tay (chi tiết ở phần 9.2) nếu như Linux distribution không có sẵn một số công cụ thuộc gói mkinitrd chỉ có trong RedHat distribution và các distribution dựa trên RedHat.

Lưu ý: đối với kernel 2.6.x series, bạn có thể dùng các bước như trên. Tuy nhiên bước "make dep" không cần thiết nữa. Bài viết này bao gồm kernel 2.4.x và 2.6.x series nên có một số chi tiết không cần thiết cho kernel 2.6.x. Tuy vậy, những chi tiết này sẽ không ảnh hưởng đến sự thành công của quy trình biên dịch kernel.

2. Tại sao cần compile lại Linux kernel?

Đối với người dùng đã quen với những hệ điều hành "đóng" thì khái niệm tái biên dịch kernel là một khái niệm hết sức lạ lẫm. Điều này cũng dễ hiểu vì kernel của các hệ điều hành "đóng" hiển nhiên là "đóng" và người dùng bình thường không thể có cơ hội tiếp cận với mã nguồn của kernel cho thao tác quy trình tái biên dịch. Trong khi đó, mã nguồn của Linux kernel hoàn toàn "mở" và đây là phương tiện cũng như động lực tiên quyết cho vấn đề tái biên dịch kernel. Câu hỏi được đặt ra là tại sao lại cần phải tái biên dịch Linux kernel?

Câu trả lời ngắn: không cần nếu như không cần và cần nếu như cần

Câu trả lời dài: có vô số lý do khiến cho người dùng cần phải tái biên dịch Linux kernel. Sau đây là một số trường hợp thường gặp nhất:

a. tái biên dịch kernel để chữa lỗi của kernel. Nếu các lỗi này thuộc về lõi của kernel thì phải vá nguồn của kernel và tái biên dịch nó để sửa chữa các lỗi được công bố.

b. tái biên dịch kernel để nâng cao hiệu năng của kernel. Theo mặc định, các Linux distribution thường kèm một phiên bản kernel biên dịch với hầu hết những thành phần có sẵn để có thể đáp ứng rộng rãi cấu hình hardware (có thể hiện diện trên các máy). Đây là điểm lợi tổng quát lúc khởi điểm. Tuy nhiên, sau khi đã cài thành công và nắm chắc máy có những thiết bị gì (sound card, graphic card, network cards, SCSI card..... ) và biết rõ cần những thành phần nào cho cấu hình của máy thì không có lý do gì phải bao gồm trọn bộ các thứ không cần thiết và không dùng. Đối với kernel 2.4.x, mức độ nâng cao hiệu năng không rõ rệt (ngoại trừ dùng phương pháp test load để đo). Tuy nhiên, từ kernel 2.6.x trở đi, tính hiệu năng qua việc tái biên dịch và điều chỉnh "driver" modules cho kernel tạo hiệu xuất rõ rệt, nhất là trong việc điều chỉnh "thời biểu" (scheduling) của các công tác mà system phải đảm nhiệm.

c. tái biên dịch để loại bỏ những "drivers" không được dùng và có thể gây "hiểu lầm" cho kernel, tạo ra trường hợp máy có những triệu chứng hoạt động thiếu ổn định và hay gây lỗi.

d. tái biên dịch kernel để thử nghiệm một chức năng hoặc một module mình vừa tạo ra. Trường hợp này không nhiều như các trường hợp trên nhưng cũng nằm trong các lý do phổ biến.

3. Cấu trúc và quy định phiên bản của Linux kernel

Phiên bản của Linux có quy định rất đơn giản và dễ nhớ. Vấn đề này cần nắm rõ trước khi chọn một phiên bản nào đó của Linux kernel để vá và biên dịch.

Phiên bản của Linux bao gồm ba nhóm số tách ra bởi các dấu chấm. Ví dụ: 2.4.26

Số thứ nhất: 2 là phiên bản

Số thứ nhì: 4 là chỉ định cho tình trạng phiên bản. Nếu số này là số chẵn, nó chỉ định cho phiên bản ổn định (stable), có thể dùng cho môi trường production. Nếu số này là số lẻ, nó chỉ định cho phiên bản không ổn định, nó thường dùng trong môi trường đang phát triển (development). Các kernel thuộc dạng này thường có nhiều bugs và không ổn định. Nếu dùng các phiên bản này để tìm bugs và thông báo cho nhóm phát triển Linux kernel thì đây là điều rất tốt. Không nên dùng phiên bản development cho môi trường production.

Số thứ ba: 26 là chỉ định cho số hiệu phát hành của một phiên bản Linux kernel. Một phiên bản ổn định của một Linux kernel có thể có nhiều số hiệu phát hành khác nhau.

Đây là các quy định chung cho dạng Linux kernel "vanilla" có nghĩa là ứng dụng cho các phiên bản kernel từ http://www.kernel.org, các phiên bản kernel được điều chỉnh bởi mỗi distribution có những điểm dị biệt. Có nhiều Linux distribution xử dụng số hiệu con (extra-version) cho phiên bản kernel họ đã điều chỉnh. Ví dụ RedHat có những cập nhật phụ cho các kernel như: 2.4.20-8 chẳng hạn. Điều cần nắm ở đây là chỉ nên xử dụng phiên bản ổn định (stable) của Linux kernel (số chẵn ở giữa) cho môi trường production và dùng phiên bản thử nghiệm (development) của Linux kernel (số lẻ) cho môi trường thử nghiệm và phát triển.

4. Đòi hỏi tối thiểu trong việc tái biên dịch Linux kernel

Trước khi bắt tay vào việc tái biên dịch Linux kernel, điều cần thiết là phải có đủ chỗ chứa trên disk. Ít nhất là phải đủ chỗ chứa cho mã nguồn (trước và sau khi xả nén), chỗ chứa để cài kernel và các modules mới sau khi biên dịch.

Đòi hỏi quan trọng khác là phải có một bộ công cụ cần thiết và đúng phiên bản, không thể biên dịch được kernel nếu không thoả mãn yêu cầu này. Phiên bản cho bộ công cụ với mỗi series kernel khác nhau. Nên nhớ, nhóm phát triển kernel yêu cầu bạn phải có đúng phiên bản của các công cụ để đảm bảo việc biên dịch kernel thành công.

4.1 Đòi hỏi cho Linux kernel 2.4.x

Đồ nghề Phiên bản tối thiểu Cách xác định phiên bản có trên máy

Gnu C 2.91.66 # gcc --version

Gnu make 3.77 # make --version

binutils 2.9.1.0.25 # ld -v

util-linux 2.10o # fdformat --version

modutils 2.4.2 # insmod -V

e2fsprogs 1.19 # tune2fs

reiserfsprogs 3.x.0b # reiserfsck 2>&1|grep reiserfsprogs

pcmcia-cs 3.1.21 # cardmgr -V

PPP 2.4.0 # pppd --version

isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version

Tham khảo thêm chi tiết các công cụ này và địa chỉ để tải các công cụ cho đúng (ít nhất phải cùng phiên bản đã cung cấp ở trên hoặc mới hơn) trong hồ sơ ./Documentation/changes của mã nguồn kernel bạn đang dự tính biên dịch.

4.2 Đòi hỏi cho Linux kernel 2.6.x

Đồ nghề Phiên bản tối thiểu Cách xác định phiên bản có trên máy

Gnu C 2.95.3 # gcc --version

Gnu make 3.78 # make --version

binutils 2.12 # ld -v

util-linux 2.10o # fdformat --version

module-init-tools 0.9.10 # depmod -V

e2fsprogs 1.29 # tune2fs

jfsutils 1.1.3 # fsck.jfs -V

reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs

xfsprogs 2.1.0 # xfs_db -V

pcmcia-cs 3.1.21 # cardmgr -V

quota-tools 3.09 # quota -V

PPP 2.4.0 # pppd --version

isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version

nfs-utils 1.0.5 # showmount --version

procps 3.1.13 # ps --version

oprofile 0.5.3 # oprofiled --version

Tham khảo thêm chi tiết các công cụ này và địa chỉ để tải các công cụ cho đúng (ít nhất phải cùng phiên bản đã cung cấp ở trên hoặc mới hơn) trong hồ sơ ./Documentation/changes của mã nguồn kernel bạn đang dự tính biên dịch.

Nếu phiên bản của các công cụ trên máy cũ hơn các phiên bản đưa ra ở trên, bạn cần phải tải phiên bản mới (đã biên dịch) từ website của distribution nào bạn đang dùng. Bạn cũng có thể chọn cách tải mã nguồn của từng công cụ về biên dịch lại. Cách này mất thời gian hơn rất nhiều và chỉ thích hợp cho những ai đã quen thuộc với vấn đề biên dịch mã nguồn trên Linux. Lợi điểm của cách này là bạn tạo cho mình một bộ công cụ rất "sạch" vì đã biên dịch theo ý, thích hợp với môi trường của máy (và vừa đủ).

Đối với IA64 architecture, bạn cần GCC 64bit compliant compiler, nên tham khảo chi tiết ở:

http://gcc.gnu.org/install/specific.html (nếu bạn may mắn có một con IA64 để thử

5. Xác định cấu hình (hardware) của máy

Phần lớn người dùng bình thường ít khi quan tâm đến cấu hình của máy ngoại trừ có nhu cầu cụ thể. Ngay cả những ai dùng Linux đã lâu và không cần phải tái biên dịch kernel, cũng ít khi quan tâm đến cấu hình hardware của máy. Dù có biết nhiều hay ít về cấu hình hardware của máy mình dùng, bạn vẫn phải thu thập thông tin chính xác của cấu hình trước khi bắt tay vào việc điều chỉnh kernel build configuration.

Giả định mọi chỉnh lý đã ổn định và làm việc tốt đẹp (do installer tự detect trong khi cài Linux hay do bạn phải điều chỉnh lại), bạn cần tái biên dịch Linux kernel và cần thâu thập thông tin về cấu hình của máy, hai lệnh sau cung cấp các chi tiết hardware có trên máy:

# /sbin/lspci để liệt kê trọn bộ những PCI "card" đang gắn vào máy. Lệnh này liệt kê trọn bộ các "card" đang trực tiếp làm việc trên máy, hardware version và model của chúng.

# cat /proc/cpuinfo để xem chi tiết CPU của máy là loại gì. Nếu Linux distribution bạn dùng không dùng /proc filesystem thì bạn có thể dùng lệnh # dmesg để thu thập thông tin về hardware trên máy của mình. Ngoài ra, lệnh lsmod cũng ít nhiều giúp bạn xác định các modules đang được dùng trên máy và tên của các modules này.

Những thông tin thâu thập được ở đây hết sức quan trọng trong giai đoạn điều chỉnh kernel build configuration. Nó giúp bạn xác định các chọn lựa đúng cho cấu hình máy, tránh đi những trở ngại có thể rất mất thời gian sau này.

6. Các bước chuẩn bị

6.1 Tạo một bootable floppy disk dùng kernel đang chạy

Đây là một bước cần thiết đề phòng sự cố gì đó khiến bạn không thể boot vào Linux system sau khi cài kernel mới. Trường hợp này hiếm khi xảy ra trong quá trình biên dịch kernel và cài kernel mới nếu bạn thực hiện và điều chỉnh đúng. Những sự cố với bootloader (LILO hoặc GRUB) ít thấy xảy ra vì bootloader đã được thiết lập hoàn chỉnh trước khi cập nhật kernel. Phần lớn giai đoạn tái điều chỉnh config của LILO hoặc GRUB không chính xác tạo trở ngại. Vấn đề này sẽ được đề cập sau. Trước mắt chúng ta cần tạo một "bootable floppy disk".

Có rất nhiều cách để tạo một bootable floppy lấy từ kernel hiện đang chạy trên máy. Thay vì trình bày nhiều cách khác nhau cho việc tạo bootable floppy disk, ở đây tôi chỉ đề cập đến phương thức đơn giản nhất. Cách dễ nhất có lẽ là cách dùng mkbootdisk. Đây là một binary được cài mặc định trên các RedHat distribution và hầu hết các distribution dựa RedHat. Nếu binary này không hiện diện trên máy, bạn có thể tải mã nguồn về và biên dịch cho distribution mình đang dùng. Chạy lệnh:

# mkbootdisk --device /dev/fd0 'uname -r', trong đó

'uname -r' là lệnh ngầm để lấy phiên bản kernel hiện dùng trên máy. Nếu không muốn phiên bản này, bạn có thể gõ vào phiên bản nào đó theo ý (tất nhiên là phiên bản kernel này phải hiện hữu trên system).

/dev/fd0 là "device" chỉ cho đĩa mềm thứ nhất trên máy (tương tự như drive A: trên DOS). Bạn phải chọn đúng "device" thì mới có dữ liệu viết vào đĩa mềm mình muốn tạo.

Quy trình này chỉ mất khoảng vài phút. Sau khi tạo bootable floppy disk ở trên, bạn nên dùng nó để thử boot vào Linux trước khi thực hiện các bước kế tiếp. Nên nhớ phải chỉnh BIOS để cho phép máy boot từ A:

Ở trang:

http://www.yolinux.com/TUTORIALS/Lin...Disk.html

có các hướng dẫn tạo disk cấp cứu rất hay. Bạn nên tham khảo thêm nếu trên máy mình dùng không có sẵn mkbootdisk.

6.2 Tải mã nguồn

Mã nguồn của Linux kernel cả stable lẫn development có rất nhiều nơi trên Internet. Nên vào trang trung tâm của Linux kernel ở http://www.kernel.org và tham khảo danh sách "mirrors" để tìm nơi "gần" chỗ mình cư ngụ nhất để tải về. Nơi "gần" không nhất thiết là "gần" theo phương diện địa lý mà nên chọn "gần" nhất dựa trên "ping time". Chịu khó lấy vài địa chỉ trên mirror và ping những địa chỉ này để chọn lấy nơi có ping time ngắn nhất mà download. Bằng cách sẽ giúp bạn đỡ mất thời gian và tiện cho vấn đề chia xẻ băng thông.

Có nhiều cách tải mã nguồn. Bạn có thể dùng browser để tải qua http hoặc dùng một ftp client nào đó để tải qua ftp. Bạn cũng có thể dùng wget để download. Có lẽ đây là cách tiện nhất và nhanh nhất nếu biết rõ địa chỉ và đường dẫn đến gói mình muốn download. Ví dụ:

$ wget http://www.kernel.org/pub/linux/kern...6.tar.bz2 (trong trường hợp này, gói cụ thể cần tải là linux-2.4.26.tar.bz2).

Mã nguồn ổn định của Linux kernel được nén ở hai dạng khác nhau: dạng có đuôi là .gz (dùng GNUzip để nén) và dạng có đuôi .bz2 (dùng bzip2 để nén). Thông thường cả hai tiện ích nén / xả nén trên đều có sẵn trong các Linux distribution thông dụng. Nếu không có sẵn trên máy thì tìm trong trong CD của distribution (tham khảo thêm tài liệu của distribution mình dùng cho cách cài thêm software trên máy) hoặc tải về từ:

- http://www.gzip.org/ cho GNUzip

- http://sources.redhat.com/bzip2/ cho bzip2

Hướng dẫn chi tiết các bước trong quá trình tái biên dịch Linux kernel cho kernel 2.4.x và 2.6.x.

Chuẩn bị mã nguồn và những điểm liên quan.

<hnd viết cho vninformatics.com>

6.3 Kiểm tra thực tính của mã nguồn

Điều quan trọng khi tải mã nguồn của kernel, nên tải gpg .sign cho phiên bản tương ứng. Mục đích là để kiểm tra thực tính của mã nguồn được tải về. Khi mã nguồn của Linux kernel được công bố, chúng được dồn lại thành một gói .tar và sau đó được nén bằng GNUzip hoặc bzip2, cả hai loại này sau khi được nén đều được tạo "chữ ký" .sign.

Kiểm tra thực tính của mã nguồn được tải về bằng phương pháp kiểm tra "chữ ký" của từng gói mã nguồn là một thói quen cần thiết. Lý do: các mã nguồn mở nói chung được công bố và phổ biến rộng rãi, ai cũng có thể chỉnh sửa (một cách không chính thức và không được nhóm phát triển chính thức cho phép) rồi đưa lên một server nào đó trên Internet. Người dùng tải về, biên dịch và cài trên máy mà không kiểm tra thực tính của chúng (và mã nguồn này có những thay đổi mờ ám) thì hậu quả khó mà lường.

Quy trình kiểm tra "chữ ký" chỉ đơn giản gói gọn trong một dòng lệnh:

$ gpg --verify linux-2.4.26.tar.bz2.sign linux-2.4.26.tar.bz2, trong đó

linux-2.4.26.tar.bz2.sign là "chữ ký" của gói linux-2.4.26.tar.bz2 được tải về từ server chứa mã nguồn Linux kernel

linux-2.4.26.tar.bz2 là gói mã nguồn Linux kernel được nén bằng bzip2

Trước khi có thể kiểm tra thành công bằng lệnh trên, bạn phải có gpg đã cài trong máy, tải và nhập public key của server chứa mã nguồn Linux kernel mà bạn tải về. Chi tiết hướng dẫn cho quy trình này ở:

http://www.kernel.org/signature.html

Quy trình tải mã nguồn Linux kernel và kiểm tra thực tính của mã nguồn này có thể tóm tắt bằng một ví dụ như sau:

# chuyển vào thư mục chứa mã nguồn của máy ở /usr/src là nơi thông thường. Đối với kernel 2.6.x series, bạn có thể dùng thư mục khác tùy ý:

cd /usr/src

# dùng wget để lấy một phiên bản mã nguồn từ server về ở dạng .bz2

wget http://www.kernel.org/pub/linux/kern...6.tar.bz2

# dùng wget để lấy .sign của phiên bản mã nguồn vừa được tải về

wget http://www.kernel.org/pub/linux/kern....bz2.sign

# Dùng gpg với option verify để kiểm thực tính của mã nguồn vừa tải về

gpg --verify linux-2.4.26.tar.bz2.sign linux-2.4.26.tar.bz2

Ngoài phương pháp dùng signature cho vấn đề kiểm chứng thực tính của mã nguồn (không chỉ mã nguồn của Linux kernel) , bạn cũng thấy rất nhiều nơi trên Internet dùng "MD5sum" cho mục đích này (cho đến nay, mã nguồn Linux kernel dùng signature để kiểm chứng, không dùng MD5sum). Quy trình kiểm tra "MD5sum" chỉ đơn giản là một quy trình tạo một "MD5sum" từ mã nguồn được tải về trên máy và so sánh kết quả "MD5sum" này với hồ sơ "MD5sum" được tải về kèm với mã nguồn. Nếu "MD5sum" bạn tạo ra trên máy của mình với cùng gói mã nguồn mà không trùng hợp với "MD5sum" nguyên thuỷ tải về từ server thì thực tính của phần mã nguồn này không đáng tin cậy. Cách tốt nhất là chỉ nên tải mã nguồn ở những địa chỉ phố biến và đáng tin cậy. Cẩn thận hơn nữa (really paranoid), thì so sánh MD5sum với một số server chứa mã nguồn khác nhau.

- Kiểm tra thực tính của mã nguồn bằng MD5 checksum khá đơn giản. Tiện ích md5sum có sẵn hần như trên mọi bản phân phối. Lệnh tạo MD5 checksum đơn giản là lệnh:

# md5sum <file_cần_kiểm_tra>

sẽ tạo ra 1 chuỗi chữ và số tương tự như: 2fe2a5fabcc3a33722b4ffe05714bec3 *<file_cần_kiểm_tra>. Nếu chuỗi này trùng với chuỗi được cung cấp chính thức với mã nguồn thì mã nguồn này có thực tính và đáng tin cậy.

6.4 Xả nén mã nguồn

Tùy vào gói mã nguồn được tải về thuộc dạng nén .gz hay .bz2 mà dùng tiện ích thích hợp để xả nén. Như đã tóm tắt trong phần 6.3 ở trên, gói mã nguồn được chứa trong /usr/src (wget được chạy sau khi cd vào /usr/src), cho nên bạn phải ở trong thư mục này trước khi thao tác các bước kế tiếp (không thì các bước kế tiếp phải thêm và đường dẫn đến nơi chứa gói mã nguồn). Đối với kernel 2.6.x series, mã nguồn của Linux kernel có thể được xả, chứa và biên dịch từ bất cứ nơi đâu mà bạn có quyền chứa trên hệ thống. Tuy nhiên, để giữ cho hệ thống sạch và thống nhất, bạn nên giữ mã nguồn ở /usr/src.

- nếu gói mã nguồn có dạng .gz thì dùng:

$ gunzip linux-2.x.xx.tar.gz (x.xx là bất cứ phiên bản nào bạn tải về).

$ tar xf linux-2.x.xx.tar (lệnh này dùng option x để extract (xả) và f để chỉ định hồ sơ nào cần được xả, ở đây hồ sơ cần được xả là linux-2.x.22.tar).

Hai lệnh trên cũng có thể gọp chung lại như sau:

$ tar xfz linux-2.x.xx.tar.gz (lệnh này dùng thêm option z để ngầm xả nén .gz file "on-the-fly" trước khi xả gói tar).

Hoặc có thể tạo cùng kết quả bằng cách khác nữa:

$ gzip -dc linux-2.x.xx.tar.gz | tar xvf - (cụm lệnh này dùng chương trình gzip để xả nén (option -d) ra stdout (option -c) và "tee" nó qua chương trình tar để xả gói tar ra "on-the-fly". Cả cách này và cách ở trên đều tiện dụng cho những ai eo hẹp dung lượng trên đĩa).

- nếu gói mã nguồn có dạng .bz2 thì dùng:

$ bunzip2 linux-2.x.xx.tar.bz2

$ tar xf linux-2.x.xx.tar

Hai lệnh trên cũng có thể gọp chung lại như sau:

$ tar xfj linux-2.x.xx.tar.bz2 (lệnh này dùng thêm option j để ngầm xả nén .bz2 file "on-the-fly" trước khi xả gói tar).

Hoặc có thể tạo cùng kết quả bằng cách khác nữa:

$ bzip2 -dc linux-2.x.xx.tar.bz2 | tar xvf - (cụm lệnh này dùng chương trình bzip2 để xả nén (option -d) ra stdout (option -c) và "tee" nó qua chương trình tar để xả gói tar ra "on-the-fly". Cả cách này và cách ở trên đều tiện dụng cho những ai eo hẹp dung lượng trên đĩa).

Cả ba trường hợp đều cho kết quả là một thư mục có tên là linux-2.x.xx bên trong thư mục /usr/src/

Trong phần này, chúng ta chỉ đề cập đến trường hợp tải trọn bộ mã nguồn của Linux kernel về để biên dịch. Trường hợp đã có mã nguồn cũ hơn của Linux kernel trên máy và chỉ cần tải patch và "vá" thì có quy trình khác. Vấn đề này sẽ đề cập sau.

6.5 Dùng "config" nào thì thích hợp?

Cấu hình biên dịch nhân Linux đơn giản là một "text file" chứa các biến với giá trị Y (Yes), N (No) hoặc M (Module). Các giá trị này được xử dụng trong quá trình biên dịch; chúng dùng để xác định những gì không được biên dịch, những gì được biên dịch và nếu được biên dịch thì sẽ theo dạng nào.

Tùy vào cách sắp xếp của mỗi Linux bản phân phối, cấu hình biên dịch nhân Linux nằm nhiều nơi khác nhau. Hồ sơ cấu hình theo mặc định của "vanilla" kernel nằm ở ./arch/i386/defconfig (nếu dùng dòng phần cứng IA32 nói chung), các hồ sơ cấu hình khác cho những dòng phần cứng khác nằm ở ./arch/$ARCH/defconfig; trong đó $ARCH là dòng phần cứng của máy. Nếu dùng cấu hình mặc định, không chỉnh sửa thì kernel sẽ được tái biên dịch trọn bộ theo giá trị mặc định và chắc hẳn, kernel này sẽ không thích hợp cho bạn (ngay cả nếu nó được biên dịch thành công). Điều này đi ngược lại mục đích cần tái biên dịch Linux kernel ngay từ đầu. Bạn có thể dùng hồ sơ cấu hình này để khởi đầu và chỉnh sửa giá trị cho thích hợp. Đây là một bước rất khó khăn cho những ai chưa từng đi qua giai đoạn này và không có sẵn một cấu hình biên dịch nhân hoàn chỉnh cho máy.

Cấu hình cho kernel hiện hữu trên máy cũng có thể nằm trong thư mục /boot ở dạng config-2.x.xx nếu bạn dùng kernel do RedHat (hoặc dựa RedHat) và một số bản phân phối khác cung cấp. Bạn có thể an toàn dùng cấu hình này và chỉnh sửa, loại bỏ các chi tiết (driver module) không cần dùng. Nếu hệ thống đã được biên dịch kernel trước đây, bạn có thể tìm thấy cấu hình biên dịch nhân Linux có tên là .config, được lưu trong thư mục <KERNEL_SRC> (nơi trước đây mã nguồn của kernel được xả nén và biên dịch).

7. Chỉnh cấu hình biên dịch nhân Linux

7.1 Thành phần của cấu hình biên dịch nhân Linux

Thành phần trong cấu hình biên dịch nhân Linux cho kernel 2.4.x và 2.6.x có một số tương đồng và dị biệt. Tuy nhiên, quy trình chọn Y, N hoặc M cho các modules vẫn như nhau. Bước chọn lựa và chỉnh liệu cấu hình biên dịch nhân Linux là một bước mất nhiều thời gian nhất, nó cũng là một bước gây nhiều trở ngại nhất nếu chỉnh sửa không hợp lý hoặc thiếu sót.

7.1.1 Thành phần cấu hình biên dịch nhân Linux thuộc kernel 2.4.x series

Code Maturity Level Options

Chọn lựa của mục này cho phép dùng các modules / drivers còn ở trạng thái "alpha" (thử nghiệm). Nếu hệ thống làm việc là một máy production, cần tính ổn định cao thì nên tắt bỏ chọn lựa của phần này. Làm như thế sẽ tắt bỏ rất nhiều modules / drivers thuộc dạng "alpha" trong những phần bên dưới. Nếu muốn thử dùng một số modules / drivers ở dạng alpha thì nên cho phép phần này (Y) và cẩn thận khi lựa chọn các modules được biên dịch sau này. Việc chọn lựa các "alpha" drivers ở chế độ mặc định của các kernel trong nhiều bản phân bố Linux là một trong những nguyên nhân chính tạo nên tình trạng bất ổn định trên một số hệ thống Linux. Nếu chọn lựa các driver này một cách cẩn thận, cơ hội va phải tình trạng bất ổn định sẽ giảm thiểu rõ rệt.

Loadable Module Support

Đây là chức năng nòng cốt của Linux kernel (loadable module). Như đã đề cập ở phần tổng quan (phần 1), loadable modules tiện dụng và linh động, cho nên bạn gần như sẽ chọn Y trong trường hợp này. Trong trường hợp bạn cần dùng kernel modules được viết thêm bên ngoài kernel tree chính thức (3rd party modules), bạn phải chọn "enable set version information on all modules symbols" trong mục này. Nếu bạn cần biên dịch trọn bộ các drivers thẳng vào kernel và không dùng modules (vì lý do bảo mật chẳng hạn), bạn có thể chọn N ở đây. Bạn cũng phải chọn "Y" cho trọn bộ các drivers trong cấu hình biên dịch nhân để thích hợp với chọn lựa "N" cho phần Loadable Module Support này.

Processor Type and Features

Phần này có lẽ là phần tối quan trọng trong cấu hình biên dịch nhân Linux. Đây là nơi để chọn đúng CPU đang dùng trên máy. Ngoài ra còn rất nhiều chọn lựa khác nhau cho vấn đền system scheduling, SMP (symetrical multi-processing) nếu máy có nhiều CPU, hỗ trợ số lượng lớn memory có trong máy.... Nếu bạn chon CPU là i386 thì có lẽ sẽ không có sự cố vì i386 là architecture chung nhất (cả Intel và AMD CPU đều chạy với chọn lựa i386). Tuy nhiên, chọn lựa này sẽ không đạt hiệu năng tối đa và thích hợp cho từng loại CPU cụ thể. Nên chọn đúng CPU để bảo đảm hiệu năng của máy và nhất là để tránh trường hợp không thể boot vào Linux sau khi cài kernel mới (vì loại CPU chỉnh định cho kernel không đúng với CPU có trên máy hay nói một cách kỹ thuật, instructions giữa kernel và máy không tương đồng).

General Setup

Mục này cho phép chọn lựa các ứng dụng hỗ trợ cho những thiết bị (cards) trên máy như ISA, PCI, PCMCIA và các chức năng thuộc về vấn đề quản trị năng lượng nâng cấp (Advanced Power Management).

Memory Technology Devices

Phần này cho phép lựa chọn những ứng dụng thiết bị liên hệ đến memory. Nếu bạn dùng các thiết bị như digital camera hoặc các loại compact flash thì bạn nên chỉnh lý phần này cho thích hợp.

Block Devices

Đây là một phần rất quan trọng trong cấu hình biên dịch nhân Linux. Nó bao gồm các chọn lựa cho những thiết bị thông thường và cần thiết như đĩa cứng, đĩa mềm, băng lưu trữ cũng như các thiết bị điều tác (controllers) cho parallel ports và RAID. Hầu như các chọn lựa trong mục này đều cần thiết; đặc biệt là chức năng hỗ trợ initrd cần thiết để tải sẵn các drivers cần thiết ở dạng module trong quá trình boot máy.

Multi-Device support (RAID and LVM)

Phần này chuyên chú đến các chức năng cần thiết cho hệ thống ở cấp độ server. Các chọn lựa ở đây hỗ trợ những thiết bị như RAID và LVM. Nếu máy của bạn hiện đang dùng RAID và LVM thì không thể bỏ qua phần này trong quá trình xác lập cấu hình biên dịch nhân Linux. Chọn lựa trong phần này đòi hỏi phải hiểu rõ nhu cầu dùng những công nghệ thuộc dạng này trên máy. Nếu máy không dùng đến những công nghệ này, bạn có thể an toàn tắt bỏ chúng (dùng N). Nên nhớ, nếu tắt bỏ RAID trong phần này thì phải tắt bỏ chọn lựa RAID trong phần "block devices" ở trên để tránh gặp phải lỗi biên dịch sau này.

ATA/IDE/MFM/RLL support

Phần này bao gồm các chọn lựa và hỗ trợ cho IDE và ATAPI dùng trên các pc-compatible (và trên nhiều architecture khác hiện có trên thị trường). Hầu hết các hệ thống cần các chức năng hỗ trợ trong phần này.

Cryptography Support (CryptoAPI)

Đây là một phần khá mới và lý thú trong mã nguồn của Linux kernel 2.4.x (chỉ được giới thiệu và công bố trong các phiên bản sau này của 2.4.x). Phần này có những lựa chọn thuộc về vấn đề "mã hoá" cho filesystems. Bạn có thể biên dịch các chọn lựa trong mục này và xử dụng (hoặc không) trên máy tùy ý.

Networking Options

Đây là một phần cực kỳ quan trọng trong cấu hình biên dịch nhân Linux nếu bạn muốn máy của mình gắn liền với mạng. Nó bao gồm các chọn lựa cho cả IPv4 và IPv6 networking. Đây cũng là một phần hết sức phức tạp, cho nên, để có thể hiểu rõ và chọn lựa đúng cho hiệu năng tối đa của máy về mặt networking, bạn nên tham khảo rộng rãi các tài liệu về Linux networking, ít nhất là nên đọc các tài liệu kèm theo trong mã nguồn Linux kernel ở <KERNL_SRC>/Documentation/networking/ (thường là /usr/src/linux-2.x.xx/Documentation/networking/).

SCSI Support

Phần chọn lựa cho SCSI ít được những người dùng PC bình thường quan tâm đến vì không mấy ai dùng SCSI cho máy con. Tuy nhiên nếu bạn dùng SCSI card (hoặc SCSI built-in trên motherboard) hoặc dùng CDR/W qua IDE nhưng chạy ở dạng SCSI emulation thì phải điều chỉnh các chọn lựa trong mục này. Điều quan trọng cần nhớ, nếu không dùng tiện dụng initrd, khi chọn lựa SCSI cho một filesystem chạy trên SCSI disk bạn phải biên dịch trực tiếp các chọn lựa cho SCSI vào kernel thay vì dùng dưới dạng module. Nếu không, kernel sẽ treo trong giai đoạn Linux kernel boot vì module hỗ trợ SCSI chưa được load trong giai đoạn này.

Character Devices

Trong mục này có khá nhiều lựa chọn tập trung vào các thiết bị như serial và parellel, mouse, joysticks (để chơi games). Tắt hoặc mở các lựa chọn trong mục này thường ít tạo ảnh hưởng nghiêm trọng.

File Systems

Mục này chứa trọn bộ các chọn lựa liên quan đến file system và các loại file system được hỗ trợ trên Linux (bao gồm các file system thường được hỏi đến như FAT, FAT32, NTFS, ISO cho CD-ROM....). Các file system phụ trợ như NTFS, FAT... có thể được biên dịch như một module cho kernel. Không nên biên dịch các modules cho file system dùng để "mount" trong giai đoạn boot như ext3, jbd mà nên biên dịch thẳng vào kernel (Lý do tương tự như đã đề cập trong phần "SCSI Support" ở trên). Cách này sẽ làm kích thước kernel lớn hơn nhưng sẽ an toàn và đơn giản hơn. Chức năng hỗ trợ initrd có thể dùng để tải các modules cần thiết trong quá trình Linux kernel boot nhưng phải nhớ bật chức năng này lên trong phần block devices. Đây là vấn đề tùy chọn của từng cá nhân.

7.1.2 Thành phần Linux kernel configuration thuộc kernel 2.6.x series

Code Maturity Level Options

Phần này tương tự như đã đề cập ở trên cho kernel 2.4.x series

General Setup

Phần này tương tự như đã đề cập ở trên cho kernel 2.4.x series

Loadable Module Support

Phần này tương tự như đã đề cập ở trên cho kernel 2.4.x series

Processor Type and Features

Phần này tương tự như đã đề cập ở trên cho kernel 2.4.x series

Power Management Options

Phần này tương tự như đã đề cập ở trên cho kernel 2.4.x series

Executable File Formats

Đây là một mục riêng biệt trong cấu hình biên dịch nhân của series 2.6.x. Nếu bạn quan tâm đến "a.out", "elf" và "misc", nên nghiên cứu kỹ phần này qua các tài liệu kèm theo với mã nguồn kernel, đặt biệt cho các tiện dụng của "misc" (<KERNEL_SRC>/Documentation/mono.txt, <KERNEL_SRC>/Documentation/binfmt_misc.txt, <KERNEL_SRC>/Documentation/filesystem/proc.txt)

Device Drivers

Đây là một mục mới trong phần cấu hình biên dịch nhân của series 2.6.x. Thật ra device drivers nằm rải rác khắp nơi trong kernel build configuration của series 2.4.x. Ở series 2.6.x, mọi vấn đề liên quan đến "device drivers" được gom lại trong cùng một nhóm. Các chọn lựa thuộc về các thiết bị như graphic card, sound card, USB, SCSI và vấn đề hiệu chỉnh chúng đều tập trung ở đây.

File Systems

Phần này tương tự như đã đề cập ở trên cho kernel 2.4.x series

Security Options

Phần này dành riêng cho các vấn đề về bảo mật của kernel. Cho đến nay vẫn còn đang phát triển, tuy nhiên, đây là phần đầy hứa hẹn cho một Linux kernel mang tính bảo mật cao.

Biên dịch Linux kernel - phần 3

Hướng dẫn chi tiết các bước trong quá trình tái biên dịch Linux kernel cho kernel 2.4.x và 2.6.x.

Các yếu tố cần thiết trong việc chuẩn bị cấu hình biên dịch Linux kernel và các bước tạo.

<hnd viết cho vninformatics.com>

7.2 Điều chỉnh cấu hình biên dịch nhân Linux

Vậy, để điều chỉnh các chọn lựa cho một cấu hình biên dịch nhân Linux, có một số cách thực hiện chuyện này.

7.2.1 Các "config" tools

Như đã đề cập ở phần 6.5, mặc định cấu hình biên dịch nhân nằm ở ./arch/i386/defconfig. Khi khởi động một "config" tool nó sẽ tự động đọc và dùng nội dung của config mặc định này trước khi bạn chỉnh sửa theo ý.

Để chỉnh cấu hình biên dịch nhân Linux, chuyển vào thư mục chứa mã nguồn của kernel (đã xả nén):

$ cd /usr/src/linux-2.4.26 (ví dụ này dùng kernel 2.4.26 - xem lại phần xả nén ở phần 6.4)

và việc đầu tiên rất nên làm đó là chạy lệnh:

$ make mrproper

Không kể bạn dùng bản phân phối Linux nào và phiên bản Linux kernel nào, bạn nên chạy lệnh này trước khi thực hiện quy trình tái biên dịch kernel. Target "mrproper" này dùng để xoá hết tất cả những gì còn "vất vưởng" trong các cây chứa mã nguồn của Linux kernel để nắm chắc mã nguồn trước khi được biên dịch phải ở tình trạng "sạch sẽ".

Có ba phương tiện "config" phổ biến có thể dùng để chỉnh cấu hình biên dịch nhân Linux. Sau khi chuyển vào thư mục /usr/src/linux-2.4.26, bạn có thể chọn một trong ba cách:

- make config

- make menuconfig

- make xconfig

Trong đó,

- make config là phương tiện đơn giản nhất và không đòi hỏi thêm bất cứ thư viện nào khác để chạy công cụ này. make config sẽ tạo ra một loạt câu hỏi (ở dạng prompt) và sau khi nhận được câu trả lời của bạn (Y, N, M như đã nói ở trên sau khi bạn nhấn phím Enter, xác nhận câu trả lời của mình), nó sẽ hình thành một cấu hình biên dịch nhân Linux. Nhược điểm của loại config này ở chỗ, nếu bạn lỡ trả lời sai (chọn Y, N hoặc M và gõ phím Enter), bạn không thể quay ngược lại để điều chỉnh mà phải bắt đầu lại từ đầu. Phương tiện "make config" này chỉ tiện lợi cho những ai rất kinh nghiệm và nắm rõ mình cần gì trong cấu hình biên dịch nhân, nó cũng tiện lợi cho quy trình chỉnh cấu hình biên dịch nhân từ xa (xuyên qua console và không dùng được X11 forward vì lý do gì đó). Sau khi hoàn tất các câu hỏi, công cụ này sẽ lưu trữ một cấu hình biên dịch nhân (được lưu ở dạng .config trong thư mục chứa mã nguồn của Linux) và sẵn sàng cho bước tạo dependency cho kernel build. Nếu hồ sơ .config đã tồn tại từ lần biên dịch trước, nó sẽ bị viết chồng lên ở giai đoạn này.

<insert hình>

- make menuconfig nâng cấp lên một mức cao hơn so với make config. Công cụ này cần thư viện và binaries "ncurses" để tạo GUI đơn giản. Với công cụ này, bạn có thể tái điều chỉnh các chi tiết tuỳ thích mà không phải bắt đầu lại từ đầu (nếu lỡ chọn sai) như dùng make config. Trên GUI đơn giản này, bạn có thể di chuyển, thay đổi các chọn lựa bằng cách dời chuyển phím mũi tên (lên xuống), chọn Y bằng phím Y, chọn N bằng phím N và chọn M bằng phím M. Với công cụ này, bạn cũng có thể tải một cấu hình biên dịch nhân có sẵn (đã làm từ trước và đã biên dịch thành công chẳng hạn) mà chẳng phải đi xuyên qua mọi chọn lựa để hình thành một cấu hình biên dịch nhân mới. Một đặc tính của công cụ này là nó chứa "help context sensitive" (phần giúp đỡ hoặc thông tin cho từng mục trong quá trình điều chỉnh configuration). Nếu bạn không nắm rõ giá trị hoặc tác dụng của module nào đó, bộ phận "help" này chắc chắn sẽ hữu ích. Sau khi đã hoàn thành các chọn lựa, bạn có thể lưu trữ một bản configuration trên máy để lần sau dùng lại và "exit" đồ nghề này. Ở giai đoạn này, một bản configuration được lưu lại (ở dạng .config trong thư mục chứa mã nguồn của Linux) và sẵn sàng cho bước tạo dependency cho kernel build. Tương tự như "make config", nếu hồ sơ .config đã tồn tại từ lần biên dịch trước, nó sẽ bị viết chồng lên.

<insert hình>

- make xconfig có lẽ là phương tiện được dùng rộng rãi nhất, nhất là cho những hệ thống chạy X Window. make xconfig cần trọn bộ thư viện Qt và X Window để tạo GUI. Các chọn lựa và cách di chuyển trong GUI này để điều chỉnh hoàn toàn giống như trường hợp dùng menuconfig và thêm một khả năng nữa là có thể dùng mouse để chọn. Nếu bạn cần tái biên dịch kernel và có thể dùng X Window thì nên dùng công cụ xconfig này vì nó dễ dùng nhất.

Trên Linux kernel 2.6.x series có thêm make gconfig. Tương tự như make xconfig, "gconfig" cũng tạo GUI config tool nhưng GUI này dựa trên thư viện Gtk.

7.2.2 Một số điểm cần chú ý trong giai đoạn hình thành cấu hình biên dịch nhân

- Dùng cấu hình biên dịch nhân có sẵn và điều chỉnh cho thích hợp với nhu cầu của mình. Nếu bạn dùng bản phân phối của RedHat, cấu hình biên dịch nhân có trong thư mục /boot ở dạng config-<KERNEL_VERSION> (hồ sơ cấu hình này từ các kernel do RedHat cung cấp). Để dùng cấu hình biên dịch nhân này, bạn có thể dùng make menuconfig hoặc make xconfig để tải configuration này lên và điều chỉnh theo ý muốn. Thật ra không có bất cứ tài liệu nào có thể giải thích cặn kẽ từng chọn lựa cho mỗi cấu hình máy cả. Ở mức độ tái biên dịch một kernel, bạn cần hiểu cấu hình máy và những chọn lựa trong một configuration đến mức độ có thể quyết định chọn lựa những gì cho thích hợp. Bản phân phối Debian cũng lưu trữ các cấu hình biên dịch nhân trong thư mục /boot tương tự như bản phân phối RedHat. Các bản phân phối khác có một số tương đồng và dị biệt, bạn nên tham khảo thêm các hướng dẫn cụ thể cho bản phân phối mình đang dùng.

- Lưu trữ cấu hình biên dịch nhân cho lần biên dịch kế tiếp. Nếu vì lý do gì đó khiến giai đoạn biên dịch kernel bị hỏng, bạn cần xem xét đoạn báo lỗi sau cùng khi công cụ biên dịch (compiler) thoát ra với "tình trạng không thành công" (exit status is not 0). Thông thường compiler thoát ra nửa chừng vì cách chọn lựa cấu hình biên dịch nhân có những điểm không thích hợp và thoả mãn (liên hệ nhau). Những lỗi được báo trên console giúp bạn xác định trục trặc nằm trong khu vực nào của cấu hình biên dịch nhân. Bạn chỉ cần tải hồ sơ biên dịch đã được lưu trữ lần cuối cùng lên và vào thẳng khu vực bị sự cố để xem xét và điều chỉnh, thay vì phải thiết lập từ dầu để tránh va vào những lỗi khác. Mỗi khi điều chỉnh và thay đổi cấu hình biên dịch nhân, bạn lại tiếp tục lưu lại một bản và đặt tên cho nó một cách hợp lý (ví dụ kernel-2.4.26-1 cho configuration thứ nhất, kernel-2.4.26-2 cho configuration thứ nhì.....).

- Nếu bạn dùng một "vanilla" kernel, mã nguồn kernel được tải về từ kernel.org hoặc mirror site của nó (bài viết này tập trung chủ yếu vào "vanilla" kernel), sau khi hoàn thành bước make config hoặc make menuconfig hoặc make xconfig, cấu hình biên dịch nhân đã được bạn điều chỉnh và chọn lựa sẽ đưọc lưu trữ ở dạng dấu (hidden) ở ./.config (các hồ sơ và thư mục bắt đầu bằng dấu chấm . được xếp loại là hidden files, chỉ có ls -la mới thấy chúng). Lần kế tiếp, sau khi chạy một trong số lệnh trên và tiếp nhận các thay đổi thì cấu hình biên dịch nhân lại tự động viết chồng lên ./.config. Cho nên, bạn có thể lưu trữ hồ sơ ./.config thành một hồ sơ có tên khác trước khi điều chỉnh và chọn lựa lần kế tiếp.

- Ngoài make config, make menuconfig, make xconfig hoặc make gconfig (cho kernel 2.6.x series), bạn còn có thể dùng một lệnh khác cho cả kernel series 2.4.x và 2.6.x là: make oldconfig. make oldconfig là một trường hợp đặc biệt dùng để đọc và dùng các chọn lựa đã có sẵn trong ./.config mà không cho bạn cơ hội đi xuyên qua để điều chỉnh và chọn lựa. Trường hợp này rất tiện lợi nếu bạn đã điều chỉnh và chọn lựa thành công một cấu hình biên dịch nhân cho mình.

Kernel 2.6.x series còn có bốn target cho bước này:

make defconfig: tạo một cấu hình biên dịch nhân mới với chế độ mặc định cho mọi chọn lựa

make allmodconfig: tạo một cấu hình biên dịch nhân mới với chế độ chọn lựa các modules khi có thể được

make allyesconfig: tạo một cấu hình biên dịch nhân mới với chế độ tiếp nhận yes (Y) cho mọi chọn lựa

make allnoconfig: tạo một cấu hình biên dịch nhân mới với chế độ tiêp nhận no (N) cho mọi chọn lựa. Chế độ này sẽ tạo ra một kernel rất nhỏ và đơn giản.

Hiếm khi bạn điều chỉnh một cấu hình biên dịch nhân Linux lần đầu mà không hề bị lỗi trong khi biên dịch. Cách lưu trữ từng configuration cho mỗi lần hiệu chỉnh là cách tốt nhất để bảo đảm "lỗi" lần trước sẽ không tái diễn. Nếu bạn chỉ đơn giản dùng cấu hình biên dịch nhân có sẵn (như RedHat Linux chứa trong /boot) và không điều chỉnh gì cả thì ngoài mục đích vá lỗi, lối dùng này chẳng có tác dụng gì về mặt nâng cao hiệu năng của máy.

8. Các bước xây dựng

8.1 Bước tạo dependency, dọn dẹp và tạo kernel image

Bước này có thể chạy ba lệnh:

make dep

make clean

make bzImage

hoặc gom chung lại thành một nhóm:

make dep clean bzImage

Nếu bạn chạy dep, clean và bzImage riêng biệt thì phải trông chừng khi nào lệnh thứ nhất hoàn tất để tiếp tục chạy lệnh thứ nhì và tiếp theo. Nếu bạn chạy ba lệnh một lượt thì lệnh thứ nhì tự dộng nối tiếp lệnh thứ nhất và lệnh thứ ba nối tiếp lệnh thứ nhì. Bạn không cần phải chờ đợi.

- bước "dep" là bước tạo dependencies và các includes cần thiết cho kernel. Bước này có thể mất nhiều phút, tùy vào CPU của từng máy. Đối với kernel series 2.6.x, bước này không cần thiết nữa.

- sau khi xong bước "dep", bước "clean" dùng để dọn dẹp tất cả những "objects" vụn vặt, không còn cần thiết vì dependencies đã hoàn tất ở trên.

- bước kế tiếp "bzImage" là bước tạo kernel image. Đây là bước hết sức quan trọng trong ba bước này. Nếu có sự cố gì xảy ra thì phải quay lại điều chỉnh cấu hình biên dịch nhân và đi xuyên qua các bước "make dep", "make clean" trở lại (cần phải chạy một số lệnh dọn dẹp trước khi make dep clean bzImage trở lại, vấn đề này sẽ được đề cập trong phần 10). Trên máy chạy Athlon Thunderbird 1.4Ghz, tôi mất chừng 10 phút để hoàn thành bước này. Trên một máy Pentium 233MMX cũ, tôi mất hơn 40 phút mới hoàn thành bước tạo kernel image.

Nếu ba bước trên hoàn toàn thành công, bạn có thể tìm thấy "kernel image" nằm trong thư mục ./arch/$ARCH/boot, trong đó $ARCH là dòng phần cứng của kernel bạn muốn biên dịch. Nếu máy bạn thuộc dạng i386, bạn sẽ tìm thấy kernel image trong ./arch/i386/boot. Kernel image này đã được tạo ra nhưng chưa được cài và ở bước này, nó chỉ lưu trong thư mục trên cho các bước về sau.

Thật ra có thể tạo nhiều dạng "kernel image". Dạng kernel image được tạo từ "make bzImage" là dạng phổ biến nhất hiện nay vì nó nén kernel image tốt nhất và thích hợp với hầu hết các loại computer. Bạn cũng có thể dùng:

make zImage, make zDisk hoặc make zLilo để tạo kernel image nếu kernel dự kiến rất nhỏ và không cần kỹ thuật nén cao độ như "bz". Dùng các dạng này cũng thích hợp trong trường hợp máy của bạn quá cũ và có thể có sự cố với "bzImage". Chỉ cần nắm một cách khái quát như sau:

- Phần bz hoặc z đi trước các image ở trên chỉ định cho loại nén nào được dùng với kernel image.

- Phần Image hoặc Disk hoặc Lilo chỉ định cho "loại" kernel image.

- Kernel image này được xả nén "on-the-fly" trong quá trình boot vào Linux sau này.

Xuyên qua ba bước ở trên, bạn sẽ thấy vô số thông điệp chạy trên console (ở kernel 2.6.x thông điệp chạy trên console ít hơn rất nhiều). Bất cứ lỗi nào (error) được báo trong bước này đều phải điều chỉnh cấu hình biên dịch nhân và trở lại bước "make dep". Cho đến giai đoạn này, lý do gây ra lỗi thường là:

- đồ nghề dùng để biên dịch không đúng phiên bản (xem phần 4.1 và 4.2 cho kernel series này bạn đang biên dịch)

- điều chỉnh sai hoặc thiếu một số chọn lựa nào đó trong cấu hình biên dịch nhân. Xem lỗi báo trước khi compiler thoát ra để xác định lỗi này thuộc phần nào trong cấu hình biên dịch nhân mà chỉnh lại cho thích hợp, nên dùng phương pháp tải và lưu trữ cấu hình biên dịch nhân đã đề cập trong phần 7.2.2 ở trên

- cấu hình máy quá thấp (memory / diskspace) không đủ để thực hiện ba bước ở trên. Nếu gặp sự cố này, nên nâng cấp máy hoặc dùng một máy khác để build kernel cho máy này.

Linux kernel 2.6.x series đơn giản hoá chỉ với một target "make all". Target này bao gồm luôn phần "make modules" trong bước 8.2 kế tiếp.

8.2 Bước tạo modules và cài modules

Bước này có thể chạy hai lệnh:

make modules

make modules_install

hoặc gom chung lại thành một dòng:

make modules modules_install

Điểm khác biệt giữa cách chạy hai lệnh riêng biệt hoặc chạy chung một dòng lệnh ở đây nằm ở chỗ:

- bạn có thể chỉ muốn biên dịch modules cho kernel mà không muốn cài (install) trên máy ngay sau khi các modules được biên dịch xong,

- hoặc bạn chỉ muốn biên dịch modules trên máy này rồi sẽ mang qua máy khác để cài.

Thông thường "make modules modules_install" đi chung vì ít người build modules trên một máy rồi mang đi cài trên một máy khác. Nếu chạy hai lệnh này một lượt, bạn phải chạy ở chế độ "super user" không thì modules không install được vì chỉ có root (super user) mới có thể "install" các modules vừa được biên dịch. Nếu bạn tách rời hai lệnh trên thì các lệnh tách rời như sau:

make modules # chạy bằng user account bình thường

su # chuyển sang chế độ "super user"

[enter password]

make modules_install # cài modules vừa biên dịch xong.

Bước "make modules" là bước biên dịch và tạo ra các modules (mà bạn đã chọn ở dạng M trong quá trình chỉnh lý cấu hình biên dịch nhân). Các modules đã được biên dịch sẽ được lưu trữ trong các thư mục thích ứng với từng nhóm "drivers" trong cây mã nguồn (kernel source tree). Giai đoạn này là giai đoạn biên dịch lâu nhất trong trọn bộ quá trình compiler thực sự biên dịch mã nguồn của kernel. Trên một máy chạy Athlon Thunderbird 1.4Ghz, bước này mất chừng 25 phút. Trong khi đó cùng số lượng modules cần biên dịch chạy trên máy Pentium 233MMX mất chừng trên 4 giờ đồng hồ.

Bước "make modules_install" sẽ "cài" các modules vừa được biên dịch vào thư mục /lib/modules/<kernel_version>. Nếu liệt kê thư mục này (ls), bạn sẽ thấy ít nhất một thư mục chứa modules cho kernel đang chạy trên máy hoặc nhiều thư mục cho nhiều phiên bản kernel trước đây (có từ quy trình cập nhật kernel bằng rpm hoặc quy trình nào đó tuỳ theo bản phân phối, hoặc từ quy trình biên dịch kernel tương tự như bài viết này). Khi boot Linux bằng một phiên bản kernel nào đó có trên máy, các modules thuộc kernel này (trong thư mục thích ứng với kernel version) sẽ được ứng tải.

Đối với kernel 2.4.x series, bạn có thể tham khảo chi tiết thông tin về modules, cách biên dịch modules tổng quát và cách xử dụng modules (thuộc user space) trong hồ sơ ./Documentation/modules.txt thuộc mã nguồn kernel bạn dự định biên dịch.

Đối với kernel 2.6.x series, bạn có thể tham khảo chi tiết thông tin về modules, cách biên dịch modules tổng quát và cách xử dụng modules (thuộc user space) trong ba hồ sơ ./Documentation/kbuild/modules.txt, ./Documentation/networking/net-modules.txt và ./Documentation/sound/oss/README.modules thuộc mã nguồn kernel bạn dự định biên dịch. Riêng với kernel 2.6.x series, bước "make modules" có thể thực hiện từ "make all" và bước "make modules_install" chỉ thực hiện riêng (ở chế độ super user) để cài các modules đã được biên dịch.

8.3 Tách rời mã nguồn và hồ sơ output trên kernel 2.6.x series

Nếu bạn đang dùng kernel 2.4.x series thì không cần tham khảo thông tin của mục 8.3. Những thông tin trong mục này chỉ giới thiệu thêm một số tiện ích hữu dụng cho quy trình chuẩn bị và biên dịch kernel 2.6.x.

8.3.1 "make help", một tiện ích mới trên kernel 2.6.x series

Ngoài những điểm khác biệt trong các make target đã được đề cập ở phần 8.1 và 8.2, trên kernel 2.6.x series, bạn có thể xử dụng một tiện ích khá hay mà kernel 2.4.x không có đó là phần "help" trước khi "make" mã nguồn của Linux kernel. Tất nhiên bạn phải chạy lệnh này sau khi vào trong thư mục chứa mã nguồn Linux kernel:

$ cd /usr/src/linux-2.6.6 (dùng kernel 2.6.6 trong trường hợp này)

$ make help sẽ cho thông tin trợ giúp như sau:

bash-2.05b$ make help

Cleaning targets:

clean - remove most generated files but keep the config

mrproper - remove all generated files + config + various backup files

Configuration targets:

oldconfig - Update current config utilising a line-oriented program

menuconfig - Update current config utilising a menu based program

xconfig - Update current config utilising a QT based front-end

gconfig - Update current config utilising a GTK based front-end

defconfig - New config with default answer to all options

allmodconfig - New config selecting modules when possible

allyesconfig - New config where all options are accepted with yes

allnoconfig - New minimal config

Other generic targets:

all - Build all targets marked with [*]

* vmlinux - Build the bare kernel

* modules - Build all modules

modules_install - Install all modules

dir/ - Build all files in dir and below

dir/file.[ois] - Build specified target only

rpm - Build a kernel as an RPM package

tags/TAGS - Generate tags file for editors

cscope - Generate cscope index

Documentation targets:

Linux kernel internal documentation in different formats:

sgmldocs (SGML), psdocs (Postscript), pdfdocs (PDF)

htmldocs (HTML), mandocs (man pages, use installmandocs to install)

Architecture specific targets (i386):

* bzImage - Compressed kernel image (arch/i386/boot/bzImage)

install - Install kernel using

(your) ~/bin/installkernel or

(distribution) /sbin/installkernel or

install to $(INSTALL_PATH) and run lilo

bzdisk - Create a boot floppy in /dev/fd0

fdimage - Create a boot floppy image

make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build

make O=dir [targets] Locate all output files in "dir", including .config

make C=1 [targets] Check all c source with checker tool

Execute "make" or "make all" to build all targets marked with [*]

For further info see the ./README file

bash-2.05b$

Thông tin trên cho thấy "Makefile" chính của kernel 2.6.x series bao gồm các mục tiêu (target) biên dịch khi chạy make help. Với thông tin này, bạn có thể chọn các target make theo ý muốn mà không phải kiểm tra trong "Makefile" như với kernel 2.4.x series (kernel 2.4.x series không có "make help" như kernel 2.6.x series và kernel 2.4.x series không có nhiều make targets như kernel 2.6.x series). Điểm đặt biệt cần quan tâm là ba chọn lựa cuối trong thông tin "make help" cung cấp:

make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build

make O=dir [targets] Locate all output files in "dir", including .config

make C=1 [targets] Check all c source with checker tool

Một trong những chọn lựa quan trọng ở đây là nó cho phép bạn lưu trữ trọn bộ các hồ sơ output trong quá trình biên dịch vào một thư mục riêng biệt thay vì chứa chung với mã nguồn của kernel.

8.3.2 Tách rời mã nguồn và output files

Kernel 2.6.x series cho phép bạn tách rời mã nguồn của kernel và các hồ sơ output được tạo trong quá trình compile, các hồ sơ dấu (hidden) như .config, .depend.... trong các bước đề cập ở phần 7 và 8 cũng sẽ được lưu trữ ở thư mục nào bạn muốn dùng cho output files. Với phương tiện này, mã nguồn và các hồ sơ output sẽ không xen kẽ chung. Điểm quan trọng cần nhớ là khi đã dùng chọn lựa này thì phải dùng cho các bước "make" khác trong suốt quá trình biên dịch. Ví dụ, bạn có thể khởi đầu bằng:

make O=/path/to/output xconfig

thì các bước kế tiếp sẽ là:

make O=/path/to/output all (target "all" bao gồm "dep, clean, bzImage, modules"), và

make O=/path/to/output modules_install (chạy lệnh này bằng super user để cài modules của kernel).

Biên dịch Linux kernel - phần 4

9. Cài kernel

Phần này giới thiệu hai cách cài kernel vừa biên dịch và chỉnh định boot loader.

9.1 Cài qua "make install"

Ít người dùng đến chức năng "make install" này vì một số bản phân phối không có các tiện ích cần thiết để thực hiện trọn vẹn bước này. "make install" tiện lợi và an toàn hơn cài bằng tay vì nó thao tác các bước cần thiết để thiết lập kernel mới trên hệ thống. Các bước này bao gồm quy trình lưu trữ kernel cũ (trong thư mục /boot), copy kernel image mới, copy System.map mới, điều chỉnh boot loader configuration (lilo.conf hoặc grub.conf) và cập nhật boot loader.

Bước "make install" dựa trên hồ sơ Makefile và install.sh, một shell script thuộc thư mục ./arch/$ARCH/boot. Shell script install.sh "gọi" một số shell script khác như /sbin/installkernel và /sbin/new-kernel-pkg, ngoài ra các shell scripts này còn dựa vào một binary có tên là "grubby" để tạo thông tin trong grub.conf nếu bạn dùng GRUB. Các shell scripts "installkernel" và "new-kernel-install" thuộc gói mkinitrd của RedHat, các bản phân phối khác có những ứng dụng tương tự. Nếu bản phân phối bạn dùng không có gói tương tự, bạn phải cài kernel bằng tay (phần 9.2) hoặc tạo các script tương tự để thực hiện bước này. Trong khuôn khổ giới hạn của bài viết, tôi không đi sâu vào vấn đề tạo các script tiện ích.

Để cài Linux kernel mới, bạn chỉ đơn giản chạy lệnh # make install ở chế độ super user từ trong thư mục chứa mã nguồn của Linux kernel. Sau khi hoàn tất bước "make install" bạn nên kiểm tra lại cấu hình của boot loader trên máy và chạy các lệnh tương ứng (nếu cần) để chỉnh định boot loader cho chính xác.

9.1.1 Đối với GRUB

Ví dụ bạn có hai phiên bản kernel trên máy 2.4.20 (phiên bản đang chạy) và 2.4.26 (phiên bản vừa được biên dịch), sau khi chạy "make install", grub.conf có chi tiết tương tự như sau:

{b}default=1{/b}

timeout=20

splashimage=(hd0,0)/boot/grub/splash.xpm.gz

title Linux (2.4.26)

root (hd0,0)

kernel /boot/vmlinuz-2.4.26 ro root=/dev/hda1

initrd=/boot/initrd-2.4.26.img

title Linux (2.4.20)

root (hd0,0)

kernel /boot/vmlinuz-2.4.20 ro root=/dev/hda1

initrd=/boot/initrd-2.4.20.img

- chi tiết cần chú ý là biến default. Trong ví dụ trên, bạn có hai kernel trong cấu hình GRUB cho các phiên bản 2.4.26 và 2.4.20. Nếu bạn muốn boot kernel 2.4.26 theo mặc định thì giá trị của default phải là 0 (grub đếm thứ tự các kernel từ giá trị 0, không phải từ giá trị 1). Khi chạy "make install", các tiện ích của "install" tự động đưa vào các chi tiết thuộc kernel mới vào cấu hình GRUB. Tuy nhiên, giá trị default vẫn giữ ở giá trị chỉ định cho kernel hiện đang hoạt động trên máy. Bạn cần chỉnh giá trị này để buộc boot loader tải lên phiên bản kernel mới. Một chi tiết hết sức quan trọng bạn cần chú ý là giá trị root (hdX,Y). Nếu GRUB đã được cài trong lúc cài đặt hệ thống từ CD và đã hoạt động hoàn chỉnh, bạn không nên thay đổi giá trị này. Giá trị này chỉ cần thay đổi nếu bạn thêm đĩa cứng và thay đổi các partitions trên máy.

- sau khi chỉnh định và lưu trữ grub.conf thích hợp, bạn chỉ cần tái khởi động máy. Nếu bạn dùng GRUB làm boot loader thì công tác tái biên dịch nhân Linux hoàn thành ở đây.

- giải pháp phòng bị trường hợp không thể boot vào kernel mới rất đơn giản nếu dùng GRUB làm boot loader. Bạn chỉ cần thêm một dòng fallback 1 vào cấu hình grub.conf là đủ. Chỉnh định này cho GRUB boot loader biết nếu dùng "default=0" để boot kernel mới nhất (2.4.26 trong ví dụ này) nhưng không thành công vì lý do nào đó thì thử boot lại với kernel cũ hơn (2.4.20). Xem thêm ở phần 10 nếu không thể boot được vào Linux vì boot loader bị hỏng.

9.1.2 Đối với LILO

Ví dụ bạn có hai phiên bản kernel trên máy 2.4.20 (phiên bản đang chạy) và 2.4.26 (phiên bản vừa được biên dịch), sau khi chạy "make install", lilo.conf có chi tiết tương tự như sau:

timeout=50

{b}default=linux{/b}

boot=/dev/hda

map=/boot/map

install=/boot/boot.b

message=/boot/message

image=/boot/vmlinuz-2.4.20

initrd=/boot/initrd-2.4.20.img

root=/dev/hda1

label=linux-2.4.20

read-only

image=/boot/vmlinuz

initrd=/boot/initrd-2.4.26.img

root=/dev/hda1

{b}label=linux{/b}

read-only

- chi tiết cần chú ý là biến default. Trong ví dụ trên, bạn có hai kernel trong cấu hình LILO cho các phiên bản 2.4.26 và 2.4.20. Nếu bạn muốn boot kernel 2.4.26 thì giá trị của default phải là giá trị label thuộc kernel nào bạn muốn dùng. Trong trường hợp này, label có giá trị là linux chỉ định cho kernel 2.4.26. Khi chạy "make install", các tiện ích của "install" đưa vào các chi tiết của kernel mới vào cấu hình LILO. Ở đây vmlinuz là symbolic link của hồ sơ vmlinuz-2.4.26. Bạn nên kiểm tra lại giá trị default để bảo đảm boot loader sẽ tải kernel vừa biên dịch khi boot.

- sau khi chỉnh định và lưu trữ lilo.conf theo ý muốn, bạn phải chạy lệnh:

# /sbin/lilo và chú ý trường hợp hệ thống báo lỗi trong bước cài lilo làm boot loader. Nếu có, điều chỉnh cho chính xác và thực hiện lại lệnh trên. Với ví dụ trên, bạn sẽ được báo kết quả trên console tương tự như:

Added linux*

Added linux-2.4.20

Giá trị nào đi kèm với dấu hoa thị chỉ định cho kernel được boot theo mặc định.

- với LILO, giải pháp đơn giản nhất phòng bị trường hợp không thể boot vào kernel mới mang tính tạm thời. Trước khi tái khởi động máy dùng lệnh như sau:

# /sbin/lilo -R linux

rồi chạy

# reboot

Nên nhớ lệnh trên được đưa ra như một ví dụ cho kernel 2.4.20 và 2.4.26 với cấu hình boot loader như trên, bạn phải điều chỉnh đúng phiên bản kernel bạn đang biên dịch.

Lệnh thứ nhất cho LILO biết lần kế tiếp máy tái khởi động thì thử dùng kernel 2.4.26. Nếu không thành công cũng không chỉnh định cho kernel 2.4.26 làm kernel boot theo mặc định và lần boot kế tiếp sẽ dùng kernel 2.4.20 (kernel này chắc chắn phải làm việc được vì nó đã dùng để biên dịch kernel 2.4.26).

Lệnh thứ nhì chỉ đơn giản ra lệnh cho máy tái khởi động.

Nếu dùng lệnh "/sbin/lilo -R linux-x.xx.xx" và boot vào kernel mới thành công thì sau khi boot vào, bạn cần chỉnh định cho kernel x.xx.xx làm mặc định rồi mới chạy "/sbin/lilo -v" như đã nói ở trên (trong phần biến "default" của lilo.conf).

9.2 Cài qua các bước bằng tay

Các bước cài "bằng tay" tương tự như các bước "make install" ở trên nhưng được thao tác "bằng tay". Thật ra quy trình này rất đơn giản, điều bạn cần lưu ý là phải thực hiện chính xác để tránh những trở ngại trong bước này và trong giai đoạn boot vào kernel mới.

9.2.1 Tạo initrd

Trường hợp bạn biên dịch các drivers quan trọng ở dạng modules có liên hệ đến quy trình boot của Linux (như SCSI driver, RAID driver, các loại filesystem mà root filesystem dùng như ext3, jbd...) thì chắc chắn bạn phải cần đến initrd (INITial Ram Disk). Mục đích chính của initrd là phương tiện tải sẵn các driver cần thiết cho kernel trong quá trình boot. Nếu không muốn dùng initrd, bạn phải biên dịch các driver trực tiếp vào kernel (hay còn gọi là static compile). Nên chú ý một số bản phân phối Linux không dùng initrd, họ khuyến khích biên dịch các driver liên hệ đến quy trình boot trực tiếp vào kernel. Muốn tham khảo thêm chi tiết về RAM disk cho trường hợp này, xem <KERNEL_SRC>/Documentation/ramdisk.txt.

Quy trình tạo initrd rất đơn giản, chỉ cần chạy lệnh:

# /sbin/mkinitrd /boot/initrd-<KERNEL_VERSION>.img <KERNEL_VERSION>, trong đó:

- Tham số thứ nhất /boot/initrd-<KERNEL_VERSION>.img chỉ định cho hồ sơ và thư mục chứa hồ sơ initrd. Thông thường initrd của kernel được chứa trong thư mục /boot cùng với các thông tin và hồ sơ khác cần thiết cho quy trình boot.

- Tham số <KERNEL_VERSION> thứ nhì chính là kernel nào bạn muốn tạo initrd cho nó. Tất nhiên thư mục chứa các modules cho kernel version này phải hiện hữu ở /lib/modules/, nếu không bạn sẽ được system báo lỗi.

Tùy bản phân phối, mkinitrd đòi hỏi thêm các thông số cụ thể để chỉ đường dẫn đến kernel. Nếu gặp trở ngại trong bước tạo mkinitrd bạn nên tham khảo tài liệu cụ thể cho bản phân phối mình đang dùng hoặc tối thiểu là xem man mkinitrd và tài liệu <KERNEL_SRC>/Documentation/initrd.txt để xem thêm các thông tin cần thiết.

Một điểm đáng chú ý là từ kernel 2.5.x (development kernel) trở đi, initramfs được phát triển với mục đích hỗ trợ và sẽ đi đến chỗ thay thế initrd (init ram disk). Ưu điểm nổi bật của initramfs là nó có thể chứa các bộ lưu trữ ở dạng cpio "newc" hoặc "crc" (được nén hoặc không được nén). initramfs cho đến nay chưa phổ biến và ứng dụng rộng rãi trên các bản phân phối Linux. Tuy nhiên, hướng phát triển và ứng dụng initramfs có vẻ đầy hứa hẹn.

9.2.2 Copy kernel và System.map

Sau khi hoàn thành bước "make modules_install" (phần 8.2), lúc này bạn đã có trọn bộ các bộ phận cần thiết cho kernel mới bao gồm kernel image và các modules thuộc kernel này.

- copy bzImage từ <KERNEL_SRC>/arch/i386/boot/ đến thư mục /boot, ví dụ:

# cp /usr/src/linux-2.4.26/arch/i386/boot/bzImage /boot/bzImage-2.4.26

install script của RedHat và một số phân phối khác bao gồm bước copy bzImage thành vmlinuz, bạn có thể thực hiện (hay không tùy ý, bước này tương tự như bước ở trên) như sau:

# cp /usr/src/linux-2.4.26/arch/i386/boot/bzImage /boot/vmlinuz-2.4.26

kế tiếp là xoá symbolic link cũ (nếu có) của vmlinuz trong thư mục /boot:

# rm -f /boot/vmlinuz

và sau đó tạo symbolic link mới cho vmlinuz-2.4.26 thành:

# ln -s /boot/vmlinuz-2.4.26 /boot/vmlinuz

Tất nhiên bạn phải điều chỉnh lại cấu hình boot loader để thích ứng với cách gọi "bzImage" hoặc "vmlinuz" này cho giá trị image (trong lilo.conf) hoặc giá trị kernel (trong grub.conf). Cách dùng và cách gọi bzImage và vmlinuz tạo khá nhiều bối rối cho người dùng Linux khi tiếp cận quy trình biên dịch kernel. Một số bản phân phối Linux dùng bzImage, một số khác lại dùng vmlinuz. Dù gì đi chăng nữa, đây cũng chỉ là cách dùng và cách gọi; bạn nên dùng theo cách bản phân phối Linux nào có trên máy.

- phần còn lại là bước copy hồ sơ System.map:

# cp /usr/src/linux-2.4.26/System.map-2.4.26 /boot/System.map-2.4.26

kế tiếp là xoá symbolic link cũ của System.map trong thư mục /boot:

# rm -f /boot/System.map

và sau đó, tạo symbolic link mới cho System.map:

# ln -s /boot/System.map-2.4.26 /boot/System.map

9.2.3. Chỉnh bootloader config

9.2.3.1 Nếu bootloader là GRUB

Ví dụ bạn có hai phiên bản kernel trên máy 2.4.20 (phiên bản đang chạy) và 2.4.26 (phiên bản vừa được biên dịch) thì grub.conf tương tự như sau:

default=0

timeout=20

splashimage=(hd0,0)/boot/grub/splash.xpm.gz

title Linux (2.4.20)

root (hd0,0)

kernel /boot/vmlinuz-2.4.20 ro root=/dev/hda1

initrd=/boot/initrd-2.4.20.img

Chỉnh thành:

default=0

timeout=20

splashimage=(hd0,0)/boot/grub/splash.xpm.gz

title Linux (2.4.26)

root (hd0,0)

kernel /boot/vmlinuz ro root=/dev/hda1

initrd=/boot/initrd-2.4.26.img

title Linux (2.4.20)

root (hd0,0)

kernel /boot/vmlinuz-2.4.20 ro root=/dev/hda1

initrd=/boot/initrd-2.4.20.img

Sau khi đã lưu trữ (save) cấu hình của /etc/grub.conf ở trên (/etc/grub.conf là symbolic link đến /boot/grub/menu.1st) và tái khởi động máy để bắt đầu dùng kernel vừa được biên dịch. Nếu bạn dùng GRUB làm boot loader thì công tác tái biên dịch nhân Linux hoàn thành ở đây. Nên lưu ý trong ví dụ này, tôi dùng vmlinuz thay vì dùng bzImage, bạn nên chọn lựa theo ý và điều chỉnh cho phù hợp trong grub.conf.

Đối với giải pháp phòng bị trường hợp không thể dùng GRUB để boot vào kernel mới, xem chi tiết ở phần 9.1.1 ở trên.

9.2.3.2 Nếu bootloader là LILO

Ví dụ bạn có hai phiên bản kernel trên máy 2.4.20 (phiên bản đang chạy) và 2.4.26 (phiên bản vừa được biên dịch) thì lilo.conf tương tự như sau:

timeout=50

default=linux

boot=/dev/hda

map=/boot/map

install=/boot/boot.b

message=/boot/message

image=/boot/vmlinuz

initrd=/boot/initrd-2.4.20.img

root=/dev/hda1

label=linux

read-only

Chỉnh /etc/lilo.conf để cài kernel mới (2.4.26 cho ví dụ ở đây), bạn có /etc/lilo.conf như sau:

timeout=50

{b}default=linux{/b}

boot=/dev/hda

map=/boot/map

install=/boot/boot.b

message=/boot/message

image=/boot/vmlinuz-2.4.20

initrd=/boot/initrd-2.4.20.img

root=/dev/hda1

{b}label=linux-2.4.20{/b}

read-only

image=/boot/vmlinuz

initrd=/boot/initrd-2.4.26.img

root=/dev/hda1

{b}label=linux{/b}

read-only

Sau khi đã lưu trữ (save) cấu hình của /etc/lilo.conf ở trên, chạy lệnh:

# /sbin/lilo để đăng ký kernel mới cho LILO boot loader.

Đối với giải pháp phòng bị trường hợp không thể dùng LILO để boot vào kernel mới, xem chi tiết ở phần 9.1.2 ở trên.

10. Tái khởi động máy và chỉnh lý nếu gặp trục trặc

Tới đây, bạn cần tái khởi động máy để boot vào kernel mới. Nếu không có gì trở ngại, máy sẽ boot vào Linux bình thường. Bạn có thể kiểm lại xem kernel mình đang chạy có đúng phiên bản vừa được biên dịch hay không bằng cách chạy:

$ uname -r

hoặc,

$ cat /proc/version

Nếu kết quả báo phiên bản kernel cũ thì có nghĩa boot loader (LILO hoặc GRUB) đã không boot kernel vừa được biên dịch. Bạn nên kiểm tra lại boot configuration (lilo.conf hoặc grub.conf) cho đúng theo chi tiết đã nêu ở trên.

10.1 Bị treo khi bootloader đang boot vào linux

Trở ngại trong giai đoạn boot loader chuẩn bị boot vào Linux thông thường do cấu hình boot loader ấn định không đúng và boot loader được cài lên không đúng boot partition hoặc MBR bị hỏng (hiếm thấy trong quá trình tái biên dịch và cài kernel mới nếu thực hiện đúng quy cách). Trong trường hợp này, bạn phải:

- dùng đến đĩa mềm "cấp cứu" được tạo ở phần 6.1 để boot vào Linux

- Đến giai đoạn này bạn hẳn phải biết vị trí của root partition (/) trên đĩa cứng để mount partition của đĩa cứng:

# mount /dev/hdXy /mount/point/somewhere, trong đó X là ví trí đĩa cứng trên máy, y là vị trị root partition trên đĩa cứng này.

- đổi root (chroot) trở thành root partition của đĩa cứng:

# chroot /mount/point/somewhere, trong đó /mount/point/somewhere là nơi đĩa cứng của bạn được mount.

- kiểm tra lại cấu hình của boot loader và cài lại boot loader cho máy (xem phần 9.1.1 hoặc 9.1.2 tùy theo boot loader bạn dùng là GRUB hay LILO). Điểm cần chú ý ở đây cho GRUB boot loader là bạn phải chạy lệnh:

# /sbin/grub-install /dev/hdX, trong đó /dev/hdX là disk nào chứa MBR cho hệ thống (thường là đĩa đầu tiên trên máy - Primary Master). Lệnh trên sẽ tái thiết lập boot record và loại bỏ các trường hợp MBR bị hỏng. Tương tự cho LILO, bạn phải chạy lệnh:

# /sbin/lilo.

10.2 Bị treo trong quá trình kernel được load

Nếu bạn vướng vào các trở ngại trong giai đoạn kernel đang được tải lên thông thường là do các drivers tối cần thiết để mount filesystems trên máy bị thiếu. Giả sử bạn dùng ext3 cho root partition (/) chứa kernel. Để có thể mount root partition này, ext3 module phải được biên dịch và initrd phải tải module này lên. Tương tự ứng dụng cho các trường hợp dùng filesystem khác và cũng thiếu module.

Trong trường hợp này, bạn cần ghi xuống phần lỗi được báo trong khi boot vào kernel mới để xác định lỗi này thuộc phần nào của cấu hình biên dịch nhân Linux và từ đó điều chỉnh lại và tái biên dịch lại cho thích ứng. Nói một cách tổng quát, bạn phải:

- tái khởi động lại máy và boot vào phiên bản cũ của kernel (hoặc boot loader sẽ boot vào phiên bản cũ của kernel nếu bạn dùng biện pháp trù bị đã được đề cập ở phần 9.1.1 và 9.1.2 ở trên)

- chọn lựa và chỉnh định cấu hình biên dịch nhân Linux lại (xem phần 7.2.2 để tránh lặp lại bước lựa chọn cấu hình một cách không cần thiết).

- thực hiện lại các bước đã nêu ra trong phần 8 và 9 ở trên

11. Vá và biên dịch kernel

Mã nguồn của Linux kernel thường được "vá" rồi tái biên dịch nhiều hơn là được biên dịch từ trọn bộ mã nguồn tải về từ kernel.org nếu bạn đã quen thuộc với quy trình tái biên dịch hoặc bạn có nhu cầu phải cập nhập kernel của máy thường xuyên. Tại sao lại cần "vá"? Mã nguồn của Linux kernel cần được vá vì các lý do thường gặp như sau:

- mã nguồn của Linux kernel được cập nhật. Bạn đã có sẵn mã nguồn của Linux kernel (cũ hơn) trên máy. Muốn nâng cấp phiên bản của Linux kernel, bạn chỉ cần tải các "miếng vá" về để vá (thay vì phải tải trọn bộ mã nguồn của Linux kernel cho phiên bản mới).

- một số "drivers" được cập nhật. Để xử dụng các driver mới này (và các drivers này cần được biên dịch để nối với các thư viện hiện hành trên máy), bạn chỉ cần tải các "miếng vá" của những drivers này để vá Linux kernel và tái biên dịch chúng.

11.1 Các điểm quan trọng trước khi vá

Tương tự như phần 6.2, 6.3 và 6.4 ở trên, quy trình tải các miếng vá (patch) cho Linux kernel y hệt như tải trọn bộ gói mã nguồn của Linux kernel. Điểm khác biệt là bạn phải tải các hồ sơ khởi đầu bằng patch và chọn cho đúng các patch cần thiết cho kernel cần được patch.

Điểm tối yếu cần ghi nhớ là khi vá mã nguồn của Linux kernel, bạn phải vá đúng thứ tự và đầy đủ các miếng vá cho đến đúng phiên bản cần có. Ví dụ, bạn đang có phiên bản kernel là 2.4.20 trên máy và bạn muốn tái biên dịch phiên bản kernel của máy trở thành 2.4.26. Thay vì tải trọn bộ mã nguồn của kernel 2.4.26 và biên dịch lại (như đã trình bày trong suốt bài viết này), bạn có thể tải các bản vá 2.4.21, 2.4.22, 2.4.23, 2.4.24, 2.4.25 và 2.4.26 về máy. Tổng cộng dung lượng các bản vá này chỉ là một phần rất nhỏ so với trọn bộ gói mã nguồn 2.4.26. Tất nhiên bạn đã có mã nguồn của kernel 2.4.20 trên máy không thì không thể vá được.

11.2 Tải, xả và vá

Các miếng vá thường được nén ở hai dạng: .gz hoặc .bz2 như gói mã nguồn. Bạn có thể tùy chọn và có thể tải các miếng vá này về bất cứ nơi nào trên máy. Sau khi tải chúng về, bạn có thể thực hiện quy trình tương tự như sau:

giả định các bản vá được nén ở dạng .bz2, nơi chứa mã nguồn của Linux kernel ở /usr/src và thực tính của các patch này đã được kiểm tra. Trong ví dụ này, giả định phiên bản đang dùng trên máy là 2.4.20 và phiên bản cần được vá sẽ là 2.4.26

a)

# chuyển vào thư mục /usr/src

$ cd /usr/src

# xả nén các patch ở dạng .bz2 vào thư mục /usr/src. Lặp lại cho đến khi xả hết các patch cần được vá

$ tar xfvj /path/to/patch/patch-x.xx.xx ./

c)

# dọn dẹp sạch sẽ mã nguồn kernel hiện có trên máy, giả định phiên bản mã nguồn hiện có là 2.4.20

cd ./kernel-2.4.20

make mrproper

d)

# lưu một bản mã nguồn kernel 2.4.20 trong thư mục /usr/src phòng bị cho sự cố trong quá trình vá (nếu bạn không lưu một bản mã nguồn nguyên thủy của kernel 2.4.20 trên máy, hoặc bản mã nguồn 2.4.20 này cũng đã được vá trước đây)

tar cvf ../linux-2.4.20.tar ./

# vá các miếng vá theo đúng thứ tự và theo dõi bất cứ lỗi nào được báo

$ patch -p1 < ../patch-2.4.21

$ patch -p1 < ../patch-2.4.22

$ patch -p1 < ../patch-2.4.23

$ patch -p1 < ../patch-2.4.24

$ patch -p1 < ../patch-2.4.25

$ patch -p1 < ../patch-2.4.26

hoặc thực hiện kiểu "lười" như sau:

# tạo một biến PATCH tạm thời chứa tên các patch cần patch theo đúng thứ tự, tách rời bằng phím trống (space)

$ export PATCH="patch-2.4.21 patch-2.4.22 patch-2.4.23 patch-2.4.24 patch-2.4.25 patch-2.4.26"

# chạy vòng lặp

$ for item in $PATCH; do patch -p1 < ../$item; done

Nếu trong khi vá không có gì trở ngại, bạn sẽ thấy các thông tin tương tự:

patching file xxx

patching file yyy

....

cho đến khi kết thúc.

Nếu trong khi vá bị báo lỗi, bạn phải ngưng bước vá (ctrl-C) và kiểm tra xem bạn có dùng đúng bản vá và thực hiện các bản vá đúng thứ tự phiên bản hay không. Không nên tiếp tục với bước vá khi gặp lỗi vì chắc chắn bạn sẽ gặp trở ngại trong giai đoạn biên dịch sau này. Để tránh các trở ngại về sau, nếu bị báo lỗi trong khi vá, cách tốt nhất bạn nên xoá trọn bộ thư mục chứa mã nguồn của Linux kernel (đang được vá và bị lỗi) và xả gói mã nguồn nguyên thủy hoặc gói bạn vừa lưu trữ ở trên rồi thử lại.

f)

# xoá thư mục chứa mã nguồn vừa vá và bị trục trặc, thư mục linux-2.4.20 được dùng như một ví dụ ở đây

$ cd /usr/src

$ rm -rf ./linux-2.4.20

# xả gói mã nguồn được lưu trữ ở trên

$ tar xvf linux-2.4.20

$ cd ./linux-2.4.20

và sau đó lặp lại bước vá (bước e) theo đúng thứ tự các miếng và.

Sau khi vá thành công, bạn nên thực hiện hai bước kế tiếp như sau trước khi bắt tay vào việc chuẩn bị cấu hình biên dịch nhân Linux và biên dịch mã nguồn:

h)

# đổi tên thư mục chứa mã nguồn cho đúng phiên bản đã được vá (giúp bạn nhận diện phiên bản của mã nguồn đang có trên máy đã được vá tới phiên bản nào)

$ cd /usr/src

$ mv ./linux-2.4.20 ./linux-2.4.26

# chỉnh giá trị "VERSION" trong Makefile chính của mã nguồn Linux. Thư mục chứa mã nguồn lúc này đã được đổi tên thành linux-2.4.26

$ vi ./linux-2.4.26/Makefile

Vài dòng đầu của hồ sơ Makefile này chứa các thông tin tương tự như sau (nếu mã nguồn của phiên bản 2.4.20 được xả từ gói mã nguồn nguyên thủy):

VERSION = 2

PATCHLEVEL = 4

SUBLEVEL = 20

EXTRAVERSION =

Bạn cần đổi giá trị SUBLEVEL thành 26 và lưu hồ sơ Makefile này (cho ví dụ này, hoặc bất cứ phiên bản nào bạn đã vá tới - xem thêm chi tiết về quy định phiên bản Linux kernel ở phần 3). Giá trị phiên bản 2.6.26 lấy từ hồ sơ Makefile sẽ được dùng trong quá trình biên dịch và cài đặt kernel về sau. Nếu bạn không điều chỉnh giá trị "VERSION" ở bước này, bước cài kernel về sau sẽ viết chồng lên kernel 2.4.20 đang có trên máy. Nói về mặt kỹ thuật việc viết chồng lên không có gì trở ngại. Tuy nhiên, nếu bạn gặp trục trặc sau khi đã biên dịch kernel nhưng không boot vào được thì sự thể sẽ rất phức tạp vì bạn không còn bản kernel chạy được trên máy.

Tới đây bạn đã thực hiện thành công bước vá mã nguồn Linux kernel và các bước phòng bị cần thiết. Bạn có thể tiếp tục với công việc tái biên dịch Linux kernel như đã nói trên.

Bạn đang đọc truyện trên: Truyen2U.Pro