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.
driver → liên kết module → tên module.
Đi theo các "lối tắt" trong /sys để ra tên mảnh ghép.
From a device name → the driver link → the module link → the module name.
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
-
/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 blueprintPhầ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ệnhls /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ằnggzip -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.configvà 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.config2. Nhớ nhé: một lệnh là biết có hay không.Most distribution kernels are built to include the configuration within the
/procfilesystem. Checking is a singlels /proc/config.gz; if the file is there, copy it into your source directory and uncompress it withgzip -dv config.gz— in the book's example it reports 74.9 % 2. Rename it to.configand 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ùngCONFIG_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_PROC12. 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_IKCONFIGoption (“Kernel .config support”) together withCONFIG_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-ikconfigtrong cây mã nguồn 12. Nghĩa là ngay cả khi/proc/config.gzvắ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.
-
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 localmodconfiglà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 localmodconfigkhông có trong sách và không phải phát biểu của Kroah-Hartman — nó là mục tiêumakeđượ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 trongmenuconfig2.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/
-
one-line traversal
Một dòng lệnh — từ
eth0đếne1000Một dòng lệnh ra ngay tên mảnh ghép One line — frometh0toe1000Ví 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 địnheth0là 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 rae10003. Ông tách dòng ấy thành bốn bước: theo liên kếtdevicevào cây/sys/devices/; từ đó theo liên kếtdriver; từ đó theo liên kếtmodule; 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ùngifconfig -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:e10003. 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/andifconfig -aidentifyeth0as the live interface, everything else collapses into one line:basename `readlink /sys/class/net/eth0/device/driver/module`, which printse10003. He unpacks it into four steps: follow thedevicesymlink into the/sys/devices/tree; from there follow thedriversymlink; from there themodulesymlink; 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/modulevà nhận đượcpl23033.Gặp ở đâu. Đổi
netthànhttylà tra được thiết bị khác: cáp USB-serial cho rapl23033. 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/moduleand getspl23033.Ghi chú thời gian: liên kết
deviceLờ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/devicelà 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. -
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 aCONFIG_optionBiế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
Makefiletrong cây mã nguồn:find -type f -name Makefile | xargs grep e1000, và kết quả chứa dòngobj-$(CONFIG_E1000) += e1000/3. Điều cần nhìn là bất kỳ dòng nào có chuỗiCONFIG_— đó chính là tùy chọn phải bật 3. Với ví dụ USB, cùng cách làm cho raCONFIG_USB_SERIAL_PL23033.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ệpMakefile, và thấy dòng có chữCONFIG_E10003. 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 containsobj-$(CONFIG_E1000) += e1000/3. The thing to look for is any line carrying the termCONFIG_— that is the option the kernel needs enabled 3. For the USB example the same method yieldsCONFIG_USB_SERIAL_PL23033.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ầnCONFIG_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 theCONFIG_prefix 3. The configuration system then tells you exactly where in the menus to select it 3.Tìm kiếm trong
menuconfighôm nayCơ chế ấy còn nguyên. Tài liệu
kconfighiệ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.8và 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. -
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áchmodalias— let the kernel read the list out for youSau 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.sh3. Nó duyệtsysfstìm mọi tệp tênmodalias— tệp này chứa bí danh module, thứ nói chomodprobebiế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
/sysnhặt các tệp tênmodalias— 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.sh3. It goes throughsysfsfinding every file calledmodalias— that file holds the module alias that tellsmodprobewhich 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;
modprobedò 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;
modprobesearches 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 -u3Vì sao nó không nạp gì cả
Hai cờ làm nên sự an toàn.
--show-dependschỉ 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ắcinstall/removeriê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ặcFATAL: 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
-
PCI device
Thiết bị PCI — bảy bước từ
lspciđếnCONFIG_Thiết bị cắm trong máy A PCI device — seven steps fromlspcitoCONFIG_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 ethernetcho ra dòng06: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ưnglspcikhông in ra — rồi đọc hai tệpvendorvàdevice:0x10ecvà0x81394.Ví dụ là một card mạng cắm trong máy nhưng chưa chạy. Lệnh
lspcicho biết nó nằm ở vị trí06:04.04. Vào thư mục tương ứng trong/sys(nhớ thêm0000:ở đầu) rồi đọc hai con số:0x10ecvà0x81394. 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 ethernetprints06:04.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+ (rev 10)4. Go into/sys/bus/pci/devices/— remembering the leading0000:the kernel uses butlspcidoes not print — and read thevendoranddevicefiles:0x10ecand0x81394.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 0x10eccho raPCI_VENDOR_ID_REALTEK, vàgrep -i 0x8139cho raPCI_DEVICE_ID_REALTEK_81394 — 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_REALTEKvàPCI_DEVICE_ID_REALTEK_81394. 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 0x10ecyieldsPCI_VENDOR_ID_REALTEKandgrep -i 0x8139yieldsPCI_DEVICE_ID_REALTEK_81394 — 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.c4. Mọi driver PCI đều mang danh sách thiết bị hỗ trợ trong một cấu trúcstruct pci_device_id— đó là chỗ phải nhìn 4. Bảng củar8169.ckhai0x8169và0x8129, không có0x8139, nên nó bị loại 4.Khi driver tự chỉ sang driver khác
8139too.ckhô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.cquả nhiên khai cảPCI_VENDOR_ID_REALTEKlẫnPCI_DEVICE_ID_REALTEK_8139, kèmMODULE_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_tabletới bảngstruct pci_device_id, và “phần lớn driver nên xuất bảng này bằngMODULE_DEVICE_TABLE(pci,...)” — chính là thứ sinh ra cácmodaliasmàmodprobedò tìm 14. -
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òngID 0000:0000vì đó 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ạilsusb, và dòng biến mất chính là thiết bị cần tìm — trong ví dụ là157e:300d4.Với thiết bị cắm ngoài, cách làm dễ hơn. Chạy
lsusbxem 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 showingID 0000:0000, which are the USB host controllers driving the bus itself 4. Then he uses a very physical trick: unplug the device, runlsusbagain, and the line that vanished is your device — here157e:300d4.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.hKhá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ạidrivers/net/wireless/zd1211rw/zd_usb.c4.Bảng
struct usb_device_idTrong tệp ấy,
157exuất hiện trong một mảngusb_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ếnstruct 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 -nin mã nhà sản xuất và mã thiết bị dưới dạng số thay vì tra tên,-nnin cả hai dạng, còn-kcho 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ờ-klà 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ếtCONFIG_nào, nên bước traMakefilevẫn còn nguyên. Và tiến trìnhudevmà 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
-
walking up the chain
Đi ngược lên cây thiết bị cho đến khi gặp
driverLeo ngược lên từng bậc Walking up the device chain until adriverappearsBắ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/sda2và loại tệp làext35. Vìsda2là 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àext35. Số 2 nghĩa là phân vùng; phải lo cho cả ổsdachứ 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/sda2and the type isext35. Becausesda2is a partition — partitions are numbered, main block devices are not — the wholesdadevice 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ếtdevicedẫn xuống sâu trong/sys/devices/pci0000:00/0000:00:1f.2/host0/…, nơi có liên kếtdrivertrỏ tớisd— driver đĩa SCSI 5. Đi tiếp lên hai bậc nữa mới gặp liên kếtdriverthứ 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ảnhsd; leo ngược lên vài bậc nữa, gặp mảnhata_piix5. Nhớ nhé: chưa thấy chữdriverthì leo tiếp một bậc.Where you see it. From
/sys/block/sda, thedevicelink leads deep into/sys/devices/pci0000:00/0000:00:1f.2/host0/…, where adriverlink points atsd— the SCSI disk driver 5. Two more levels up the chain sits the seconddriverlink:ata_piix, the disk controller 5. -
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 leoget-driver.sh— a script built to survive version churnChươ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ệcsysfsliê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 aboutsysfsconstantly moving around 3.Bạn thấy nó ở đâu. Với ví dụ vừa làm bằng tay,
get-driver.sh sdain ra đúng hai dòngfound driver: sdvàfound driver: ata_piix5. VớittyUSB0nó lần ra cả chuỗi:pl2303, rồiusbtừ moduleusbcore, rồiuhci_hcd5.Gặp ở đâu. Gõ
get-driver.sh sdalà ra ngaysdvàata_piix5. 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 sdaprints exactly two lines,found driver: sdandfound driver: ata_piix5. ForttyUSB0it traces the whole chain:pl2303, thenusbfrom moduleusbcore, thenuhci_hcd5.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
sysfstương ứng bằng cách dò lần lượt/sys/class,/sys/block,/sys/bus; giải liên kết bằngreadlink -f; gỡ liên kếtdevicekiểu cũ về thiết bị cha; rồi lặpwhile test "$DEVPATH" != "/", mỗi vòng thử đọc$DEVPATH/drivervà$DRIVERPATH/moduletrước khidirnamelê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
findthay 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ệusysfshiệ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.
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.
- Bạn kiểm tra được máy mình có
/proc/config.gzhay 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_PROCcủa người dựng nhân, không ở thao tác của bạn 12. - 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;readlinklấy đích,basenamecắt lấy tên cuối 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ỗiCONFIG_3. - 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?
- 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 trongsysfscho tới khi gặp liên kếtdriver5. - Bạn giải thích được vì sao
find_all_modules.shkhông nạp module nào dù có gọimodprobe?Vì
--show-dependschỉ liệt kê phụ thuộc thay vì nạp, còn--config /dev/nullgạt cấu hình riêng của máy ra 7.
- Máy bạn có tệp
/proc/config.gzkhông? Gõ thửls /proc/config.gzxem sao. - 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?
- 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?
- 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?
- Ổ chứa hệ điều hành của bạn tên gì, định dạng gì? Gõ
mount | grep " / "là biết. - Nhớ nhé: trả lời được cả năm câu thì sang chương 8 được rồi.
- 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. - 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;readlinktakes the target,basenamekeeps the last name 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 containingCONFIG_3. - 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?
- For your own machine, which three drivers must be present to boot: filesystem type, disk driver, and controller?
- Can you explain why
find_all_modules.shloads nothing even though it callsmodprobe?Because
--show-dependsonly lists dependencies instead of inserting, and--config /dev/nullshuts 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.