Linux Kernel in a Nutshell · Chương 7 · Tùy biến nhânChapter 7 · Customizing a Kernel
Mức đọcLevel

Phần II · Tùy biến lớn · Chương 7Part II · Major Customizations · Chapter 7

Hỏi chính cái máy xem nó cần driver nào Để máy tự nói nó cần gì Ask the machine which drivers it needs

Sáu chương đầu dạy bạn quy trình: lấy mã nguồn, cấu hình, dựng, cài, nâng cấp. Phần II của sách — gồm đúng hai chương 7 và 8 — chuyển sang câu hỏi khó hơn: cấu hình cái gì 16. Kroah-Hartman mở chương bằng lời thú nhận thẳng thắn: một trong những phần khó nhất của việc tự dựng nhân là xác định chính xác driver và tùy chọn nào máy bạn cần để chạy đúng 1. Cả chương là một câu trả lời duy nhất: đừng đoán — hãy đọc câu trả lời ra từ chính hệ thống đang chạy.

Sáu chương trước dạy cách làm. Từ chương 7 trở đi, sách hỏi: làm cái gì? Chương 7 và 8 là Phần II của sách 16. Ông Greg nói phần khó nhất khi tự dựng nhân là biết máy mình cần những mảnh nào 1. Nhớ nhé: đừng đoán, hãy hỏi chính chiếc máy.

The first six chapters teach you the procedure: fetch the source, configure, build, install, upgrade. Part II of the book — exactly Chapters 7 and 8 — turns to the harder question: configure what 16. Kroah-Hartman opens the chapter with a plain admission: one of the hardest parts of building your own version of the Linux kernel is determining exactly which drivers and configuration options are needed for your machine to work properly 1. The whole chapter is one answer: do not guess — read the answer off the running system.

Đây cũng là chương tác giả nói ông tâm đắc nhất, và lý do dễ hiểu: nó là chỗ duy nhất trong sách mà bạn không làm theo công thức, mà tự điều tra. Hai nửa của chương là hai chiều điều tra ngược nhau — nửa đầu đi lùi từ một thiết bị đang chạy tốt về tên module; nửa sau đi tới từ một con số nhận dạng phần cứng vào mã nguồn nhân 14.

Luận điểm chương 7. Hệ thống đang chạy đã chứa sẵn câu trả lời. Nếu một thiết bị đang hoạt động, nhân đã gắn đúng driver vào nó, và mối gắn kết ấy hiện ra thành các liên kết tượng trưng trong sysfs 1. Việc của bạn chỉ là lần theo liên kết để lấy tên module, rồi lần ngược từ tên module về tùy chọn CONFIG_ tương ứng 3.

Ý chính. Nếu một thiết bị trên máy bạn đang chạy được, nghĩa là nhân đã tìm ra đúng "mảnh ghép" cho nó rồi, và nó có ghi lại ở một chỗ tên là sysfs 1. Bạn chỉ cần đi theo dấu vết đó để biết tên mảnh ghép, rồi tra ngược ra nút cần bật 3. Nhớ nhé: câu trả lời đã có sẵn trong máy.

Chapter 7 thesis. The running system already holds the answer. If a device works, the kernel has already bound the right driver to it, and that binding surfaces as symlinks inside sysfs 1. Your job is only to follow the links to the module name, then work backward from the module name to the matching CONFIG_ option 3.

Cụm khái niệm 01 · “Using a Distribution Kernel”Concept cluster 01 · “Using a Distribution Kernel”

Mượn cấu hình của bản phân phối làm điểm xuất phát Bắt đầu bằng cấu hình có sẵn Borrowing the distribution config as a starting point

Cách dễ nhất để biết cần những module nào, theo ông, là bắt đầu từ chính cấu hình đi kèm gói nhân của bản phân phối 1. Lý do sâu hơn là về trạng thái chứ không phải về tệp tin: việc xác định driver dễ hơn nhiều trên một hệ thống đang chạy, nơi driver đúng đã được gắn vào phần cứng 1. Nếu máy đích chưa cài Linux, ông khuyên dùng một bản LiveCD để khởi động lên và quan sát 1.

Cách dễ nhất là chép lại cấu hình của bản Linux bạn đang dùng 1. Vì khi máy đang chạy, mọi thứ đã được lắp đúng chỗ rồi 1. Nếu máy đó chưa cài Linux, ông bảo hãy dùng đĩa LiveCD để khởi động thử 1. Nhớ nhé: phải có một hệ đang chạy thì mới quan sát được.

The easiest way to determine which modules are necessary, he says, is to start with the kernel configuration that comes with your distribution's kernel package 1. The deeper reason is about state, not files: it is much easier to determine which drivers are needed on a running system, where the proper drivers are already bound to the hardware 1. If the target machine has no Linux installed, he suggests booting a LiveCD version of a distribution to observe it 1.

Tệp cấu hình nhân (.config). Danh sách phẳng mọi tùy chọn CONFIG_ và trạng thái của chúng. Hầu hết bản phân phối đều đóng gói tệp này, thường nằm đâu đó dưới cây /usr/src/linux/ 2. Nếu khó tìm, hãy hỏi chính cái nhân đang chạy.

.config là gì. Là bảng liệt kê mọi nút bật/tắt của nhân. Bản Linux nào cũng kèm theo tệp này, thường nằm dưới /usr/src/linux/ 2. Nhớ nhé: không thấy tệp thì hỏi thẳng cái nhân đang chạy.

Kernel configuration file (.config). A flat list of every CONFIG_ option and its state. Almost all distributions ship it as part of the kernel package, usually somewhere below the /usr/src/linux/ directory tree 2. If it is hard to find, ask the running kernel itself.

ls /proc/config.gz
cp /proc/config.gz ~/linux/
cd ~/linux && gzip -dv config.gz
mv config .config
→ nền cấu hình chắc chắn khởi động được

có tệp /proc/config.gz không?
chép về thư mục nguồn
giải nén
đổi tên thành .config
→ nền an toàn để bắt đầu

