- Microkernel, từng kém thực tế vì overhead cao trong quá khứ, nay có thể trở lại thành một lựa chọn khả thi nhờ IOMMU và bộ nhớ chia sẻ đã trở nên phổ biến
- Việc cô lập driver và subsystem trong không gian người dùng có thể giới hạn phạm vi ảnh hưởng của lỗi hoặc tấn công, qua đó nâng cao bảo mật, độ tin cậy và tính mô-đun
- Trong thập niên 1980–1990, các tiến trình không gian người dùng không thể truy cập trực tiếp thiết bị, nên mỗi thao tác như đọc đĩa đều kéo theo system call và chuyển đổi ngữ cảnh, khóa và sao chép bộ nhớ
- Bằng cách tận dụng IOMMU và hàng đợi lệnh dùng chung, có thể xử lý IPC bất đồng bộ và truy cập thiết bị trên đường xử lý bình thường mà không cần chuyển đổi ngữ cảnh, sao chép giữa các không gian địa chỉ hay khóa
- Có thể tận dụng các thành phần sẵn có như Xen, FreeBSD, Linux DRM, nên gánh nặng phải xây dựng hypervisor và server hệ thống từ đầu cũng không quá lớn
Cấu trúc của microkernel và hiệu quả cô lập
- Microkernel là kiến trúc kernel trong đó các chức năng ngoài lập lịch, quản lý truy cập thiết bị I/O và giao tiếp liên tiến trình (IPC) được chạy trong không gian người dùng
- Cô lập subsystem mang lại ba lợi ích
- Bảo mật: lỗ hổng trong một driver chỉ có thể cấp cho kẻ tấn công quyền truy cập của subsystem hoặc driver đó, thay vì toàn bộ hệ thống
- Độ tin cậy: sự cố của một subsystem chỉ ảnh hưởng đến phần đó, không phải toàn bộ hệ thống
- Tính mô-đun: giảm gánh nặng cho đội ngũ kernel Linux trong việc phải hợp nhất mọi driver phần cứng và xem xét cả hoạt động nội bộ của từng chip
- Nếu Windows là một hệ thống microkernel, lỗi CrowdStrike có lẽ chỉ làm gián đoạn việc thu thập dữ liệu telemetry của một số phụ trách viên bảo mật CNTT
Giới hạn hiệu năng trong quá khứ và cách IOMMU giải quyết
- Trong các microkernel trước đây, tiến trình không gian người dùng không thể truy cập trực tiếp thiết bị cụ thể, nên mỗi tác vụ đều cần system call và chuyển đổi ngữ cảnh, kèm theo khóa tốn kém và sao chép bộ nhớ
- Mach vì vấn đề hiệu năng đã dần chuyển các tiến trình không gian người dùng vào trong kernel, và cuối cùng trở nên gần với kernel nguyên khối thông thường
- Ngày nay, PC đã được trang bị IOMMU như tiêu chuẩn trong khoảng 10 năm, và khi dùng cùng bộ nhớ chia sẻ, có thể loại bỏ hoàn toàn chuyển đổi ngữ cảnh trên đường xử lý bình thường khi có đủ core
- Nếu chấp nhận một chút độ trễ, nhìn chung cũng có thể gần như loại bỏ chuyển đổi ngữ cảnh
- Scheduler dựa trên công nghệ ảo hóa có thể được cấu hình theo hình thức tương tự hypervisor Xen
- Truy cập thiết bị I/O do phần cứng IOMMU quản lý
- IPC có thể được triển khai bằng cách cấp phát buffer chia sẻ giữa các tiến trình và cung cấp phép compare-and-swap nguyên tử trên số nguyên
- Dùng buffer chia sẻ như hàng đợi lệnh dạng ring buffer và cập nhật nguyên tử con trỏ đầu/cuối
- Trên đường xử lý bình thường, có thể truyền thông điệp bất đồng bộ mà không cần chuyển đổi ngữ cảnh, sao chép giữa các không gian địa chỉ hay khóa; đây cũng là cách được dùng rộng rãi trong driver GPU
Cấu hình thư viện và tận dụng mã hiện có
- Trong môi trường tiến trình là VM guest, có thể liên kết thư viện chia sẻ khi chương trình khởi động, còn các chức năng không cần chạy ở tiến trình khác có thể xử lý cục bộ theo cách của exokernel
- Trong thời nay, khi mỗi ứng dụng kiểu Electron phân phối kèm các thành phần hệ điều hành riêng, thư viện trùng lặp trong bộ nhớ không còn là vấn đề lớn như 30 năm trước
- Các nền tảng chính cần cho việc triển khai cũng đã tồn tại
- Xen đã có hầu hết chức năng cần thiết cho tầng hypervisor
- Có thể cấu hình server mạng và filesystem như Mach, nhưng dùng mã của FreeBSD
- DRM vốn đã dựa trên command buffer bất đồng bộ, nên có thể chạy subsystem đồ họa Linux trong không gian người dùng
- Vì tiện lợi, cũng có thể cấu hình để display server và subsystem đồ họa chạy trong cùng một tiến trình
1 bình luận
Các ý kiến trên Lobste.rs
Lý do Linux bao gồm mọi driver là vì không có API ổn định cho kernel module ngoài cây, và microkernel không phải là điều kiện bắt buộc để cung cấp một API như vậy
Tôi nhớ từng thấy phàn nàn trên LKML rằng ngay cả nếu giả định chuyển toàn bộ driver Linux sang user space, việc thay đổi API nội bộ cũng sẽ trở nên khó khăn
Có lẽ các kernel họ L4 vốn nổi tiếng là nhanh. Tôi cũng tò mò Redox OS hay Fuchsia thì ra sao
Genode hỗ trợ nhiều kernel, nhưng trên seL4 và một số kernel khác thì hiệu năng tệ đến mức buồn cười. Khi đồng nghiệp thử boot một Linux VM, nó chỉ hỗ trợ 32-bit, và để boot được chừng một nửa cũng mất vài phút
Bản fork Genode của NOVA microhypervisor là nền tảng mặc định vì trên thực tế nó chạy được và hiệu năng cũng đủ tốt
Vì dùng circular buffer, nếu bên nhận đã đang chạy trên core khác thì có thể không cần lần chuyển ngữ cảnh thứ hai. Nếu diễn giải message mà không chuyển ngữ cảnh, bên nhận phải tự kiểm chứng message, khiến bề mặt tấn công có thể trở nên quá lớn, nhưng có vẻ có thể giảm nhẹ bằng dynamic library do kernel cung cấp
Tôi không phải chuyên gia, nhưng có cảm giác bài gốc đã bỏ sót vài điểm cân nhắc quan trọng
QNX được biết đến là một microkernel nhanh, nên tôi tò mò họ đã làm đúng điều gì
Trước đây, tôi và một người bạn bị cuốn hút bởi sự tao nhã của microkernel, đặc biệt là QNX, nên đã triển khai một bài toán xử lý video dựa trên FireWire. Code đơn giản và đẹp, nhưng chậm thảm hại. Khi đó, việc thêm hỗ trợ truyền đẳng thời dựa trên DMA vào driver 1394 cho Linux chỉ mất khoảng 12 giờ và hiệu năng cải thiện rõ rệt; nhờ việc này, sự hoài nghi về việc dùng Linux cho thiết bị phân loại quang học của công ty cũng biến mất
Lý tưởng của QNX, microkernel và message passing vẫn rất tuyệt, nhưng để được dùng rộng rãi, chi phí truyền dữ liệu giữa các process phải giảm đi rất nhiều
Giờ tôi đang làm ứng dụng web bằng Elixir và hưởng lợi từ kiểu cô lập process giống như QNX quảng bá. Vì không phải tác vụ đòi hỏi hiệu năng như xử lý quang học nên vẫn ổn, nhưng Elixir/BEAM cũng có cùng vấn đề sao chép dữ liệu
Dù Mach không thể làm cho các thành phần độc lập hoàn toàn như ý tưởng ban đầu, tôi nghe nói nó cũng không trở thành một kernel đơn khối bình thường, và kiến trúc đó vẫn mang lại lợi ích
Nếu gọi
readdir()vàstat()cho mọi mục như trong benchmark liệt kê file POSIX cổ điển, microkernel chắc chắn bất lợi. Nhưng nếu dùng API xử lý theo lô nhưio_uringđể giảm tần suất system call, độ trễ cao có thể không còn là điểm yếu lớnLinux cũng không thể theo kịp tốc độ đường truyền nếu mỗi gói mạng lại thực hiện một system call. Xử lý theo lô quan trọng với cả Linux lẫn microkernel
Một gương mặt mới thú vị trong lĩnh vực này là HongMeng, nhưng đáng tiếc đó là phần mềm độc quyền
Trừ khi chi phí di chuyển dữ liệu giảm mạnh hơn một bậc độ lớn, có vẻ microkernel khó có đủ sức cạnh tranh
Về lý thuyết thì thanh lịch và gọn gàng, nhưng thực tế phức tạp, nên để xử lý sự phức tạp đó, có lẽ kernel cũng phải phức tạp ở một mức nào đó
Tôi thích kiến trúc đúng đắn, nhưng cho rằng việc Linux vươn lên vị thế thống trị cũng nhờ nhiều yếu tố phụ trợ ngoài kỹ thuật thuần túy. Tôi muốn đọc một bài phân tích điều đó trên nhiều khía cạnh