Tổng kết module — Kernel & System Call
Cheat sheet dual mode + syscall + interrupt/trap, glossary, pitfall tổng hợp và self-assessment đối chiếu learning outcomes.
TL;DR: Module này bóc ranh giới nơi chương trình của bạn dừng lại và hệ điều hành bắt đầu. Bạn đã học CPU có hai chế độ đặc quyền (user/kernel) được phần cứng cưỡng chế; system call là cây cầu hợp pháp qua ranh giới, đi qua thanh ghi và bảng syscall với chi phí một mode switch; ba con đường vào kernel (interrupt bất đồng bộ, trap chủ động, exception do lỗi); và strace để nhìn tận mắt rồi chẩn đoán một chương trình. Đây là trang để bookmark.
Đã đi qua những gì
Module mở đầu bằng một sự thật mà code hàng ngày che giấu: chương trình của bạn không độc chiếm máy tính. Nó chạy ở user mode — một chế độ hạn chế mà CPU cưỡng chế bằng một mode bit trong phần cứng — và bị cấm chạm trực tiếp phần cứng. Thử chạy lệnh đặc quyền là bị SIGSEGV. Ranh giới này tồn tại vì ba lý do: bảo vệ (lỗi không lan), công bằng (timer interrupt cho kernel giành lại CPU), và an ninh.
Từ ranh giới đó, bạn học cây cầu bắc qua nó: system call. Bạn trace write() từ hàm glibc, qua việc nạp số hiệu vào rax và đối số vào rdi/rsi/rdx, tới lệnh syscall chuyển mode, vào điểm vào cố định, kernel tra bảng syscall tìm handler, chạy, rồi trả kết quả về rax. Bạn phân biệt được mode switch (đổi đặc quyền, cùng tiến trình — rẻ) với context switch (đổi hẳn tiến trình — đắt), và hiểu vì sao gom syscall lớn nhanh hơn nhiều syscall nhỏ.
Rồi bạn tổng quát hoá: syscall chỉ là một trong ba con đường vào kernel. Interrupt đến từ phần cứng, bất đồng bộ; trap (syscall) do chương trình chủ động; exception do chính lệnh gây lỗi. Điểm tinh tế: nhiều exception (page fault khi demand paging) là bình thường — kernel xử lý rồi chạy lại lệnh.
Cuối cùng, bạn cầm công cụ thật: strace ghi lại mọi syscall dựa trên ptrace. Bạn học đọc từng dòng, phân bốn nhóm (file/memory/process/network), dùng strace -c xếp hạng, và strace -p soi tiến trình treo. Mini-challenge cho bạn tự mổ xẻ cat và curl, thấy tận mắt "file I/O" khác "network" thế nào về hình dạng syscall.
flowchart LR ROOT["Kernel & System Call"] ROOT --> A["Hai che do"] ROOT --> B["System call"] ROOT --> C["Ba loi vao kernel"] ROOT --> D["strace"] A --> A1["User mode han che"] A --> A2["Kernel mode toan quyen"] A --> A3["Mode bit: ring 0 vs 3"] A --> A4["Lenh dac quyen bi chan bang fault"] B --> B1["glibc wrapper mong"] B --> B2["rax so hieu; rdi rsi rdx doi so"] B --> B3["Bang syscall tra ra handler"] B --> B4["Mode switch khac context switch"] B --> B5["Chi phi hang tram ns"] C --> C1["Interrupt: bat dong bo, phan cung"] C --> C2["Trap: chu dong (syscall)"] C --> C3["Exception: do lenh loi"] C --> C4["Page fault khong phai luon la loi"] D --> D1["Dua tren ptrace"] D --> D2["ten(doi_so) = ket_qua"] D --> D3["Phan nhom: file mem proc net"] D --> D4["strace -c xep hang"] D --> D5["strace -p soi treo"]
🗺️ Cheat sheet
| Khái niệm | Cốt lõi | Pitfall / ghi nhớ |
|---|---|---|
| User mode | Chế độ hạn chế cho code ứng dụng | Không chạm phần cứng; phải xin qua syscall |
| Kernel mode | Chế độ toàn quyền cho nhân OS | Ring 0 (x86), EL1 (ARM); khác với "root" |
| Mode bit | Bit trong CPU cho biết chế độ hiện tại | x86: CPL trong CS; phần cứng kiểm tra, không lách được |
| Lệnh đặc quyền | hlt, mov cr3, in/out, cli/sti | User chạy → #GP fault → SIGSEGV |
| System call | Cách hợp pháp nhờ kernel làm việc đặc quyền | glibc chỉ là wrapper; lệnh syscall mới vượt biên |
| Quy ước x86-64 | Số hiệu rax; đối số rdi rsi rdx r10 r8 r9; trả về rax | Trả về âm nhỏ = -errno |
| Bảng syscall | Mảng con trỏ handler; số hiệu = chỉ số | Một cửa vào cố định → an ninh |
| Mode switch | Đổi user↔kernel, cùng tiến trình | Rẻ (hàng trăm ns); mọi syscall đều là mode switch |
| Context switch | Đổi hẳn tiến trình + page table | Đắt hơn; xả TLB, cache nguội |
| Chi phí syscall | Cỡ hàng trăm ns; KPTI làm đắt hơn | Gom syscall lớn; buffer; vDSO tránh mode switch |
| Interrupt | Từ phần cứng, bất đồng bộ | Timer, bàn phím, mạng; qua IDT |
| Trap | Syscall — chủ động, đồng bộ | Về lệnh kế tiếp |
| Exception | Do lệnh gây lỗi, đồng bộ | Sửa được → chạy lại lệnh; không → signal |
| Page fault | Exception vector 14 | Không phải luôn lỗi: demand paging là bình thường |
| strace | Ghi mọi syscall qua ptrace | Phóng đại thời gian; không thấy tính toán user |
| strace -c | Bảng đếm calls/errors/time | Cột calls ≠ cột % time |
| strace -p PID | Soi tiến trình đang treo | Dòng cuối đứng im = chỗ chờ |
📖 Glossary module
| Thuật ngữ | Định nghĩa 1 câu |
|---|---|
| User mode | Chế độ đặc quyền hạn chế của CPU dành cho code ứng dụng, bị cấm chạm phần cứng trực tiếp |
| Kernel mode | Chế độ toàn quyền của CPU dành cho nhân hệ điều hành (ring 0 trên x86) |
| Mode bit | Bit trạng thái trong CPU cho biết đang chạy ở user hay kernel mode |
| CPL | Current Privilege Level — hai bit trong thanh ghi CS trên x86 biểu diễn ring hiện tại |
| Lệnh đặc quyền | Lệnh chỉ chạy hợp lệ ở kernel mode (dừng CPU, cấu hình MMU, I/O cổng) |
| System call | Giao diện để chương trình user nhờ kernel thực hiện một thao tác đặc quyền |
| Wrapper (glibc) | Hàm C mỏng bọc quanh một system call, lo phần nạp thanh ghi và xử lý lỗi |
| Bảng syscall | Mảng con trỏ hàm trong kernel, ánh xạ số hiệu syscall tới handler tương ứng |
| errno | Mã lỗi kernel trả về dưới dạng giá trị âm nhỏ (-errno), được glibc dịch ra |
| Mode switch | Cú chuyển giữa user và kernel mode trong cùng một tiến trình |
| Context switch | Cú chuyển thay hẳn tiến trình đang chạy bằng tiến trình khác, gồm đổi page table |
| Interrupt | Tín hiệu bất đồng bộ từ phần cứng bên ngoài, đưa CPU vào kernel |
| Trap | Cú vào kernel chủ động do chương trình phát ra (system call) |
| Exception | Cú vào kernel do chính lệnh đang chạy gây ra (lỗi hoặc sự kiện cần kernel) |
| IDT | Interrupt Descriptor Table — bảng ánh xạ vector interrupt/exception tới handler |
| Page fault | Exception khi truy cập địa chỉ ảo chưa được ánh xạ; có thể bình thường hoặc lỗi |
| vDSO | Vùng nhớ kernel ánh xạ vào tiến trình để phục vụ vài truy vấn ngay trong user mode |
| ptrace | System call cho một tiến trình theo dõi và chặn tiến trình khác (nền của strace, gdb) |
| strace | Công cụ ghi lại mọi system call của một chương trình kèm đối số và giá trị trả về |
| File descriptor | Số nguyên nhỏ kernel cấp để tham chiếu một file/socket/pipe đang mở |
⚠️ Pitfall tổng hợp
1. Nhầm "root" với "kernel mode":
SAI: Chay sudo -> chuong trinh vao kernel mode (ring 0)
DUNG: Root (uid 0) la danh tinh cua OS, van chay o user mode;
kernel mode (ring 0) la khai niem phan cung, chi code kernel moi vao
2. Tưởng system call luôn kéo theo context switch:
SAI: Moi syscall = doi tien trinh
DUNG: Moi syscall = mode switch (cung tien trinh); chi doi tien trinh
khi syscall phai CHO (read cho dia, futex cho lock)
3. Gọi nhiều syscall nhỏ thay vì gom lại:
// SAI: 1 trieu syscall, moi lan 1 byte -> 1 trieu mode switch
for (int i = 0; i < n; i++) write(fd, &buf[i], 1);
// DUNG: 1 syscall cho ca khoi
write(fd, buf, n);
4. Coi mọi ENOENT/= -1 trong strace là bug:
SAI: Thay openat(...) = -1 ENOENT -> bao loi
DUNG: Phan lon la search path binh thuong (tim lib/config/cert
qua nhieu duong dan); chi lo loi o cho khong nen co
5. Tin thời gian strace là tốc độ thật:
SAI: strace -c bao read ton 14ms -> chuong trinh cham vi read
DUNG: strace phong dai thoi gian (chan moi syscall 2 lan); dung
de so TI LE giua cac syscall, benchmark that thi chay KHONG strace
6. Tưởng page fault luôn là lỗi:
SAI: Page fault -> chuong trinh co bug
DUNG: Demand paging / copy-on-write la page fault BINH THUONG;
kernel xu ly roi chay lai lenh. Chi truy cap khong hop le moi -> SIGSEGV
✅ Self-assessment
Bạn đã đạt module này nếu trả lời được:
- Explain vì sao CPU có kernel mode và user mode, và ranh giới đó bảo vệ hệ thống thế nào — nêu được mode bit là gì, một ví dụ lệnh đặc quyền, và ba lý do (bảo vệ, công bằng, an ninh).
- Nếu chưa: đọc lại bài 01 — Kernel mode vs user mode mục 3–5.
- Trace đường đi một system call từ hàm thư viện qua kernel rồi quay về chương trình, kèm chi phí của mode switch — kể được số hiệu và đối số đi qua thanh ghi nào, ai tra bảng syscall, và vì sao mode switch khác context switch.
- Nếu chưa: đọc lại bài 02 — System call là gì mục 3–4.
- Compare interrupt, trap và exception — ba con đường đưa CPU vào kernel: phân biệt được theo nguồn và tính đồng bộ, và giải thích vì sao page fault không phải lúc nào cũng là lỗi.
- Nếu chưa: đọc lại bài 03 — Interrupt, trap & exception mục 3 và 5.
- Diagnose hành vi một chương trình bằng
strace: đọc, phân loại và giải thích syscall — dùng đượcstrace -c/strace -pđể tìm hot spot hoặc chỗ treo.- Nếu chưa: làm lại bài 05 — Mini-challenge đếm syscall và ôn bài 04.
🚀 What's next
Bạn vừa thấy ranh giới nơi chương trình gặp hệ điều hành. Nhưng "chương trình đang chạy" thật ra là gì đối với kernel? Câu trả lời là tiến trình (process) — và đó là module tiếp theo.
Module 2 — Tiến trình sẽ dùng nền tảng bạn vừa xây: fork/exec/wait (những syscall bạn giờ đã hiểu cơ chế) tạo và quản lý tiến trình thế nào, vòng đời từ sinh tới exit, hiện tượng zombie và orphan, và signal (những SIGSEGV/SIGKILL bạn đã gặp ở đây) hoạt động ra sao. Bạn sẽ tiếp tục dùng strace -f để nhìn tiến trình sinh con.
Tiếp theo: Module 2 — Tiến trình: tổng quan
Khám phá thêm: Tất cả khoá học
📚 Tài liệu mở rộng
- OSTEP — "Operating Systems: Three Easy Pieces" (Arpaci-Dusseau) — miễn phí tại https://pages.cs.wisc.edu/~remzi/OSTEP/ — chương 6 "Limited Direct Execution" (
cpu-mechanisms.pdf) là nguồn dễ đọc nhất cho toàn bộ module này: user/kernel mode, trap, interrupt, và vì sao thiết kế như vậy. - Linux man pages (man7.org) — syscall(2) cho quy ước thanh ghi, syscalls(2) cho danh sách đầy đủ, strace(1) và ptrace(2) cho công cụ, signal(7) cho các signal.
- "The Linux Programming Interface" (Michael Kerrisk) — chương 3 "System Programming Concepts" đào sâu system call, errno, và quy ước — cuốn tham khảo API Linux toàn diện nhất, cùng tác giả với man7.org.
- Brendan Gregg — "Systems Performance" — chương về công cụ quan sát (
strace,perf,bpftrace); đọc sau module này để lên cấp từstracesang các công cụ tracing hiện đại ít overhead hơn.
Bài này có giúp bạn hiểu bản chất không?
Hỏi đáp về bài này
Chưa có câu hỏi
Có gì chưa rõ trong bài? Đặt câu hỏi đầu tiên — câu trả lời từ cộng đồng giúp bạn (và người sau).
Đặt câu hỏi đầu tiên