ls /proc/config.gz
cp /proc/config.gz ~/linux/
cd ~/linux && gzip -dv config.gz
mv config .config
→ a base config guaranteed to boot

  1. /proc/config.gz

    /proc/config.gz — cái nhân mang theo sơ đồ của chính nó Cái nhân tự mang bản vẽ của nó /proc/config.gz — the kernel carries its own blueprint

    Phần lớn nhân của bản phân phối được dựng để nhúng luôn cấu hình vào trong hệ thống tệp /proc. Cách kiểm tra chỉ là một lệnh ls /proc/config.gz; nếu tệp có mặt, chép về thư mục mã nguồn và giải nén bằng gzip -dv config.gz — trong ví dụ của sách, tệp nén lại còn 74,9 % 2. Đổi tên thành .config và dùng nó làm nền để dựng theo Chương 4 2.

    Nhiều bản Linux giấu sẵn bản vẽ cấu hình ngay trong máy. Gõ ls /proc/config.gz để xem có không; có thì chép về, giải nén, đổi tên thành .config 2. Nhớ nhé: một lệnh là biết có hay không.

    Most distribution kernels are built to include the configuration within the /proc filesystem. Checking is a single ls /proc/config.gz; if the file is there, copy it into your source directory and uncompress it with gzip -dv config.gz — in the book's example it reports 74.9 % 2. Rename it to .config and use it as the basis for the build described in Chapter 4 2.

    Bạn thấy nó ở đâu. Tệp ấy không tự nhiên có: nó đến từ tùy chọn CONFIG_IKCONFIG (“Kernel .config support”) cùng CONFIG_IKCONFIG_PROC, vốn mô tả đúng là “bật truy cập tệp cấu hình nhân qua /proc/config.gz” 12.

    Gặp ở đâu. Tệp đó chỉ có khi người dựng nhân bật tùy chọn IKCONFIG_PROC 12. Nhớ nhé: không thấy tệp không có nghĩa là bạn làm sai.

    Where you see it. That file does not appear by magic: it comes from the CONFIG_IKCONFIG option (“Kernel .config support”) together with CONFIG_IKCONFIG_PROC, described as enabling “access to the kernel configuration file through /proc/config.gz” 12.

    Nếu không có tệp

    Cùng tùy chọn ấy cũng nhúng cấu hình vào chính ảnh nhân trên đĩa, và có thể moi ra bằng script scripts/extract-ikconfig trong cây mã nguồn 12. Nghĩa là ngay cả khi /proc/config.gz vắng mặt, bản vẽ vẫn có thể còn nằm trong tệp nhân.

    Vì sao nó luôn khởi động được

    Cấu hình distro là tập siêu — nó bật gần như mọi driver đã biết. Một tập siêu thì luôn chứa tập bạn cần, nên ông khẳng định dùng tệp này “sẽ luôn tạo ra một ảnh nhân chạy được cho máy bạn” 2. Cái giá nằm ở thời gian biên dịch, không phải ở tính đúng đắn.

  2. cutting down

    Cắt gọt — và quy tắc “chỉ tắt thứ bạn chắc chắn” Bỏ bớt, nhưng đừng bỏ liều Cutting down — and the “only what you are sure of” rule

    Nhược điểm của cấu hình distro rất cụ thể: bạn sẽ dựng gần như mọi module và driver có trong cây mã nguồn, điều gần như không bao giờ cần cho một máy đơn lẻ 2. Nên ông khuyên bắt đầu tắt dần các driver và tùy chọn không cần — kèm một mệnh đề phanh rất đáng nhớ: chỉ nên tắt những thứ bạn chắc chắn là không cần, vì có thể có phần nào đó của hệ thống đang dựa vào một tùy chọn cụ thể 2.

    Dùng cấu hình có sẵn thì phải dựng gần như tất cả mọi thứ, rất lâu 2. Vậy nên hãy tắt bớt — nhưng chỉ tắt cái bạn chắc chắn không dùng, vì có thứ khác có thể đang cần nó 2. Nhớ nhé: tắt ít một, đừng tắt cả loạt.

    The disadvantage of the distro config is concrete: you will have built almost every kernel module and driver present in the kernel source tree, which is almost never needed for a single machine 2. So he advises starting to turn off drivers and options you do not need — with a memorable brake attached: disable only those options you are sure you do not need, as there might be parts of the system that rely on specific options being enabled 2.

    Bạn thấy nó ở đâu. Con đường tự động hóa việc cắt gọt này ngày nay mang tên make localmodconfig: nó lấy cấu hình của bản phân phối làm nền rồi tắt các module có vẻ thừa với máy bạn, và tài liệu nói cách này “giảm thời gian biên dịch một cách khổng lồ” 10.

    Gặp ở đâu. Ngày nay có lệnh make localmodconfig làm việc cắt gọt ấy giúp bạn, nhanh hơn rất nhiều 10. Nhớ nhé: máy làm hộ được phần lớn việc này.

    Where you see it. Today that trimming has an automated route named make localmodconfig: it takes your distribution's kernel as a base, then disables modules apparently superfluous for your setup — documentation says it “will reduce the compile time enormously” 10.

    Ghi chú thời gian

    make localmodconfig không có trong sách và không phải phát biểu của Kroah-Hartman — nó là mục tiêu make được tài liệu nhân hiện hành khuyến nghị 10. Sách năm 2006 mô tả việc cắt gọt như một thao tác thủ công trong menuconfig 2.

    Cái bẫy chung

    Tài liệu hiện hành cảnh báo đúng cái bẫy mà quy tắc “chỉ tắt thứ bạn chắc chắn” nhắm tới: localmodconfig “rất có khả năng tắt những tính năng bạn chưa dùng kể từ lúc khởi động” — ví dụ driver cho thiết bị ngoại vi hiện đang rút ra 10. Hai mươi năm, cùng một cái bẫy.

Cụm khái niệm 02 · “Finding Which Module Is Needed”Concept cluster 02 · “Finding Which Module Is Needed”

Lần ngược qua sysfs về tên module Đi theo dấu vết trong /sys Walking sysfs back to a module name

Sách gọi sysfs là vị trí quan trọng nhất trong số những nơi lưu thông tin về việc thiết bị nào gắn với driver nào trên một nhân đang chạy; nó phải luôn được gắn ở /sys bởi các script khởi tạo của bản phân phối 3. Ông mô tả nó rất gợi hình: sysfs cho ta một cái nhìn thoáng qua vào cách các phần khác nhau của nhân móc nối với nhau, thông qua vô số liên kết tượng trưng trỏ khắp nơi trong hệ thống tệp 3.

Trong máy có một thư mục đặc biệt tên là /sys. Nó không chứa tệp thật, mà chứa bản đồ: thiết bị nào đang được mảnh ghép nào điều khiển 3. Bản đồ này làm bằng rất nhiều "lối tắt" trỏ qua trỏ lại 3. Nhớ nhé: đi theo lối tắt là ra tên mảnh ghép.

The book calls sysfs the most important of the places that store information about which devices are bound to which drivers in a running kernel; it should always be mounted at /sys by your distribution's initialization scripts 3. His description is vivid: sysfs provides a glimpse into how the different portions of the kernel are hooked together, with many different symlinks pointing all around the filesystem 3.

