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).
<kết thúc phần 3>. Mời các bạn đọc tiếp
/hvaonline/posts/list/88.html.
<hnd, vninformatics.com / diendantinhoc.net - 06/06/2004>
Tác giả : Conmale (hnd)
Nguồn : www.diendantinhoc.net