Chương 1 · Bức tranh toàn cảnh Chapter 1 · The Big Picture
Một hệ thống Linux chỉ dễ hiểu khi bạn cắt nó thành ba tầng Máy Linux giống một toà nhà ba tầng A Linux system only becomes understandable once you cut it into three levels
Brian Ward mở đầu quyển sách bằng một nhận xét rất đời thường: nhìn thoáng qua, một hệ điều hành hiện đại như Linux phức tạp đến chóng mặt, với vô số mảnh chạy và trò chuyện với nhau cùng lúc.1 Cách hiệu quả nhất để hiểu nó, theo ông, là trừu tượng hoá — tạm gác lại hầu hết chi tiết cấu tạo của một bộ phận, để tập trung vào mục đích và cách vận hành cơ bản của nó.1
Máy tính chạy Linux thoạt nhìn rối lắm: rất nhiều thứ chạy cùng lúc. Nhưng bạn không cần biết hết. Giống như đi ô tô: bạn chỉ cần biết xe chở bạn đi và cách mở cửa, cài dây an toàn — không cần biết con ốc nào giữ động cơ. Cách nghĩ “bỏ bớt chi tiết, giữ lại mục đích” đó gọi là trừu tượng hoá. Nhớ nhé: muốn hiểu máy tính, đừng nhìn hết một lượt — hãy nhìn từng tầng một.
Brian Ward opens the book with a very ordinary observation: at first glance a contemporary operating system such as Linux is dizzyingly complicated, with a great many pieces running and communicating at once.1 The most effective way to understand it, he argues, is abstraction — setting aside most of the details that make up a piece, and concentrating instead on its basic purpose and operation.1
Điểm tinh tế trong lập luận của ông là trừu tượng hoá không chỉ để học, mà còn để gỡ lỗi. Ông lấy ví dụ: khi xe chạy xóc, bạn lần lượt loại trừ ba trừu tượng — chiếc xe, cách bạn lái, và mặt đường — để khoanh vùng nguyên nhân.1 Toàn bộ kỹ năng quản trị hệ thống trong mười sáu chương còn lại đều là biến thể của động tác khoanh vùng đó.
Luận đề của chương: một hệ thống Linux đang chạy có ba tầng chính — phần cứng ở dưới cùng, kernel (nhân) ở giữa, và user space (không gian người dùng) ở trên; hiểu ba tầng đó cùng đường ranh giới giữa chúng là đủ để định vị gần như mọi vấn đề.1
Ý chính: máy Linux có ba tầng — phần cứng, nhân, và chỗ các chương trình của bạn chạy. Biết một thứ nằm tầng nào là bạn đã hiểu một nửa rồi. Nhớ nhé: ba tầng, từ dưới lên — máy, nhân, chương trình.
The chapter's thesis: a running Linux system has three main levels — hardware at the base, the kernel in the middle, and user space on top; understanding those three and the boundaries between them is enough to locate almost any problem.1
Cụm khái niệm 01 Concept cluster 01
Trừu tượng hoá, thành phần, và ba tầng của hệ thống Chia nhỏ ra thì mới hiểu được Abstraction, components, and the three levels
Ward nói rõ rằng trừu tượng hoá một mình thì chưa đủ: nó “không hoạt động nếu thiếu tổ chức”. Vì vậy các thành phần được xếp thành tầng — cách phân loại dựa trên vị trí của thành phần trên trục từ người dùng xuống phần cứng.1
Chia nhỏ thôi chưa đủ, còn phải xếp cho gọn. Người ta xếp các mảnh thành tầng: mảnh nào gần bạn thì ở trên, mảnh nào gần máy thì ở dưới. Nhớ nhé: chia nhỏ rồi xếp tầng, thế là hết rối.
Ward is explicit that abstraction alone is not enough: it "doesn't work without organization." Components are therefore arranged into layers — classifications based on where a component sits between the user and the hardware.1
Định nghĩa. Một tầng (level, layer) là một nhóm thành phần được phân loại theo khoảng cách của chúng tới phần cứng. Trình duyệt web và trò chơi nằm ở tầng trên cùng; dưới đáy là bộ nhớ trong phần cứng — các số 0 và 1. Hệ điều hành chiếm phần lớn các tầng ở giữa.1
Nói đơn giản. Tầng là “kệ sách”: kệ trên để thứ bạn chạm vào, kệ dưới để thứ máy chạm vào. Nhớ nhé: càng xuống dưới càng gần 0 và 1.
Definition. A level (or layer) is a grouping of components classified by how far they sit from the hardware. Web browsers and games sit at the top layer; at the bottom is the memory in the hardware — the 0s and 1s. The operating system occupies many of the layers in between.1
hệ thống Linux = user space
+ kernel
+ hardware
máy Linux = chương trình
+ nhân
+ máy thật
linux system = user space
+ kernel
+ hardware
-
abstraction
Trừu tượng hoá — quyền được bỏ qua chi tiết Trừu tượng hoá — cho phép mình không biết hết Abstraction — the right to ignore detail
Ward định nghĩa trừu tượng hoá theo lối rất thực dụng: đó là cách nói hoa mỹ cho việc bạn có thể bỏ qua hầu hết chi tiết cấu thành một bộ phận, và thay vào đó tập trung vào mục đích cùng cách vận hành cơ bản của nó.1
Trừu tượng hoá nghĩa là: bạn được phép không biết mọi thứ. Bạn biết cái nút để làm gì là đủ, chưa cần biết bên trong nút có gì. Nhớ nhé: biết để làm gì trước, biết làm bằng cách nào sau.
Ward's definition is pragmatic: abstraction is a fancy way of saying you can ignore most of the details that make up a piece you're trying to understand, and concentrate instead on its basic purpose and operation.1
Bạn gặp nó ở đâuWhere you meet it Mỗi lần bạn gõ một lệnh mà không cần biết nó nói chuyện với đĩa ra sao, bạn đang tiêu thụ một trừu tượng do người khác dựng sẵn. Mỗi lần bạn bấm một nút mà vẫn dùng được máy. Every time you type a command without knowing how it talks to the disk, you are consuming an abstraction someone else built.Ví dụ của tác giả
Ông dùng hình ảnh chiếc ô tô: là hành khách, bạn chỉ cần biết xe chở bạn đi và cách mở cửa, cài dây an toàn. Nhưng nếu phải lái, bạn buộc phải tách trừu tượng đó thành ba phần: chiếc xe, các bộ điều khiển, và mặt đường.1
Vì sao điều này quan trọng
Quản trị viên chính là “người lái”, không phải “hành khách”. Đó là lý do quyển sách không dừng ở mức mô tả giao diện mà đi xuống tận cơ chế.
-
component
Component — mảnh phần mềm đã được trừu tượng hoá Component — một mảnh ghép Component — an abstracted piece of software
Trong phần mềm có nhiều tên gọi cho một đơn vị đã được chia nhỏ — subsystem, module, package — nhưng Ward chọn từ component cho chương này vì nó đơn giản.1 Điểm đáng nhớ: khi dựng một component, lập trình viên thường không bận tâm cấu trúc bên trong của các component khác, mà chỉ quan tâm dùng được gì và dùng ra sao.1
Một component là một mảnh ghép làm xong một việc. Người làm mảnh này không cần mở mảnh kia ra xem bên trong — chỉ cần biết cách lắp vào nhau. Nhớ nhé: mảnh ghép chỉ cần khớp mép, không cần giống ruột.
Software has many names for an abstracted subdivision — subsystem, module, package — but Ward picks component for this chapter because it is simple.1 The point to keep: when building a component, developers typically don't think much about the internal structure of other components, only about which ones they can use and how.1
Bạn gặp nó ở đâuWhere you meet it Một máy chủ web gọi một máy chủ cơ sở dữ liệu, máy chủ đó lại dùng một thư viện dùng chung — ví dụ mở đầu chương chính là một chuỗi component.1 Một chương trình nhờ chương trình khác làm hộ một việc. A web server talks to a database server, which in turn uses a shared library — the chapter's opening example is exactly a chain of components.1 -
level / layer
Ba tầng — phần cứng, nhân, không gian người dùng Ba tầng: máy, nhân, chương trình The three levels — hardware, kernel, user space
Hình 1-1 trong sách vẽ đúng ba tầng đó. Đáy là phần cứng: bộ nhớ, một hoặc nhiều CPU để tính toán và đọc/ghi bộ nhớ, cùng các thiết bị như đĩa và giao diện mạng. Trên đó là nhân, lõi của hệ điều hành. Trên cùng là không gian người dùng, tập hợp các tiến trình đang chạy.1
Tầng dưới cùng là máy thật: bộ xử lý, bộ nhớ, đĩa, dây mạng. Tầng giữa là nhân — người điều phối. Tầng trên là các chương trình đang chạy. Nhớ nhé: đếm từ dưới lên — máy, nhân, chương trình.
Figure 1-1 in the book draws exactly those three. At the base is hardware: memory, one or more CPUs to compute and to read from and write to memory, plus devices such as disks and network interfaces. Above it sits the kernel, the core of the operating system. On top is user space, the collection of running processes.1
Ward mô tả nhân bằng một câu rất gọn mà đáng thuộc: nhân là phần mềm nằm trong bộ nhớ, bảo CPU tìm tác vụ kế tiếp ở đâu; nó đóng vai trung gian, quản lý phần cứng — đặc biệt là bộ nhớ chính — và là giao diện chính giữa phần cứng với mọi chương trình đang chạy.1
Bạn gặp nó ở đâuWhere you meet it Mỗi khi phải trả lời “lỗi này của ứng dụng, của nhân, hay của phần cứng?”, bạn đang dùng đúng ba tầng này làm lưới khoanh vùng. Khi máy hỏng, bạn hỏi: hỏng ở tầng nào? Every time you ask "is this the application, the kernel, or the hardware?", you are using these three levels as a triage grid. -
bit · state · image
Bộ nhớ chính — nơi mọi thứ thật sự tồn tại Bộ nhớ — chỗ mọi thứ đang nằm Main memory — where everything actually lives
Trong tất cả phần cứng, Ward coi bộ nhớ chính có lẽ là quan trọng nhất. Ở dạng thô nhất, nó chỉ là một vùng lưu trữ lớn chứa các số 0 và 1; mỗi ô chứa một 0 hoặc 1 gọi là một bit. Nhân và các tiến trình đều cư trú ở đó — chúng chỉ là những tập hợp bit rất lớn. CPU, theo cách nói của ông, chỉ là một toán tử trên bộ nhớ: đọc lệnh và dữ liệu từ bộ nhớ rồi ghi dữ liệu trở lại.1
Bộ nhớ là một cái bảng khổng lồ toàn số 0 và 1. Mỗi ô là một bit. Nhân và mọi chương trình đều đang nằm trên bảng đó. CPU chỉ làm hai việc: đọc bảng và viết lên bảng. Nhớ nhé: mọi thứ đang chạy đều đang nằm trong bộ nhớ.
Of all the hardware, Ward considers main memory perhaps the most important. In its rawest form it is just a big storage area for 0s and 1s; each slot for a 0 or 1 is a bit. The kernel and the processes all reside there — they are just big collections of bits. A CPU, in his phrasing, is just an operator on memory: it reads its instructions and data from memory and writes data back out to it.1
Bạn gặp nó ở đâuWhere you meet it Mọi đầu vào và đầu ra từ thiết bị ngoại vi đều chảy qua bộ nhớ chính, cũng dưới dạng bit.1 Mọi thứ đi vào hay đi ra máy đều phải qua bộ nhớ. All input and output from peripheral devices flows through main memory, also as bits.1State (trạng thái)
Nói chặt chẽ, một state là một cách sắp xếp bit cụ thể: với bốn bit, các chuỗi 0110, 0001 và 1011 là ba trạng thái khác nhau.1 Vì một tiến trình có thể gồm hàng triệu bit, ta thường mô tả trạng thái bằng lời — “tiến trình đang chờ đầu vào” — thay vì liệt kê bit.1
Image (ảnh)
Vì thói quen nói về trạng thái ở mức trừu tượng, Ward dành riêng từ image cho một cách sắp xếp bit vật lý cụ thể.1 Phân biệt này sẽ quay lại khi sách bàn về tiến trình ở Chương 8.
Cụm khái niệm 02 Concept cluster 02
Nhân: bốn nhiệm vụ, một đường ranh giới Nhân làm bốn việc The kernel: four duties, one boundary
Ward gom công việc của nhân vào bốn khu vực chung: tiến trình, bộ nhớ, trình điều khiển thiết bị, và lời gọi hệ thống cùng các hỗ trợ khác.1 Bốn khu vực này cũng chính là bốn ô nằm trong khối “Linux Kernel” của Hình 1-1.
Nhân làm bốn việc: chia lượt CPU cho các chương trình, chia chỗ trong bộ nhớ, nói chuyện với thiết bị, và nhận yêu cầu từ chương trình. Nhớ nhé: chia lượt, chia chỗ, nói chuyện với máy, nhận yêu cầu.
Ward groups the kernel's work into four general system areas: processes, memory, device drivers, and system calls and support.1 These are also the four boxes inside the "Linux Kernel" band of Figure 1-1.
Về con số bốn. Bốn là cách chia của chính quyển sách này, chứ không phải một hằng số của ngành. Hình 1-1 thậm chí vẽ trình điều khiển thiết bị thành một dải riêng bên dưới ba ô còn lại.1 Các giáo trình hệ điều hành mà Ward tự giới thiệu ở cuối mục — trong đó có Operating System Concepts, 10th ed. — lại liệt kê nhiệm vụ của nhân theo những cách chi tiết hơn, tách riêng quản lý hệ thống tệp và quản lý vào/ra.110 Ở đây trang này theo cách chia bốn của Ward và ghi chú sự khác biệt thay vì lặng lẽ chọn một bên.
Đường ranh giới. Có một khác biệt then chốt giữa cách nhân và tiến trình người dùng chạy: nhân chạy ở chế độ nhân (kernel mode), tiến trình người dùng chạy ở chế độ người dùng (user mode). Mã chạy ở chế độ nhân có quyền truy cập không hạn chế vào bộ xử lý và bộ nhớ chính — một đặc quyền mạnh nhưng nguy hiểm.1
Ranh giới. Nhân được phép làm mọi thứ. Chương trình thường thì không. Vì thế chương trình hỏng thì chỉ nó chết, còn nhân hỏng thì cả máy chết. Nhớ nhé: quyền càng lớn, hỏng càng đau.
The boundary. There is a critical difference between how the kernel and user processes run: the kernel runs in kernel mode, user processes run in user mode. Code running in kernel mode has unrestricted access to the processor and main memory — a powerful but dangerous privilege.1
kernel mode → toàn quyền CPU + RAM
user mode → tập con an toàn
kernel space → chỉ nhân chạm được
user space → tiến trình chạm được
nhân → được làm mọi thứ
chương trình → chỉ được làm ít
vùng nhân → khoá
vùng người dùng → mở
kernel mode → full CPU + RAM
user mode → safe subset
kernel space → kernel only
user space → processes only
-
process management
Quản lý tiến trình — chia lượt CPU Chia lượt cho từng chương trình Process management — sharing out the CPU
Quản lý tiến trình mô tả việc khởi động, tạm dừng, tiếp tục, lập lịch và kết thúc tiến trình.1 Với một CPU một lõi, nhiều tiến trình có thể dùng CPU nhưng chỉ một tiến trình thật sự dùng nó tại một thời điểm: mỗi tiến trình dùng CPU trong một phần nhỏ của giây rồi tạm dừng, tiến trình khác tới lượt, và cứ thế. Hành động một tiến trình nhường quyền điều khiển CPU cho tiến trình khác gọi là context switch (chuyển ngữ cảnh).1
Máy trông như đang chạy nhiều chương trình cùng lúc, nhưng thật ra chúng thay phiên nhau rất nhanh — nhanh đến mức mắt người không kịp thấy. Mỗi lần đổi phiên gọi là chuyển ngữ cảnh. Nhớ nhé: không phải cùng lúc, mà là thay phiên siêu nhanh.
Process management covers the starting, pausing, resuming, scheduling and terminating of processes.1 On a one-core CPU, many processes may be able to use the CPU but only one actually uses it at any given time: each runs for a small fraction of a second, then pauses, then another takes a turn. One process giving up control of the CPU to another is called a context switch.1
Bạn gặp nó ở đâuWhere you meet it Mỗi lát thời gian (time slice) đủ để tiến trình tính toán đáng kể, nhưng vì quá ngắn nên con người không cảm nhận được — cảm giác “chạy song song” đó chính là đa nhiệm.1 Bạn vừa nghe nhạc vừa lướt web mà không thấy giật. Each time slice gives a process enough time for significant computation, but the slices are so small that humans can't perceive them — that illusion of simultaneity is multitasking.1Bảy bước của một lần chuyển ngữ cảnh
Ward liệt kê bảy bước khi một tiến trình hết lát thời gian: CPU ngắt tiến trình theo bộ định thời nội bộ và chuyển sang chế độ nhân; nhân ghi lại trạng thái hiện tại của CPU và bộ nhớ; nhân xử lý các việc phát sinh trong lát vừa rồi (như thu thập dữ liệu vào/ra); nhân xem danh sách tiến trình sẵn sàng và chọn một; nhân chuẩn bị bộ nhớ rồi chuẩn bị CPU cho tiến trình mới; nhân báo cho CPU lát thời gian mới dài bao lâu; cuối cùng nhân chuyển CPU về chế độ người dùng và trao quyền.1
Khi nào thì nhân chạy?
Đây là câu trả lời quan trọng mà chuỗi bảy bước hé lộ: nhân chạy giữa các lát thời gian của tiến trình, trong lúc chuyển ngữ cảnh.1 Trên máy nhiều CPU, nhân không bắt buộc phải nhả CPU hiện tại để tiến trình chạy trên CPU khác, nhưng thường vẫn thực hiện các bước này để tận dụng mọi CPU.1 Cách Linux hiện nay chọn tiến trình kế tiếp được mô tả trong tài liệu bộ lập lịch của nhân.7
-
memory management
Quản lý bộ nhớ — MMU và bộ nhớ ảo Chia chỗ trong bộ nhớ Memory management — the MMU and virtual memory
Nhân phải quản lý bộ nhớ trong lúc chuyển ngữ cảnh, và đây là việc phức tạp vì phải thoả nhiều điều kiện cùng lúc: nhân có vùng riêng mà tiến trình người dùng không chạm được; mỗi tiến trình có phần bộ nhớ riêng; tiến trình này không được đọc vùng riêng của tiến trình kia; nhưng tiến trình có thể chia sẻ bộ nhớ; một phần bộ nhớ có thể chỉ đọc; và hệ thống có thể dùng nhiều bộ nhớ hơn lượng vật lý sẵn có bằng cách mượn dung lượng đĩa.1
Nhân phải chia bộ nhớ sao cho mỗi chương trình có chỗ riêng, không ai ngó vào chỗ của ai, nhưng vẫn cho phép hai chương trình dùng chung một chỗ khi cần. Nhớ nhé: mỗi chương trình một phòng riêng, có khoá.
The kernel must manage memory during a context switch, and it is complex because several conditions must hold at once: the kernel has a private area user processes can't access; each process gets its own section; one process may not access another's private memory; yet processes can share memory; some process memory can be read-only; and the system can use more memory than is physically present by using disk space as auxiliary.1
Bạn gặp nó ở đâuWhere you meet it May cho nhân là có trợ thủ phần cứng: CPU hiện đại có đơn vị quản lý bộ nhớ (MMU) cho phép cơ chế bộ nhớ ảo.16 Có một mạch nhỏ trong CPU chuyên lo việc dịch địa chỉ. Fortunately the kernel has hardware help: modern CPUs include a memory management unit (MMU) enabling virtual memory.16Bộ nhớ ảo hoạt động thế nào
Với bộ nhớ ảo, tiến trình không truy cập bộ nhớ theo vị trí vật lý. Nhân thiết lập để mỗi tiến trình hành xử như thể nó sở hữu cả máy; khi tiến trình chạm vào bộ nhớ của mình, MMU chặn lại và dùng một bản đồ địa chỉ để dịch vị trí theo góc nhìn tiến trình thành vị trí vật lý thật.1
Page table
Ward ghi chú rằng hiện thực của bản đồ địa chỉ bộ nhớ được gọi là page table (bảng trang).1 Nhân phải khởi tạo và liên tục duy trì, sửa đổi bản đồ này — ví dụ khi chuyển ngữ cảnh, nó phải đổi bản đồ từ tiến trình đi ra sang tiến trình đi vào.1 Cấu trúc bảng trang nhiều cấp mà Linux dùng được mô tả trong tài liệu nhân.5
Ward hẹn quay lại cách xem hiệu năng bộ nhớ ở Chương 8.1
Ward defers how to inspect memory performance to Chapter 8.1
-
device drivers
Trình điều khiển thiết bị — một giao diện thống nhất Nói chuyện với thiết bị Device drivers — one uniform interface
Vai trò của nhân với thiết bị tương đối đơn giản. Một thiết bị thường chỉ truy cập được ở chế độ nhân, vì truy cập sai — chẳng hạn một tiến trình người dùng đòi tắt nguồn — có thể làm sập máy.1 Khó khăn đáng kể là các thiết bị hiếm khi có cùng giao diện lập trình, ngay cả khi chúng làm cùng một việc, ví dụ hai card mạng khác hãng.1
Mỗi loại thiết bị nói một “thứ tiếng” khác nhau. Trình điều khiển là người phiên dịch, để chương trình chỉ cần học một thứ tiếng duy nhất. Nhớ nhé: trình điều khiển là người phiên dịch của máy.
The kernel's role with devices is relatively simple. A device is typically accessible only in kernel mode, because improper access — a user process asking to turn off the power, say — could crash the machine.1 The notable difficulty is that different devices rarely share a programming interface even when they perform the same task, for example two different network cards.1
Bạn gặp nó ở đâuWhere you meet it Vì lý do đó, trình điều khiển theo truyền thống là một phần của nhân và cố gắng trình ra một giao diện thống nhất cho tiến trình người dùng, để đơn giản hoá công việc của lập trình viên.1 Nhờ vậy bạn cắm chuột hãng nào vào cũng dùng được. For that reason drivers have traditionally been part of the kernel, striving to present a uniform interface to user processes so as to simplify the developer's job.1 -
system call · fork() · exec()
Lời gọi hệ thống — cách tiến trình nhờ nhân Chương trình xin phép nhân System calls — how a process asks the kernel
Lời gọi hệ thống (syscall) thực hiện những tác vụ mà một tiến trình người dùng đơn lẻ không làm tốt hoặc không làm được: mở, đọc và ghi tệp đều cần lời gọi hệ thống.19 Hai lời gọi đặc biệt quan trọng để hiểu tiến trình khởi động ra sao là
fork()vàexec(): khi một tiến trình gọifork(), nhân tạo một bản sao gần như y hệt của tiến trình đó; khi nó gọiexec(program), nhân nạp và khởi chạy program, thay thế tiến trình hiện tại.123Chương trình không tự làm được mọi thứ, nên nó phải nhờ nhân. Lời nhờ đó gọi là lời gọi hệ thống. Có hai lời nhờ nổi tiếng: một cái tự nhân đôi mình ra, một cái biến bản sao đó thành chương trình khác. Nhớ nhé: nhân đôi rồi hoá thân — đó là cách chương trình mới ra đời.
System calls (syscalls) perform tasks a user process alone cannot do well or at all: opening, reading and writing files all involve system calls.19 Two are especially important for understanding how processes start —
fork()andexec(): when a process callsfork(), the kernel creates a nearly identical copy of it; when it callsexec(program), the kernel loads and starts program, replacing the current process.123shell→ fork()copy of shell→ exec(ls)lsBạn gặp nó ở đâuWhere you meet it Ví dụ đơn giản nhất là bất kỳ lệnh nào bạn gõ ở dòng lệnh, chẳng hạnls: shell đang chạy trong cửa sổ terminal gọifork()để tạo bản sao của chính nó, rồi bản sao đó gọiexec(ls)để chạyls.1 Mỗi lần bạn gõ một lệnh rồi bấm Enter. The simplest example is any command you type at the command line, such asls: the shell running in the terminal window callsfork()to copy itself, and the new copy callsexec(ls)to runls.1Quy ước dấu ngoặc và họ exec()
Ward ghi chú rằng lời gọi hệ thống thường được viết kèm cặp ngoặc đơn, theo lối viết trong ngôn ngữ C; bạn không cần biết C để đọc sách.1 Ông cũng nói thẳng rằng sách đã đơn giản hoá:
exec()thực ra chỉ tên cho cả một họ lời gọi làm việc tương tự nhưng khác nhau về cách lập trình.1 Trong Linux ngày nay, lời gọi thật ở tầng nhân làexecve(), còn các dạngexecl,execp… là lớp bọc thư viện.3Pseudodevice (thiết bị giả)
Ngoài lời gọi hệ thống truyền thống, nhân còn hỗ trợ tiến trình bằng các pseudodevice: trông như thiết bị với tiến trình người dùng, nhưng được hiện thực hoàn toàn bằng phần mềm. Về kỹ thuật chúng không nhất thiết phải nằm trong nhân, song thường vẫn ở đó vì lý do thực tiễn — ví dụ bộ sinh số ngẫu nhiên
/dev/randomrất khó hiện thực an toàn trong một tiến trình người dùng.14 Và Ward lưu ý: một tiến trình muốn chạm vào pseudodevice vẫn phải dùng lời gọi hệ thống để mở nó, nên không tiến trình nào thoát được syscall.1
Cụm khái niệm 03 Concept cluster 03
Không gian người dùng, người dùng, và ranh giới quyền Chương trình, người dùng và quyền hạn User space, users, and the permission boundary
Phần bộ nhớ chính mà nhân cấp cho tiến trình người dùng được gọi là không gian người dùng; vì một tiến trình chỉ là một trạng thái (hay ảnh) trong bộ nhớ, thuật ngữ này cũng chỉ bộ nhớ của toàn bộ tập tiến trình đang chạy.1 Ward cũng nhắc tới cách gọi thân mật userland.1
Chỗ trong bộ nhớ dành cho các chương trình gọi là không gian người dùng. Đó là nơi mọi thứ bạn nhìn thấy đang sống. Nhớ nhé: chương trình của bạn sống ở tầng trên cùng.
The main memory the kernel allocates for user processes is called user space; because a process is simply a state (or image) in memory, the term also refers to the memory of the entire collection of running processes.1 Ward also notes the informal term userland.1
Định nghĩa. Một người dùng là một thực thể có thể chạy tiến trình và sở hữu tệp. Người dùng thường gắn với một tên đăng nhập, nhưng nhân không quản lý tên — nó nhận dạng người dùng bằng những định danh số đơn giản gọi là user ID.18
Nói đơn giản. “Người dùng” không phải là con người — đó là một cái tên mà máy dùng để biết ai được làm gì. Máy nhớ bằng số, không nhớ bằng tên. Nhớ nhé: với nhân, bạn là một con số.
Definition. A user is an entity that can run processes and own files. A user is usually associated with a username, but the kernel does not manage usernames — it identifies users by simple numeric identifiers called user IDs.18
user → chạy tiến trình + sở hữu tệp
uid → định danh số của người dùng
group → tập người dùng, để chia sẻ tệp
root → ngoại lệ của mọi quy tắc trên
người dùng → chạy chương trình, giữ tệp
số → máy nhớ bạn bằng số
nhóm → để chia sẻ tệp
root → được làm mọi thứ
user → runs processes + owns files
uid → numeric identifier
group → set of users, for file sharing
root → the exception to all of the above
-
user space
Ba mức dịch vụ trong không gian người dùng Ba nấc trong tầng trên cùng Three service levels inside user space
Dưới mắt nhân, mọi tiến trình về cơ bản là như nhau; nhưng chúng làm những việc khác nhau cho người dùng, nên vẫn có một cấu trúc mức dịch vụ sơ khởi. Hình 1-3 xếp dịch vụ cơ bản ở dưới cùng (gần nhân nhất), dịch vụ tiện ích ở giữa, và ứng dụng mà người dùng chạm vào ở trên cùng.1
Trong tầng trên cùng lại có ba nấc nhỏ: nấc dưới là các việc lặt vặt đơn giản, nấc giữa là dịch vụ lớn hơn như in ấn hay cơ sở dữ liệu, nấc trên là thứ bạn bấm vào. Nhớ nhé: càng lên cao càng gần tay bạn.
From the kernel's point of view all processes are essentially equal; but they do different jobs for users, so a rudimentary service-level structure exists. Figure 1-3 places basic services at the bottom (closest to the kernel), utility services in the middle, and the applications users touch at the top.1
Bạn gặp nó ở đâuWhere you meet it Ví dụ của sách: trình duyệt web và giao diện người dùng ở trên cùng; một máy chủ đệm tên miền mà trình duyệt sử dụng ở giữa; cấu hình mạng, bus truyền thông và ghi nhật ký chẩn đoán ở dưới.1 Trình duyệt ở trên, mấy thứ chạy ngầm ở dưới. The book's example: the web browser and user interface on top; a name caching server the browser uses in the middle; network configuration, a communication bus and diagnostic logging below.1“Thật ra không có luật nào cả”
Ward cẩn thận hạ thấp chính sơ đồ của mình: Hình 1-3 chỉ là xấp xỉ, và trong thực tế không gian người dùng không có quy tắc cứng.1 Ví dụ, hầu hết chương trình dùng dịch vụ syslog chuẩn để ghi nhật ký, nhưng một số lại tự ghi lấy.111
Thành phần khó xếp hạng
Máy chủ web và máy chủ cơ sở dữ liệu có thể coi là ứng dụng rất cao cấp vì tác vụ phức tạp, nhưng ứng dụng khác lại phụ thuộc vào chúng để làm hộ việc — nên đặt chúng ở mức giữa cũng có lý.1 Trừu tượng là công cụ, không phải chân lý.
-
kernel space vs user space
Vì sao trình duyệt sập mà máy vẫn sống Một chương trình hỏng không làm hỏng cả máy Why a browser can crash and the machine survives
Vùng bộ nhớ chỉ nhân chạm được gọi là kernel space. Ngược lại, chế độ người dùng giới hạn truy cập vào một tập con bộ nhớ (thường khá nhỏ) và các thao tác CPU an toàn. Nếu một tiến trình mắc lỗi và sập, hậu quả bị giới hạn và nhân dọn dẹp được — nên trình duyệt của bạn sập thì phép tính khoa học chạy nhiều ngày trong nền nhiều khả năng vẫn sống.1
Mỗi chương trình chỉ được chơi trong sân của nó. Nếu nó ngã, nó ngã một mình; nhân dọn dẹp rồi mọi thứ chạy tiếp. Nhớ nhé: sân riêng thì tai nạn cũng riêng.
The memory area only the kernel can access is called kernel space. User mode, by contrast, restricts access to a (usually quite small) subset of memory and to safe CPU operations. If a process makes a mistake and crashes, the consequences are limited and the kernel can clean up — so if your web browser crashes, the scientific computation that has been running for days in the background probably survives.1
Giới hạn của lời hứa nàyThe limit of that promise Ward không hứa suông: trên lý thuyết một tiến trình lỗi không gây hại nghiêm trọng, nhưng thực tế còn tuỳ vào đặc quyền của tiến trình đó. Với quyền phù hợp, một tiến trình người dùng có thể phá hỏng dữ liệu trên đĩa — có các biện pháp bảo vệ, song chúng là biện pháp, không phải phép màu.1 Nhưng nếu bạn cho nó quyền quá lớn thì nó vẫn phá được. Nên đừng cho bừa. Ward does not oversell it: in theory a runaway process can't do serious damage, but in reality it depends on that process's privileges. With the right permissions a user process can wreck data on a disk — there are safeguards, but they are safeguards, not magic.1Có một ngoại lệ đáng nhớ: nhân Linux có thể chạy kernel thread — trông rất giống tiến trình nhưng truy cập được kernel space;
kthreaddvàkblockdlà hai ví dụ.1One exception is worth remembering: the Linux kernel can run kernel threads — they look much like processes but have access to kernel space;
kthreaddandkblockdare examples.1 -
user · user id
Người dùng tồn tại để dựng ranh giới Người dùng là để phân chia ranh giới Users exist to draw boundaries
Ward nói rõ mục đích: người dùng tồn tại chủ yếu để hỗ trợ quyền và ranh giới. Mỗi tiến trình trong không gian người dùng có một người dùng sở hữu, và ta nói tiến trình “chạy dưới danh nghĩa” người đó. Một người dùng có thể kết thúc hoặc thay đổi hành vi tiến trình của chính mình — trong giới hạn nhất định — nhưng không thể can thiệp vào tiến trình của người khác.1
Mỗi chương trình đang chạy đều thuộc về một ai đó. Bạn tắt được chương trình của mình, nhưng không tắt được chương trình của người khác. Nhớ nhé: của ai người nấy quản.
Ward is explicit about the purpose: users exist primarily to support permissions and boundaries. Every user-space process has a user owner and is said to run as that owner. A user may terminate or modify the behaviour of its own processes — within limits — but cannot interfere with another user's processes.1
Bạn gặp nó ở đâuWhere you meet it Một hệ thống Linux bình thường có nhiều người dùng hơn số con người thật đang dùng máy; ánh xạ từ tên đăng nhập sang user ID được bàn ở Chương 7.18 Máy bạn có nhiều “người dùng” hơn số người thật. A normal Linux system has more users than there are humans using it; how usernames map to user IDs is covered in Chapter 7.18 -
root · superuser · group
root — ngoại lệ, và vì sao đó là gánh nặng root — người được làm mọi thứ root — the exception, and why it is a burden
Người dùng quan trọng nhất cần biết là root. root là ngoại lệ của các quy tắc vừa nêu: root có thể kết thúc và thay đổi tiến trình của người dùng khác, và truy cập mọi tệp trên hệ thống cục bộ — vì vậy root được gọi là superuser. Người có thể thao tác với tư cách root là quản trị viên trên một hệ thống Unix truyền thống.1
root là “chìa khoá vạn năng”: mở được mọi cửa. Nghe thì oai, nhưng cầm chìa vạn năng thì lỡ tay là hỏng thật. Nhớ nhé: quyền càng to càng phải cẩn thận.
The most important user to know is root. root is the exception to the rules just given: it may terminate and alter other users' processes and access any file on the local system — which is why root is known as the superuser. A person who can operate as root is an administrator on a traditional Unix system.1
Cảnh báo của tác giảThe author's warning Vận hành với tư cách root có thể nguy hiểm: rất khó nhận ra và sửa sai vì hệ thống sẽ cho bạn làm bất cứ điều gì, kể cả điều gây hại. Vì thế người thiết kế hệ thống liên tục tìm cách làm cho quyền root càng ít cần thiết càng tốt — chẳng hạn không đòi root để đổi mạng không dây trên máy xách tay.1 Máy sẽ không ngăn bạn làm điều dại dột khi bạn là root. Operating as root can be dangerous: mistakes are hard to spot and correct because the system will let you do anything, even something harmful. System designers therefore keep trying to make root access less necessary — for example by not requiring root to switch wireless networks on a notebook.1root vẫn ở chế độ người dùng
Đây là chi tiết dễ bị bỏ qua nhất của chương: mạnh đến thế, root vẫn chạy ở chế độ người dùng của hệ điều hành, không phải chế độ nhân.1 root là một khái niệm về quyền, còn kernel mode là một khái niệm về đặc quyền phần cứng — hai trục hoàn toàn khác nhau.
Đính chính Corrections
Ba ngộ nhận mà người đọc lần đầu hay mắc Ba chỗ hay hiểu nhầm Three misconceptions first readers hit
Phần này thuộc mức đọc Đầy đủ: nó đối chiếu điều người đọc thường nghĩ với điều bản văn thật sự nói.
Phần này hơi khó, bạn có thể bỏ qua và quay lại sau. Nhớ nhé: hiểu chậm mà chắc vẫn hơn.
This block belongs to the Đầy đủ (full) reading level: it sets what readers usually assume against what the text actually says.
“Nhân là một chương trình chạy liên tục ở nền” "The kernel is a program running continuously in the background"
Ngộ nhận: nhân là một tiến trình luôn luôn chạy song song với các tiến trình khác.
Bản văn nói: chuỗi chuyển ngữ cảnh trả lời đúng câu hỏi “khi nào thì nhân chạy” — nó chạy giữa các lát thời gian của tiến trình, trong lúc chuyển ngữ cảnh.1
Misconception: the kernel is a process always running alongside the others.
The text says: the context-switch sequence answers exactly the question of when the kernel runs — it runs between process time slices, during a context switch.1
“Đa nhiệm nghĩa là chạy thật sự cùng lúc” "Multitasking means genuinely simultaneous execution"
Ngộ nhận: trình duyệt và bảng tính mở cùng lúc thì chúng đang chạy cùng lúc.
Bản văn nói: “mọi thứ không như vẻ ngoài” — các tiến trình phía sau những ứng dụng đó thường không chạy đúng cùng một thời điểm; trên CPU một lõi chúng luân phiên theo lát thời gian, và cảm giác đồng thời chính là hệ quả của lát quá ngắn.1 Trên máy nhiều CPU thì nhiều tiến trình có thể chạy thật sự cùng lúc, nhưng nhân vẫn thường thực hiện các bước chuyển ngữ cảnh để tận dụng mọi CPU.1
Misconception: a browser and a spreadsheet open at once are running at once.
The text says: "things are not as they appear" — the processes behind those applications typically do not run at exactly the same time; on a one-core CPU they alternate by time slice, and the sense of simultaneity is a consequence of the slices being tiny.1 On multi-CPU machines several processes can genuinely run at once, but the kernel usually performs the context-switch steps anyway to maximise use of all CPUs.1
“Là root thì tôi đang ở chế độ nhân” "Being root means I am in kernel mode"
Ngộ nhận: quyền cao nhất của hệ thống tệp cũng là quyền cao nhất của bộ xử lý.
Bản văn nói: mạnh đến thế, root vẫn chạy trong chế độ người dùng của hệ điều hành, không phải chế độ nhân.1 Hai trục — quyền người dùng và đặc quyền chế độ CPU — độc lập với nhau.
Misconception: the highest filesystem privilege is also the highest processor privilege.
The text says: as powerful as root is, it still runs in the operating system's user mode, not kernel mode.1 The two axes — user permission and CPU-mode privilege — are independent.
Tự kiểm tra Self-check
Bạn đã nắm bức tranh toàn cảnh chưa? Thử trả lời xem nào Do you have the big picture yet?
Trả lời bằng lời của bạn, không tra sách. Nếu một câu khiến bạn ngập ngừng, đó chính là tầng bạn nên đọc lại.
Thử trả lời miệng thôi, không cần giở lại. Câu nào bí thì quay lại đọc phần đó nhé. Nhớ nhé: chỗ bí chính là chỗ cần học.
Answer in your own words, without looking back. Whichever question makes you hesitate points at the level you should reread.
-
Ba tầng chính của một hệ thống Linux là gì, và cái nào nằm ngay sát phần cứng?
Gợi ý sâu hơn: hãy nói thêm nhân đóng vai trò gì giữa hai tầng còn lại.
-
Chuyển ngữ cảnh là gì, và câu hỏi nào về nhân được nó trả lời?
Gợi ý sâu hơn: thử kể lại bảy bước mà Ward liệt kê, ít nhất là bước đầu và bước cuối.
-
MMU và bộ nhớ ảo giải quyết điều kiện nào trong sáu điều kiện quản lý bộ nhớ?
Gợi ý sâu hơn: bản đồ địa chỉ bộ nhớ được hiện thực dưới tên gọi nào?
-
Vì sao gõ một lệnh ở terminal lại cần tới hai lời gọi hệ thống khác nhau?
Gợi ý sâu hơn: cái nào tạo ra tiến trình mới, và cái nào thay thế nội dung của nó?
-
root khác một người dùng thường ở điểm nào — và giống họ ở điểm nào?
Gợi ý sâu hơn: root chạy ở chế độ nào của CPU?
Máy Linux có mấy tầng? Kể tên từ dưới lên.
Nhiều chương trình chạy “cùng lúc” — thật ra chúng làm gì?
Nhân làm những việc gì? Kể được hai việc là tốt rồi.
Khi bạn gõ một lệnh, chuyện gì xảy ra trước tiên?
root là ai, và vì sao dùng root phải cẩn thận?
-
What are the three main levels of a Linux system, and which one sits directly against the hardware?
-
What is a context switch, and which question about the kernel does it answer?
-
Which of the six memory-management conditions do the MMU and virtual memory address?
-
Why does typing one command at a terminal require two different system calls?
-
How does root differ from an ordinary user — and how is it the same?
Khép lại chương Closing the chapter
Tiến trình người dùng làm nên môi trường bạn trực tiếp chạm vào; nhân quản lý tiến trình và phần cứng; và cả nhân lẫn tiến trình đều cư trú trong bộ nhớ. Nhưng bạn không thể học một hệ thống Linux chỉ bằng cách đọc về nó — bạn phải để tay mình lấm bẩn.1
Chương trình là thứ bạn chạm vào; nhân là người điều phối; và cả hai đều nằm trong bộ nhớ. Nhưng đọc thôi thì chưa đủ — phải tự tay làm thử. Nhớ nhé: đọc xong thì mở máy ra gõ thử.
User processes make up the environment you interact with directly; the kernel manages processes and hardware; and both the kernel and the processes reside in memory. But you can't learn a Linux system by reading about it alone — you need to get your hands dirty.1