Ông kèm ngay một lời rào đón mà hai mươi năm sau đọc lại thấy rất đúng: cấu trúc bên trong sysfs liên tục thay đổi, do các nhà phát triển nhân tổ chức lại thiết bị và nghĩ lại cách phơi bày cấu trúc nội bộ ra không gian người dùng; vì vậy theo thời gian, một số liên kết nói ở chương này có thể không còn — nhưng thông tin thì vẫn ở đó, chỉ dịch đi đôi chút 3.

sysfs. Một hệ thống tệp ảo — không nằm trên đĩa — phơi bày cây thiết bị và cây driver của nhân dưới dạng thư mục và liên kết tượng trưng. Tài liệu nhân mô tả nó là cơ chế xuất cấu trúc dữ liệu nội bộ của nhân cùng thuộc tính của chúng ra không gian người dùng 15.

sysfs là gì. Là thư mục "giả" do nhân sinh ra ngay lúc chạy, không có trên ổ cứng. Nó bày ra danh sách thiết bị và driver dưới dạng thư mục 15. Nhớ nhé: đọc nó là đọc trạng thái hiện tại của máy.

sysfs. A virtual filesystem — nothing on disk — exposing the kernel's device tree and driver tree as directories and symlinks. Kernel documentation describes it as a mechanism for exporting kernel data structures and their attributes to userspace 15.

basename `readlink \
  /sys/class/net/eth0/device/driver/module`
→ e1000

find -type f -name Makefile | xargs grep e1000
→ obj-$(CONFIG_E1000) += e1000/

một lệnh → ra tên module: e1000
một lệnh nữa → ra nút cần bật: CONFIG_E1000

basename `readlink \
  /sys/class/net/eth0/device/driver/module`
→ e1000

find -type f -name Makefile | xargs grep e1000
→ obj-$(CONFIG_E1000) += e1000/

  1. one-line traversal

    Một dòng lệnh — từ eth0 đến e1000 Một dòng lệnh ra ngay tên mảnh ghép One line — from eth0 to e1000

    Ví dụ chủ lực của chương là card mạng. Sau khi dùng ls /sys/class/net/ và ifconfig -a để xác định eth0 là giao diện đang hoạt động, toàn bộ phần còn lại gói gọn trong một dòng: basename `readlink /sys/class/net/eth0/device/driver/module`, cho ra e1000 3. Ông tách dòng ấy thành bốn bước: theo liên kết device vào cây /sys/devices/; từ đó theo liên kết driver; từ đó theo liên kết module; rồi cắt lấy phần tên cuối cùng 3.

    Ví dụ chính là card mạng. Xem /sys/class/net/ để biết có những cổng nào, dùng ifconfig -a để biết cổng nào đang chạy, rồi một lệnh duy nhất cho ra tên mảnh ghép: e1000 3. Nhớ nhé: ba lối tắt nối nhau — thiết bị → driver → module.

    The chapter's lead example is the network card. After ls /sys/class/net/ and ifconfig -a identify eth0 as the live interface, everything else collapses into one line: basename `readlink /sys/class/net/eth0/device/driver/module`, which prints e1000 3. He unpacks it into four steps: follow the device symlink into the /sys/devices/ tree; from there follow the driver symlink; from there the module symlink; then strip the path down to the last name 3.

    Bạn thấy nó ở đâu. Cùng một dòng lệnh, đổi lớp thiết bị, là ra driver của thứ khác. Với bộ chuyển USB-sang-serial ở /dev/ttyUSB0, ông tra /sys/class/tty/ttyUSB0/device/driver/module và nhận được pl2303 3.

    Gặp ở đâu. Đổi net thành tty là tra được thiết bị khác: cáp USB-serial cho ra pl2303 3. Nhớ nhé: cùng một công thức cho mọi loại thiết bị.

    Where you see it. The same line with a different class gives you another driver. For a USB-to-serial converter on /dev/ttyUSB0, he reads /sys/class/tty/ttyUSB0/device/driver/module and gets pl2303 3.

    Ghi chú thời gian: liên kết device

    Lời rào đón của ông đã thành hiện thực ở đúng chỗ này. Tài liệu “Rules on how to access information in sysfs” hiện nay nói thẳng: đừng phụ thuộc vào liên kết device, nó là giải pháp chữa cháy cho bố cục cũ, và “truy cập /sys/class/net/eth0/device là một lỗi của ứng dụng” 6. Dòng lệnh trong sách vẫn thường chạy được, nhưng nó không còn là giao diện được bảo đảm.

    Vì sao vẫn nên hiểu nó

    Vì cấu trúc thì đổi, còn quan hệ thì không: một thiết bị vẫn luôn có một driver gắn vào, và driver vẫn luôn thuộc về một module. Tài liệu cùng trang cũng nhắc rằng nhân không cam kết một giao diện nhị phân ổn định cho sysfs, nên cách đúng là hiểu quan hệ rồi thích nghi, chứ không thuộc lòng đường dẫn 6.

  2. module → CONFIG_

    Từ tên module về tùy chọn CONFIG_ Từ tên mảnh ghép ra nút cần bật From a module name to a CONFIG_ option

    Biết tên module mới xong một nửa; bạn còn cần tùy chọn cấu hình sinh ra nó. Ông tìm bằng cách lục các Makefile trong cây mã nguồn: find -type f -name Makefile | xargs grep e1000, và kết quả chứa dòng obj-$(CONFIG_E1000) += e1000/ 3. Điều cần nhìn là bất kỳ dòng nào có chuỗi CONFIG_ — đó chính là tùy chọn phải bật 3. Với ví dụ USB, cùng cách làm cho ra CONFIG_USB_SERIAL_PL2303 3.

    Biết tên mảnh ghép rồi thì tìm xem nút nào bật nó. Ông dùng lệnh find … | xargs grep để lục các tệp Makefile, và thấy dòng có chữ CONFIG_E1000 3. Nhớ nhé: cứ thấy chữ CONFIG_ là đúng nút cần tìm.

    Knowing the module name is only half of it; you still need the configuration option that builds it. He finds it by searching the tree's Makefiles: find -type f -name Makefile | xargs grep e1000, whose output contains obj-$(CONFIG_E1000) += e1000/ 3. The thing to look for is any line carrying the term CONFIG_ — that is the option the kernel needs enabled 3. For the USB example the same method yields CONFIG_USB_SERIAL_PL2303 3.

    Bạn thấy nó ở đâu. Bước cuối là make menuconfig, bấm phím / để mở ô tìm kiếm, rồi gõ tên tùy chọn bỏ phần CONFIG_ 3. Hệ thống cấu hình sẽ chỉ ra chính xác vị trí trong menu cần vào để bật nó 3.

    Gặp ở đâu. Mở make menuconfig, bấm phím /, gõ tên nút (bỏ chữ CONFIG_ ở đầu). Máy sẽ chỉ cho bạn nút đó nằm ở menu nào 3. Nhớ nhé: không phải mò từng menu.

    Where you see it. The last step is make menuconfig, pressing / to start a search, then typing the option name minus the CONFIG_ prefix 3. The configuration system then tells you exactly where in the menus to select it 3.

    Tìm kiếm trong menuconfig hôm nay

    Cơ chế ấy còn nguyên. Tài liệu kconfig hiện hành mô tả chức năng tìm kiếm là tìm theo tên ký hiệu cấu hình, nên bạn phải biết đại khái mình tìm gì, và nói rõ có thể dùng cả biểu thức chính quy trong chuỗi tìm kiếm 11.

    Ví dụ trong sách là của năm 2006

    Cây mã nguồn ông dùng là linux-2.6.17.8 và kết quả chỉ ra tùy chọn “Intel(R) PRO/1000 Gigabit Ethernet support” nằm dưới Device Drivers → Network device support → Ethernet (1000 Mbit) 3. Đường đi trong menu đã đổi nhiều lần từ đó; cái không đổi là thao tác tìm kiếm.

  3. modalias

    modalias — để chính cái nhân đọc danh sách ra cho bạn Bảo máy tự đọc cả danh sách modalias — let the kernel read the list out for you

    Sau khi đi bộ qua từng liên kết, ông đưa ra một script rất ngắn làm toàn bộ việc ấy theo một cách khác, gọi là find_all_modules.sh 3. Nó duyệt sysfs tìm mọi tệp tên modalias — tệp này chứa bí danh module, thứ nói cho modprobe biết cần nạp module nào để điều khiển thiết bị; bí danh được ghép từ nhà sản xuất, mã định danh, loại lớp và các định danh riêng khác của thiết bị 3.

    Ông cho một đoạn script ngắn làm hộ tất cả 3. Nó đi khắp /sys nhặt các tệp tên modalias — mỗi tệp là một "mã vạch" của thiết bị, nói cho máy biết cần mảnh ghép nào 3. Nhớ nhé: một lệnh là ra cả danh sách, không phải tra từng cái.

    After walking the links by hand, he offers a very short script that does all of that work a different way, called find_all_modules.sh 3. It goes through sysfs finding every file called modalias — that file holds the module alias that tells modprobe which module should be loaded to control the device, made up of a combination of manufacturer, ID, class type and other unique identifiers 3.

    Bạn thấy nó ở đâu. Mọi module driver đều mang sẵn một danh sách nội bộ các thiết bị nó hỗ trợ, sinh tự động từ chính khai báo của driver; modprobe dò danh sách ấy để khớp với bí danh, và nếu khớp thì nạp module — đó chính là cách nạp driver tự động của Linux vận hành 3.

    Gặp ở đâu. Mỗi mảnh ghép đều mang danh sách các thiết bị nó biết điều khiển; máy so mã vạch với danh sách đó rồi tự nạp đúng mảnh 3. Nhớ nhé: đó là lý do cắm vào là chạy.

    Where you see it. Every driver module carries an internal list of devices it supports, generated automatically from what the driver tells the kernel; modprobe searches that list for a match with the alias and loads the module if it finds one — that is exactly how automatic driver loading in Linux works 3.

    Script, đúng như in trong sách

    #!/bin/bash
    #
    # find_all_modules.sh
    #
    for i in `find /sys/ -name modalias -exec cat {} \;`; do
      /sbin/modprobe --config /dev/null --show-depends $i ;
    done | rev | cut -f 1 -d '/' | rev | sort -u 3

    Vì sao nó không nạp gì cả

    Hai cờ làm nên sự an toàn. --show-depends chỉ liệt kê các phụ thuộc của một module (hoặc một bí danh), kể cả chính module đó, thay vì nạp — đúng cách các bản phân phối dùng để biết nên đưa module nào vào initrd 7. Còn --config /dev/null ép dùng một thư mục cấu hình rỗng, gạt mọi quy tắc install/remove riêng của máy ra khỏi kết quả 7.

    Các dòng FATAL không phải là lỗi của bạn

    Script sẽ in ra vài dòng kiểu FATAL: Module pci:v00008086d00002592… not found. hoặc FATAL: Module serio:ty01pr00id00ex00 not found. — nghĩa là không tìm được module nào điều khiển được thiết bị đó. Ông bảo đừng bận tâm: có những thiết bị đơn giản là chưa có driver trong nhân 3.

    Kết quả là một danh sách phẳng kiểu 8139too.ko, ehci-hcd.ko, snd-hda-intel.ko, usbcore.ko — toàn bộ module cần để điều khiển phần cứng của máy 3.

    The output is a flat list like 8139too.ko, ehci-hcd.ko, snd-hda-intel.ko, usbcore.ko — all of the modules needed to control the hardware in the machine 3.

Cụm khái niệm 03 · “Determining the Correct Module from Scratch”Concept cluster 03 · “Determining the Correct Module from Scratch”

Từ con số không: truy mã nhận dạng vào mã nguồn Khi chưa có gì chạy được From scratch: tracing an ID into the source

Đôi khi bạn không có sẵn một nhân distro đang chạy để quan sát, hoặc bạn vừa cắm thêm phần cứng mới và cần biết phải bật tùy chọn nào 4. Ông đưa ra một lối tắt trước đã: cách dễ nhất là dựng toàn bộ driver cùng loại thành module, rồi để tiến trình khởi động udev tự khớp driver với thiết bị; khi nó khớp xong, bạn quay lại dùng các bước ở nửa đầu chương để tìm tên driver, rồi chỉ bật đúng driver đó 4.

Có khi máy chưa chạy được Linux, hoặc bạn vừa cắm thiết bị mới mà nó không nhận 4. Mẹo đầu tiên: cứ dựng hết mọi mảnh ghép cùng loại, để máy tự tìm ra mảnh đúng, rồi quay lại tra như ở phần trước 4. Nhớ nhé: để máy thử giúp trước khi tự mò.

Sometimes you have no distribution kernel running to observe, or you have just added new hardware and need to know which option to enable 4. He offers a shortcut first: the easiest way is to build all drivers of that type as modules and let the udev startup process match the driver to the device; once that happens you work backward with the steps above to find the driver, then go back and enable just that one 4.

Nếu lối tắt không dùng được, ông cảnh báo trước rằng phần sau phức tạp và có lúc phải đào vào mã nguồn nhân — rồi thêm một câu rất đặc trưng giọng ông: đừng ngại, nó chỉ giúp bạn hiểu phần cứng của mình và mã nguồn nhân rõ hơn mà thôi 4. Đây là chỗ cuốn sách “dành cho người dùng, không cần biết lập trình” nhẹ nhàng đẩy người đọc qua ranh giới sang phía mã nguồn.

Mã nhà sản xuất và mã thiết bị (vendor / device ID). Cặp số hệ mười sáu mà phần cứng tự khai. Thiết bị PCI được phân biệt bằng cặp này, và mỗi tổ hợp có thể cần một driver riêng 4. Driver khai báo ngược lại những cặp nào nó hỗ trợ, để nhân biết cách gắn đúng 4.

Hai con số nhận dạng. Mỗi thiết bị tự khai hai con số: ai làm ra nó, và nó là model nào 4. Mảnh ghép nào biết cặp số đó thì nhận việc 4. Nhớ nhé: hai con số này là chìa khóa của cả phần này.

Vendor and device ID. The pair of hexadecimal numbers the hardware announces about itself. PCI devices are distinguished by vendor ID and device ID, and each combination could require a unique driver 4. Drivers declare in return which pairs they support, so the kernel knows how to bind them 4.

PCI: lspci → 06:04.0
  /sys/bus/pci/devices/0000:06:04.0/vendor → 0x10ec
  …/device → 0x8139
  grep trong include/linux/pci_ids.h
  → struct pci_device_id trong drivers/net/8139cp.c

USB: lsusb → 157e:300d
  grep -i -R -l 157e drivers/*
  → struct usb_device_id trong zd_usb.c

PCI: lspci → lấy số hiệu
→ đọc hai con số trong /sys
→ tìm hai con số đó trong mã nguồn

USB: lsusb → hai con số
→ tìm thẳng trong mã nguồn

PCI: lspci → 06:04.0
  /sys/bus/pci/devices/0000:06:04.0/vendor → 0x10ec
  …/device → 0x8139
  grep in include/linux/pci_ids.h
  → struct pci_device_id in drivers/net/8139cp.c

USB: lsusb → 157e:300d
  grep -i -R -l 157e drivers/*
  → struct usb_device_id in zd_usb.c

  1. PCI device

    Thiết bị PCI — bảy bước từ lspci đến CONFIG_ Thiết bị cắm trong máy A PCI device — seven steps from lspci to CONFIG_

    Ví dụ của ông là một card mạng PCI không chạy với nhân hiện tại. lspci | grep -i ethernet cho ra dòng 06:04.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+ (rev 10) 4. Vào /sys/bus/pci/devices/ — nhớ thêm tiền tố 0000: mà nhân dùng nhưng lspci không in ra — rồi đọc hai tệp vendor và device: 0x10ec và 0x8139 4.

    Ví dụ là một card mạng cắm trong máy nhưng chưa chạy. Lệnh lspci cho biết nó nằm ở vị trí 06:04.0 4. Vào thư mục tương ứng trong /sys (nhớ thêm 0000: ở đầu) rồi đọc hai con số: 0x10ec và 0x8139 4. Nhớ nhé: hai con số này là thứ cần mang đi tìm.

    His example is a PCI network card that does not work with the running kernel. lspci | grep -i ethernet prints 06:04.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+ (rev 10) 4. Go into /sys/bus/pci/devices/ — remembering the leading 0000: the kernel uses but lspci does not print — and read the vendor and device files: 0x10ec and 0x8139 4.

    Bạn thấy nó ở đâu. Với PCI, nhân gom sẵn phần lớn mã nhận dạng vào một tệp: include/linux/pci_ids.h. grep -i 0x10ec cho ra PCI_VENDOR_ID_REALTEK, và grep -i 0x8139 cho ra PCI_DEVICE_ID_REALTEK_8139 4 — hai cái tên mà driver sẽ dùng thay cho số trần.

    Gặp ở đâu. Trong mã nguồn có một tệp gom sẵn tên gọi cho các con số đó; tra vào là ra PCI_VENDOR_ID_REALTEK và PCI_DEVICE_ID_REALTEK_8139 4. Nhớ nhé: đi tìm cái tên dễ hơn đi tìm con số.

    Where you see it. For PCI the kernel collects most IDs in one file: include/linux/pci_ids.h. grep -i 0x10ec yields PCI_VENDOR_ID_REALTEK and grep -i 0x8139 yields PCI_DEVICE_ID_REALTEK_8139 4 — the two names a driver will use instead of bare numbers.

    Đọc bảng để loại trừ

    grep -Rl PCI_VENDOR_ID_REALTEK * cho ba ứng viên: r8169.c, 8139too.c, 8139cp.c 4. Mọi driver PCI đều mang danh sách thiết bị hỗ trợ trong một cấu trúc struct pci_device_id — đó là chỗ phải nhìn 4. Bảng của r8169.c khai 0x8169 và 0x8129, không có 0x8139, nên nó bị loại 4.

    Khi driver tự chỉ sang driver khác

    8139too.c không có cặp cần tìm trong bảng, nhưng lại chứa một đoạn mã in ra lời nhắn “Use the 8139cp driver for improved performance and stability.” khi gặp đúng chip ấy 4. Và 8139cp.c quả nhiên khai cả PCI_VENDOR_ID_REALTEK lẫn PCI_DEVICE_ID_REALTEK_8139, kèm MODULE_DEVICE_TABLE(pci, cp_pci_tbl) — đây là driver cần 4.

    Cơ chế phía sau, theo tài liệu hiện hành

    Tài liệu PCI của nhân xác nhận đúng cơ chế ấy: driver trỏ id_table tới bảng struct pci_device_id, và “phần lớn driver nên xuất bảng này bằng MODULE_DEVICE_TABLE(pci,...)” — chính là thứ sinh ra các modalias mà modprobe dò tìm 14.

  2. USB device

    Thiết bị USB — rút ra, cắm vào, và so hai danh sách Thiết bị cắm ngoài A USB device — unplug, replug, diff the lists

    Với USB, cách tìm gần như giống hệt, chỉ khác ở chỗ lấy mã 4. Dùng lsusb (thuộc gói usbutils) để liệt kê 9; bỏ qua các dòng ID 0000:0000 vì đó là bộ điều khiển chủ của chính bus 4. Rồi ông dùng một mẹo rất vật lý: rút thiết bị ra, chạy lại lsusb, và dòng biến mất chính là thiết bị cần tìm — trong ví dụ là 157e:300d 4.

    Với thiết bị cắm ngoài, cách làm dễ hơn. Chạy lsusb xem danh sách, rồi rút thiết bị ra và chạy lại. Dòng nào biến mất chính là nó 4. Nhớ nhé: rút ra cắm vào là cách nhận diện đơn giản nhất.

    For USB the method is nearly identical, differing only in how you get the IDs 4. Use lsusb (from the usbutils package) to list them 9; ignore lines showing ID 0000:0000, which are the USB host controllers driving the bus itself 4. Then he uses a very physical trick: unplug the device, run lsusb again, and the line that vanished is your device — here 157e:300d 4.

    Bạn thấy nó ở đâu. Cắm lại, số thiết bị đã đổi — vì số thiết bị USB không cố định, chúng đổi mỗi lần cắm; thứ ổn định là cặp mã nhà sản xuất và mã sản phẩm, hai số bốn chữ số ngăn bởi dấu hai chấm 4.

    Gặp ở đâu. Cắm lại thì số thứ tự đổi, nhưng hai con số nhận dạng thì không đổi 4. Nhớ nhé: nhớ hai con số, đừng nhớ số thứ tự.

    Where you see it. Plug it back in and the device number has changed — USB device numbers are not unique and change every time a device is plugged in; what is stable is the vendor and product ID pair, two four-digit values separated by a colon 4.

    Không có usb_ids.h

    Khác PCI, không tệp đơn lẻ nào gom hết mã nhà sản xuất USB, nên phải quét cả cây: grep -i -R -l 157e drivers/* 4. Kết quả lẫn cả tệp dữ liệu của atm và scsi — ông loại chúng bằng hiểu biết về loại thiết bị, còn lại drivers/net/wireless/zd1211rw/zd_usb.c 4.

    Bảng struct usb_device_id

    Trong tệp ấy, 157e xuất hiện trong một mảng usb_ids[], nơi dòng { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B } khớp đúng cặp cần tìm 4. Như driver PCI, driver USB khai báo thiết bị nó hỗ trợ bằng một biến struct usb_device_id để nhân biết đường gắn 4.

    Mẹo hiện đại cho cùng việc ấy

    Ngày nay không cần rút dây cũng lấy được cặp số: lspci -n in mã nhà sản xuất và mã thiết bị dưới dạng số thay vì tra tên, -nn in cả hai dạng, còn -k cho biết luôn driver nào đang xử lý thiết bị và module nào có khả năng xử lý nó 8. Cờ -k là lối tắt gộp cả nửa đầu chương vào một lệnh — nhưng nó không nói cho bạn biết CONFIG_ nào, nên bước tra Makefile vẫn còn nguyên. Và tiến trình udev mà sách nhắc tới 4 nay thường là systemd-udevd, trình nền “lắng nghe các sự kiện uevent từ nhân” rồi áp quy tắc udev cho từng sự kiện 17.

Cụm khái niệm 04 · “Root Filesystem”Concept cluster 04 · “Root Filesystem”

Hệ thống tệp gốc — chỗ không được phép sai Phần không được phép quên The root filesystem — where you cannot afford to be wrong

Hệ thống tệp gốc là nơi phần chính của hệ thống khởi động lên: nó chứa mọi chương trình khởi đầu của bản phân phối và thường chứa toàn bộ cấu hình của máy 5. Ông tóm gọn: nó rất quan trọng, và nhân phải tìm được nó lúc khởi động thì mọi thứ mới chạy đúng 5. Triệu chứng khi sai rất dễ nhận: nhân dừng lại với VFS: Cannot open root device, Please append a correct "root=" boot option, rồi Kernel panic 5.

Hệ thống tệp gốc là ổ chứa chính hệ điều hành. Nhân phải tìm thấy nó lúc bật máy, nếu không thì dừng luôn 5. Khi sai, màn hình hiện dòng Cannot open root device rồi Kernel panic 5. Nhớ nhé: thấy dòng đó là biết quên driver cho ổ đĩa.

The root filesystem is where the main portion of the running system boots from: it contains all the initial programs that start the distro and usually the entire system configuration 5. He sums it up: it is very important, and the kernel must be able to find it at boot time for things to work properly 5. The symptom when it is wrong is unmistakable: the kernel stops with VFS: Cannot open root device, Please append a correct "root=" boot option, then Kernel panic 5.

Đây là lý do duy nhất trong chương khiến ông khuyên đi ngược lại tinh thần “dựng thành module cho gọn”. Nếu bạn không dùng ảnh ramdisk lúc khởi động, thường nên dựng thẳng vào nhân cả hệ thống tệp của phân vùng gốc lẫn bộ điều khiển đĩa của nó, thay vì để làm module; còn nếu có dùng ramdisk thì để làm module vẫn an toàn 5. Cách phân biệt của ông cũng rất thực dụng: nếu bạn cài nhân bằng script của bản phân phối thì nhiều khả năng đang dùng ramdisk; nếu tự tay cài thì nhiều khả năng là không 5.

Ba thứ phải có mặt. Để khởi động được, nhân cần đồng thời: loại hệ thống tệp của phân vùng gốc, driver đĩa ở tầng khối, và driver bộ điều khiển của phần cứng nối tới đĩa. Trong ví dụ của sách, ba thứ đó là ext3, sd và ata_piix 5.

Ba mảnh phải có. Kiểu định dạng của ổ, mảnh đọc ổ đĩa, và mảnh điều khiển mạch nối tới ổ. Ví dụ trong sách: ext3, sd, ata_piix 5. Nhớ nhé: thiếu một trong ba là không bật được máy.

Three things must be present. To boot, the kernel needs all of: the root partition's filesystem type, the disk driver at the block layer, and the controller driver for the hardware the disk hangs off. In the book's example those are ext3, sd and ata_piix 5.

mount | grep " / "
→ /dev/sda2 on / type ext3 (rw,noatime)

loại tệp → ext3
thiết bị  → sda2 ⇒ phải cấu hình cả sda
ls -l /sys/block/sda → …/driver → sd
lên tiếp một bậc     → ata_piix

mount | grep " / "
→ ổ nào, định dạng gì
rồi đi ngược trong /sys để tìm
mảnh điều khiển ổ đó

mount | grep " / "
→ /dev/sda2 on / type ext3 (rw,noatime)

fs type → ext3
device  → sda2 ⇒ configure the whole sda
ls -l /sys/block/sda → …/driver → sd
one level up       → ata_piix

  1. walking up the chain

    Đi ngược lên cây thiết bị cho đến khi gặp driver Leo ngược lên từng bậc Walking up the device chain until a driver appears

    Bắt đầu bằng mount | grep " / " để lấy cả hai dữ kiện cùng lúc: phân vùng gốc là /dev/sda2 và loại tệp là ext3 5. Vì sda2 là một phân vùng — phân vùng thì có số, thiết bị khối chính thì không — nên phải cấu hình cho cả thiết bị sda, bởi không có thiết bị chính thì không có đường truy cập các phân vùng trên nó 5.

    Gõ mount | grep " / " là biết ngay hai điều: ổ gốc là /dev/sda2, định dạng là ext3 5. Số 2 nghĩa là phân vùng; phải lo cho cả ổ sda chứ không chỉ phân vùng ấy 5. Nhớ nhé: lo cho cả ổ, không chỉ một phần của ổ.

    Start with mount | grep " / ", which gives both facts at once: the root partition is /dev/sda2 and the type is ext3 5. Because sda2 is a partition — partitions are numbered, main block devices are not — the whole sda device must be configured, since without the main block device there is no way to reach its individual partitions 5.

    Bạn thấy nó ở đâu. Từ /sys/block/sda, liên kết device dẫn xuống sâu trong /sys/devices/pci0000:00/0000:00:1f.2/host0/…, nơi có liên kết driver trỏ tới sd — driver đĩa SCSI 5. Đi tiếp lên hai bậc nữa mới gặp liên kết driver thứ hai: ata_piix, chính là bộ điều khiển đĩa 5.

    Gặp ở đâu. Từ ổ sda đi theo lối tắt vào sâu, gặp mảnh sd; leo ngược lên vài bậc nữa, gặp mảnh ata_piix 5. Nhớ nhé: chưa thấy chữ driver thì leo tiếp một bậc.

    Where you see it. From /sys/block/sda, the device link leads deep into /sys/devices/pci0000:00/0000:00:1f.2/host0/…, where a driver link points at sd — the SCSI disk driver 5. Two more levels up the chain sits the second driver link: ata_piix, the disk controller 5.

    Vì sao phải leo nhiều bậc

    Vì không phải thư mục nào trong chuỗi cũng có liên kết driver. Ông thử ở target0:0:0 — không có; lên host0 — cũng không; lên một bậc nữa mới thấy 5. Tài liệu hiện hành nói đúng điều đó ở dạng quy tắc: “thiết bị nào không có liên kết driver thì đơn giản là không có” 6.

    Hai nơi cho thiết bị khối

    Ông ghi chú rằng thiết bị khối hiện ra ở /sys/block hoặc /sys/class/block, tùy phiên bản nhân 5. Tài liệu hiện hành xác nhận cả hai tồn tại và cảnh báo ngược lại: giả định rằng /sys/block và /sys/class/block thay thế được cho nhau là một lỗi của ứng dụng 6.

  2. get-driver.sh

    get-driver.sh — script viết để sống sót qua các phiên bản Một script làm hộ cả việc leo get-driver.sh — a script built to survive version churn

    Chương khép lại bằng một script tiện dụng để tìm driver và tên module cho bất kỳ nút thiết bị nào trong hệ thống. Ông nói rõ xuất xứ của nó: được phát triển cùng các nhà phát triển nhân phụ trách sysfs, và sẽ chạy được trên mọi phiên bản tương lai của nhân 2.6 5. Đó là câu trả lời trực tiếp cho lời rào đón ở đầu chương về việc sysfs liên tục đổi chỗ 3.

    Cuối chương có một script làm hộ toàn bộ việc leo ngược ấy. Ông nói nó được làm cùng những người viết sysfs, nên chạy được với mọi bản nhân 2.6 về sau 5. Nhớ nhé: gõ một lệnh, máy leo hộ bạn.

    The chapter closes with a handy script for finding the driver and module name for any device node on the system. He states its provenance: it was developed with the kernel developers responsible for sysfs, and should successfully work on all future versions of the 2.6 kernel 5. That is a direct answer to the caveat at the top of the chapter about sysfs constantly moving around 3.

    Bạn thấy nó ở đâu. Với ví dụ vừa làm bằng tay, get-driver.sh sda in ra đúng hai dòng found driver: sd và found driver: ata_piix 5. Với ttyUSB0 nó lần ra cả chuỗi: pl2303, rồi usb từ module usbcore, rồi uhci_hcd 5.

    Gặp ở đâu. Gõ get-driver.sh sda là ra ngay sd và ata_piix 5. Với cáp USB thì ra cả chuỗi mảnh ghép 5. Nhớ nhé: một lệnh thay cho mười phút mò mẫm.

    Where you see it. For the example just done by hand, get-driver.sh sda prints exactly two lines, found driver: sd and found driver: ata_piix 5. For ttyUSB0 it traces the whole chain: pl2303, then usb from module usbcore, then uhci_hcd 5.

    Script làm gì, theo đúng thứ tự

    Nó nhận một tên lớp thiết bị, tìm thư mục sysfs tương ứng bằng cách dò lần lượt /sys/class, /sys/block, /sys/bus; giải liên kết bằng readlink -f; gỡ liên kết device kiểu cũ về thiết bị cha; rồi lặp while test "$DEVPATH" != "/", mỗi vòng thử đọc $DEVPATH/driver và $DRIVERPATH/module trước khi dirname lên một bậc 5.

    Vì sao nó bền hơn dòng lệnh một dòng

    Vì nó không cố định đường dẫn. Ba lần find thay cho một đường dẫn cứng, và vòng lặp leo lên thay cho số bậc đếm sẵn — đúng tinh thần mà tài liệu sysfs hiện hành đòi hỏi: đừng bao giờ dùng một đường dẫn như một phần tử cố định, hãy giải liên kết rồi đi tiếp 6.

    Hai script đều tải được

    Cả find_all_modules.sh lẫn get-driver.sh đều được sách nói là tải được từ trang web của cuốn sách, ghi trong mục “How to Contact Us” của Lời nói đầu 35. Bản trực tuyến miễn phí của sách nằm ở trang riêng của tác giả 13.

Ba hiểu lầm thường gặpThree common misconceptions

“Cứ tắt hết cho nhẹ”“Just switch everything off to make it light”

Hiểu lầm: tắt càng nhiều càng tốt. Thực tế: ông khuyên ngược lại — chỉ tắt những tùy chọn bạn chắc chắn không cần, vì có thể có phần nào đó của hệ thống đang dựa vào một tùy chọn cụ thể 2. Và với hệ thống tệp gốc, lời khuyên còn ngược hẳn: dựng thẳng vào nhân nếu bạn không dùng ramdisk 5.

Myth: the more you disable, the better. Fact: he advises the opposite — disable only options you are sure you do not need, since parts of the system may rely on a specific one 2. And for the root filesystem the advice inverts entirely: build it into the kernel if you are not using a ramdisk 5.

“Đường dẫn trong sách là chuẩn cố định”“The paths in the book are a fixed standard”

Hiểu lầm: cứ gõ y nguyên đường dẫn là ra. Thực tế: chính ông đã cảnh báo cấu trúc sysfs liên tục thay đổi và một số liên kết nói trong chương có thể không còn 3. Hai mươi năm sau, tài liệu nhân nói thẳng rằng truy cập /sys/class/net/eth0/device là một lỗi của ứng dụng 6. Hãy học quan hệ, đừng học thuộc đường đi.

Myth: type the paths verbatim and they will work. Fact: he warned himself that the internal structure of sysfs constantly changes and some symlinks mentioned in the chapter might not be present 3. Twenty years on, kernel documentation states flatly that accessing /sys/class/net/eth0/device is a bug in the application 6. Learn the relationships, not the paths.

“Nhân đoán ra driver bằng tên thiết bị”“The kernel guesses the driver from the device name”

Hiểu lầm: nhân nhìn tên thiết bị rồi chọn driver. Thực tế: nó khớp bí danh sinh từ mã phần cứng với danh sách nội bộ mà mỗi driver khai báo 3; với PCI, danh sách ấy là bảng struct pci_device_id được xuất qua MODULE_DEVICE_TABLE 14. Tên eth0 là hệ quả, không phải nguyên nhân.

Myth: the kernel looks at a device name and picks a driver. Fact: it matches an alias derived from hardware IDs against the internal list each driver declares 3; for PCI that list is the struct pci_device_id table exported via MODULE_DEVICE_TABLE 14. The name eth0 is a consequence, not a cause.

Tự kiểmSelf-check

Tự kiểm trước khi sang chương 8 Tự hỏi mình vài câu Self-check before Chapter 8

Chương này có lệnh để gõ, và cách kiểm tra tốt nhất là gõ chúng trên chính máy bạn. Các câu dưới đây đo xem bạn đã nắm quan hệ hay mới thuộc đường dẫn.

Chương này có lệnh để gõ thật. Cách kiểm tra tốt nhất là mở máy ra gõ thử. Nhớ nhé: gõ được trên máy mình mới là hiểu.

This chapter has commands to type, and the best check is typing them on your own machine. The questions below measure whether you hold the relationships or merely memorised the paths.

  1. Bạn kiểm tra được máy mình có /proc/config.gz hay không, và nói được vì sao một số máy không có?

    Câu trả lời nằm ở tùy chọn CONFIG_IKCONFIG_PROC của người dựng nhân, không ở thao tác của bạn 12.

  2. Bạn mô tả lại được chuỗi ba liên kết đưa từ một tên thiết bị đến tên module, và nói được mỗi liên kết trỏ tới cái gì?

    thiết bị → device → driver → module; readlink lấy đích, basename cắt lấy tên cuối 3.

  3. Cho một tên module bất kỳ, bạn tìm ra tùy chọn CONFIG_ tương ứng bằng mấy lệnh?

    Một lệnh find … | xargs grep <tên module>, rồi nhìn dòng có chuỗi CONFIG_ 3.

  4. Bạn phân biệt được hai tình huống: thiết bị đang chạy tốt, và thiết bị chưa được nhận? Mỗi tình huống dùng lối nào?
  5. Với máy của bạn, ba driver nào phải có mặt để khởi động được — loại hệ thống tệp, driver đĩa, và bộ điều khiển?

    Bắt đầu bằng mount | grep " / ", rồi leo ngược trong sysfs cho tới khi gặp liên kết driver 5.

  6. Bạn giải thích được vì sao find_all_modules.sh không nạp module nào dù có gọi modprobe?

    Vì --show-depends chỉ liệt kê phụ thuộc thay vì nạp, còn --config /dev/null gạt cấu hình riêng của máy ra 7.

  1. Máy bạn có tệp /proc/config.gz không? Gõ thử ls /proc/config.gz xem sao.
  2. Bạn chỉ ra được ba "lối tắt" nối từ tên thiết bị tới tên mảnh ghép không?
  3. Có tên mảnh ghép rồi, bạn tìm nút cần bật bằng cách nào?
  4. Thiết bị đang chạy và thiết bị chưa chạy — hai trường hợp dùng cách khác nhau thế nào?
  5. Ổ chứa hệ điều hành của bạn tên gì, định dạng gì? Gõ mount | grep " / " là biết.
  6. Nhớ nhé: trả lời được cả năm câu thì sang chương 8 được rồi.
  1. Can you check whether your machine has /proc/config.gz, and say why some machines do not?

    The answer lies in whoever built the kernel setting CONFIG_IKCONFIG_PROC, not in anything you did 12.

  2. Can you describe the chain of three symlinks from a device name to a module name, and say what each points at?

    device → device → driver → module; readlink takes the target, basename keeps the last name 3.

  3. Given any module name, how many commands does it take you to find its CONFIG_ option?

    One: find … | xargs grep <module>, then look for the line containing CONFIG_ 3.

  4. Can you tell the two situations apart — a device that already works versus one the kernel does not recognise — and name the route each takes?
  5. For your own machine, which three drivers must be present to boot: filesystem type, disk driver, and controller?
  6. Can you explain why find_all_modules.sh loads nothing even though it calls modprobe?

    Because --show-depends only lists dependencies instead of inserting, and --config /dev/null shuts out the machine's own configuration 7.

Đọng lạiWhat remains

Phần khó nhất của việc tự dựng nhân không phải là biên dịch, mà là biết chính xác driver nào máy bạn cần. Và câu trả lời không nằm trong tài liệu — nó nằm trong chính cái máy đang chạy trước mặt bạn, viết bằng những liên kết tượng trưng dưới /sys.

Việc khó nhất không phải là gõ lệnh dựng, mà là biết máy mình cần mảnh nào. Mà câu trả lời thì đã nằm sẵn trong máy rồi. Nhớ nhé: hỏi máy trước khi tra sách.

The hardest part of building your own kernel is not compiling; it is knowing exactly which drivers your machine needs. And the answer is not in the documentation — it is in the running machine in front of you, written in symlinks under /sys.