Sự khác biệt giữa Chế độ người dùng và Chế độ hạt nhân là gì, tại sao và làm thế nào để bạn kích hoạt một trong hai chế độ này và các trường hợp sử dụng của chúng là gì?
Sự khác biệt giữa Chế độ người dùng và Chế độ hạt nhân là gì, tại sao và làm thế nào để bạn kích hoạt một trong hai chế độ này và các trường hợp sử dụng của chúng là gì?
Câu trả lời:
Chế độ hạt nhân
Ở chế độ Kernel, mã thực thi có quyền truy cập đầy đủ và không hạn chế vào phần cứng bên dưới. Nó có thể thực thi bất kỳ lệnh CPU nào và tham chiếu đến bất kỳ địa chỉ bộ nhớ nào. Chế độ hạt nhân thường được dành riêng cho các chức năng cấp thấp nhất, đáng tin cậy nhất của hệ điều hành. Sự cố trong chế độ hạt nhân là rất thảm khốc; chúng sẽ tạm dừng toàn bộ PC.
Chế độ người dùng
Trong chế độ Người dùng, mã thực thi không có khả năng truy cập trực tiếp vào phần cứng hoặc bộ nhớ tham chiếu. Mã chạy ở chế độ người dùng phải ủy quyền cho các API hệ thống để truy cập phần cứng hoặc bộ nhớ. Do sự bảo vệ được cung cấp bởi loại cách ly này, các sự cố trong chế độ người dùng luôn có thể khôi phục được. Hầu hết mã chạy trên máy tính của bạn sẽ thực thi ở chế độ người dùng.
Đọc thêm
Đây là hai chế độ khác nhau mà máy tính của bạn có thể hoạt động. Trước đây, khi máy tính giống như một căn phòng lớn, nếu một cái gì đó bị hỏng - nó sẽ tạm dừng toàn bộ máy tính. Vì vậy, các kiến trúc sư máy tính quyết định thay đổi nó. Các bộ vi xử lý hiện đại thực hiện trong phần cứng ít nhất 2 trạng thái khác nhau.
Chế độ người dùng:
Chế độ hạt nhân:
Cách chuyển đổi xảy ra.
Việc chuyển từ chế độ người dùng sang chế độ hạt nhân không được thực hiện tự động bởi CPU. CPU bị ngắt bởi các ngắt (bộ định thời, bàn phím, I / O). Khi xảy ra ngắt, CPU ngừng thực hiện chương trình đang chạy hiện tại, chuyển sang chế độ hạt nhân, thực hiện xử lý ngắt. Trình xử lý này lưu trạng thái của CPU, thực hiện các hoạt động của nó, khôi phục trạng thái và trở về chế độ người dùng.
http://en.wikibooks.org/wiki/Windows_Programming/User_Mode_vs_Kernel_Mode
http://tldp.org/HOWTO/KernelAnalysis-HOWTO-3.html
Bộ xử lý trong máy tính chạy Windows có hai chế độ khác nhau: chế độ người dùng và chế độ hạt nhân. Bộ xử lý chuyển đổi giữa hai chế độ tùy thuộc vào loại mã nào đang chạy trên bộ xử lý. Các ứng dụng chạy ở chế độ người dùng và các thành phần hệ điều hành cốt lõi chạy ở chế độ hạt nhân. Trong khi nhiều trình điều khiển chạy ở chế độ hạt nhân, một số trình điều khiển có thể chạy ở chế độ người dùng.
Khi bạn khởi động một ứng dụng ở chế độ người dùng, Windows sẽ tạo một quy trình cho ứng dụng. Quá trình này cung cấp cho ứng dụng một không gian địa chỉ ảo riêng và một bảng xử lý riêng. Vì không gian địa chỉ ảo của ứng dụng là riêng tư nên một ứng dụng không thể thay đổi dữ liệu thuộc về ứng dụng khác. Mỗi ứng dụng chạy riêng lẻ và nếu một ứng dụng gặp sự cố, sự cố chỉ giới hạn ở một ứng dụng đó. Các ứng dụng khác và hệ điều hành không bị ảnh hưởng bởi sự cố.
Ngoài việc riêng tư, không gian địa chỉ ảo của ứng dụng chế độ người dùng bị hạn chế. Bộ xử lý đang chạy ở chế độ người dùng không thể truy cập các địa chỉ ảo được dành riêng cho hệ điều hành. Việc giới hạn không gian địa chỉ ảo của ứng dụng ở chế độ người dùng sẽ ngăn ứng dụng thay đổi và có thể làm hỏng dữ liệu hệ điều hành quan trọng.
Tất cả mã chạy trong chế độ hạt nhân đều chia sẻ một không gian địa chỉ ảo duy nhất. Điều này có nghĩa là trình điều khiển chế độ hạt nhân không bị cô lập với các trình điều khiển khác và chính hệ điều hành. Nếu trình điều khiển chế độ hạt nhân vô tình ghi nhầm địa chỉ ảo, dữ liệu thuộc hệ điều hành hoặc trình điều khiển khác có thể bị xâm phạm. Nếu trình điều khiển chế độ hạt nhân gặp sự cố, toàn bộ hệ điều hành sẽ bị treo.
Nếu bạn là người dùng Windows, một khi truy cập vào liên kết này, bạn sẽ nhận được nhiều hơn thế.
Vòng CPU là điểm phân biệt rõ ràng nhất
Trong chế độ bảo vệ x86, CPU luôn ở một trong 4 vòng. Nhân Linux chỉ sử dụng 0 và 3:
Đây là định nghĩa khó và nhanh nhất về kernel và userland.
Tại sao Linux không sử dụng vòng 1 và 2: Vòng đặc quyền CPU: Tại sao vòng 1 và 2 không được sử dụng?
Vòng hiện tại được xác định như thế nào?
Vòng hiện tại được chọn bằng sự kết hợp của:
bảng mô tả toàn cục: một bảng trong bộ nhớ của các mục nhập GDT và mỗi mục nhập có một trường Privl
mã hóa vòng.
Lệnh LGDT đặt địa chỉ cho bảng bộ mô tả hiện tại.
phân đoạn đăng ký CS, DS, v.v., trỏ đến chỉ mục của mục nhập trong GDT.
Ví dụ: CS = 0
có nghĩa là mục nhập đầu tiên của GDT hiện đang hoạt động cho mã thực thi.
Mỗi chiếc nhẫn có thể làm gì?
Chip CPU được xây dựng vật lý để:
chuông 0 có thể làm bất cứ điều gì
ring 3 không thể chạy một số hướng dẫn và ghi vào một số thanh ghi, đáng chú ý nhất là:
không thể thay đổi vòng riêng của nó! Nếu không, nó có thể tự đặt thành chuông 0 và đổ chuông sẽ vô dụng.
Nói cách khác, không thể sửa đổi bộ mô tả phân đoạn hiện tại, bộ mô tả phân đoạn xác định vòng hiện tại.
không thể sửa đổi các bảng trang: Phân trang x86 hoạt động như thế nào?
Nói cách khác, không thể sửa đổi thanh ghi CR3 và chính việc phân trang ngăn cản việc sửa đổi các bảng trang.
Điều này ngăn một quá trình nhìn thấy bộ nhớ của các quá trình khác vì lý do bảo mật / dễ lập trình.
không thể đăng ký trình xử lý ngắt. Chúng được cấu hình bằng cách ghi vào các vị trí bộ nhớ, điều này cũng bị ngăn chặn bởi phân trang.
Các trình xử lý chạy trong vòng 0 và sẽ phá vỡ mô hình bảo mật.
Nói cách khác, không thể sử dụng hướng dẫn LGDT và LIDT.
không thể thực hiện các hướng dẫn IO như in
và out
, do đó có quyền truy cập phần cứng tùy ý.
Nếu không, ví dụ, quyền đối với tệp sẽ vô dụng nếu bất kỳ chương trình nào có thể đọc trực tiếp từ đĩa.
Chính xác hơn là nhờ Michael Petch : hệ điều hành thực sự có thể cho phép các lệnh IO trên vòng 3, điều này thực sự được kiểm soát bởi phân đoạn trạng thái Nhiệm vụ .
Điều không thể xảy ra là vòng 3 tự cho phép mình làm như vậy nếu ngay từ đầu nó đã không có nó.
Linux luôn không cho phép nó. Xem thêm: Tại sao Linux không sử dụng chuyển đổi ngữ cảnh phần cứng qua TSS?
Làm thế nào để các chương trình và hệ điều hành chuyển đổi giữa các vòng?
khi CPU được bật, nó bắt đầu chạy chương trình ban đầu ở vòng 0 (loại tốt, nhưng nó là một con số gần đúng). Bạn có thể nghĩ chương trình ban đầu này là hạt nhân (nhưng nó thường là một bộ nạp khởi động sau đó gọi hạt nhân vẫn ở trong vòng 0 ).
khi một tiến trình vùng người dùng muốn hạt nhân làm một việc gì đó cho nó như ghi vào tệp, nó sử dụng một lệnh tạo ra một ngắt chẳng hạn như int 0x80
hoặcsyscall
để báo hiệu cho hạt nhân. x86-64 Linux syscall ví dụ hello world:
.data
hello_world:
.ascii "hello world\n"
hello_world_len = . - hello_world
.text
.global _start
_start:
/* write */
mov $1, %rax
mov $1, %rdi
mov $hello_world, %rsi
mov $hello_world_len, %rdx
syscall
/* exit */
mov $60, %rax
mov $0, %rdi
syscall
biên dịch và chạy:
as -o hello_world.o hello_world.S
ld -o hello_world.out hello_world.o
./hello_world.out
Khi điều này xảy ra, CPU sẽ gọi một trình xử lý gọi lại ngắt mà hạt nhân đã đăng ký tại thời điểm khởi động. Đây là một ví dụ cụ thể về baremetal đăng ký một trình xử lý và sử dụng nó .
Trình xử lý này chạy trong vòng 0, nó quyết định xem hạt nhân có cho phép hành động này hay không, thực hiện hành động và khởi động lại chương trình userland trong vòng 3. x86_64
khi lệnh exec
gọi hệ thống được sử dụng (hoặc khi hạt nhân sẽ bắt đầu/init
), hạt nhân chuẩn bị các thanh ghi và bộ nhớ của tiến trình vùng người dùng mới, sau đó nó nhảy đến điểm nhập và chuyển CPU sang vòng 3
Nếu chương trình cố gắng làm điều gì đó nghịch ngợm như ghi vào một thanh ghi bị cấm hoặc địa chỉ bộ nhớ (do phân trang), CPU cũng gọi một số trình xử lý gọi lại hạt nhân trong vòng 0.
Nhưng vì vùng người dùng là không đúng, nên lần này hạt nhân có thể giết quá trình hoặc đưa ra cảnh báo bằng tín hiệu.
Khi hạt nhân khởi động, nó thiết lập đồng hồ phần cứng với một số tần số cố định, điều này tạo ra các ngắt định kỳ.
Đồng hồ phần cứng này tạo ra các ngắt chạy chuông 0 và cho phép nó lên lịch đánh thức các quá trình vùng người dùng nào.
Bằng cách này, việc lập lịch có thể xảy ra ngay cả khi các tiến trình không thực hiện bất kỳ lệnh gọi hệ thống nào.
Có ích gì khi có nhiều vòng?
Có hai ưu điểm chính của việc tách kernel và userland:
Làm thế nào để chơi xung quanh nó?
Tôi đã tạo một thiết lập kim loại trần nên là một cách tốt để thao tác trực tiếp với nhẫn: https://github.com/cirosantilli/x86-bare-metal-examples
Thật không may, tôi không có đủ kiên nhẫn để tạo một ví dụ về vùng người dùng, nhưng tôi đã đi xa hơn khi thiết lập phân trang, vì vậy vùng người dùng sẽ khả thi. Tôi muốn thấy một yêu cầu kéo.
Ngoài ra, các mô-đun nhân Linux chạy ở vòng 0, vì vậy bạn có thể sử dụng chúng để thử các hoạt động đặc quyền, ví dụ như đọc các thanh ghi điều khiển: Làm thế nào để truy cập các thanh ghi điều khiển cr0, cr2, cr3 từ một chương trình? Nhận lỗi phân đoạn
Đây là một thiết lập QEMU + Buildroot thuận tiện để dùng thử mà không giết máy chủ của bạn.
Nhược điểm của mô-đun nhân là các kthreads khác đang chạy và có thể gây trở ngại cho các thử nghiệm của bạn. Nhưng về lý thuyết, bạn có thể tiếp quản tất cả các trình xử lý ngắt với mô-đun hạt nhân của mình và sở hữu hệ thống, đó thực sự sẽ là một dự án thú vị.
Vòng âm
Mặc dù các vòng âm không thực sự được tham chiếu trong sách hướng dẫn của Intel, nhưng thực sự có các chế độ CPU có nhiều khả năng hơn chính vòng 0, và do đó, rất phù hợp với tên "vòng âm".
Một ví dụ là chế độ siêu giám sát được sử dụng trong ảo hóa.
Để biết thêm chi tiết xem:
CÁNH TAY
Trong ARM, các vòng được gọi là Mức ngoại lệ, nhưng các ý tưởng chính vẫn được giữ nguyên.
Có 4 mức ngoại lệ trong ARMv8, thường được sử dụng như:
EL0: userland
EL1: kernel ("người giám sát" trong thuật ngữ ARM).
Được nhập bằng svc
lệnh (SuperVisor Call), trước đây được gọi là swi
trước khi hợp nhất hợp nhất , là lệnh được sử dụng để thực hiện các lệnh gọi hệ thống Linux. Ví dụ về Hello world ARMv8:
xin chào.S
.text
.global _start
_start:
/* write */
mov x0, 1
ldr x1, =msg
ldr x2, =len
mov x8, 64
svc 0
/* exit */
mov x0, 0
mov x8, 93
svc 0
msg:
.ascii "hello syscall v8\n"
len = . - msg
Kiểm tra nó với QEMU trên Ubuntu 16.04:
sudo apt-get install qemu-user gcc-arm-linux-gnueabihf
arm-linux-gnueabihf-as -o hello.o hello.S
arm-linux-gnueabihf-ld -o hello hello.o
qemu-arm hello
Đây là một ví dụ cụ thể baremetal đăng ký một trình xử lý SVC và thực hiện một cuộc gọi SVC .
EL2: siêu giám sát , ví dụ Xen .
Được nhập bằng hvc
lệnh (HyperVisor Call).
Một siêu giám sát là một hệ điều hành, một hệ điều hành là gì đối với vùng đất người dùng.
Ví dụ: Xen cho phép bạn chạy nhiều hệ điều hành như Linux hoặc Windows trên cùng một hệ thống cùng một lúc và nó cách ly các hệ điều hành với nhau để bảo mật và dễ gỡ lỗi, giống như Linux làm cho các chương trình vùng đất.
Người giám sát là một phần quan trọng của cơ sở hạ tầng đám mây ngày nay: chúng cho phép nhiều máy chủ chạy trên một phần cứng duy nhất, giữ cho mức sử dụng phần cứng luôn ở mức gần 100% và tiết kiệm rất nhiều tiền.
Ví dụ, AWS đã sử dụng Xen cho đến năm 2017 khi việc chuyển sang KVM được đưa tin .
EL3: một cấp độ khác. Ví dụ TODO.
Được nhập bằng smc
hướng dẫn (Cuộc gọi Chế độ Bảo mật)
Các ARMv8 Kiến trúc mô hình tham chiếu DDI 0487C.a - Chương D1 - Mô hình Hệ thống AArch64 Cấp Programmer của - Hình D1-1 minh họa này đẹp:
Tình hình của ARM đã thay đổi một chút với sự ra đời của Tiện ích mở rộng máy chủ ảo hóa ARMv8.1 (VHE) . Phần mở rộng này cho phép hạt nhân chạy trong EL2 một cách hiệu quả:
VHE được tạo ra vì các giải pháp ảo hóa trong nhân Linux như KVM đã chiếm được ưu thế hơn Xen (xem ví dụ: AWS 'chuyển sang KVM được đề cập ở trên), bởi vì hầu hết các máy khách chỉ cần máy ảo Linux và như bạn có thể tưởng tượng, tất cả đều nằm trong một dự án, KVM đơn giản hơn và có khả năng hiệu quả hơn Xen. Vì vậy, bây giờ nhân Linux máy chủ đóng vai trò là siêu giám sát trong những trường hợp đó.
Lưu ý rằng ARM, có thể do lợi ích của nhận thức muộn, có quy ước đặt tên tốt hơn cho các mức đặc quyền so với x86, mà không cần mức âm: 0 là thấp hơn và 3 cao nhất. Các cấp cao hơn có xu hướng được tạo ra thường xuyên hơn các cấp thấp hơn.
EL hiện tại có thể được truy vấn bằng MRS
lệnh: chế độ thực thi hiện tại / mức ngoại lệ là gì, v.v.?
ARM không yêu cầu tất cả các mức ngoại lệ phải có mặt để cho phép triển khai không cần tính năng tiết kiệm diện tích chip. ARMv8 "Mức ngoại lệ" cho biết:
Việc triển khai có thể không bao gồm tất cả các mức Ngoại lệ. Tất cả các triển khai phải bao gồm EL0 và EL1. EL2 và EL3 là tùy chọn.
QEMU ví dụ: mặc định là EL1, nhưng EL2 và EL3 có thể được kích hoạt với các tùy chọn dòng lệnh: qemu-system-aarch64 nhập el1 khi mô phỏng a53 bật nguồn
Đoạn mã được thử nghiệm trên Ubuntu 18.10.
in
và out
có sẵn cho chuông 3. TSS có thể trỏ đến bảng quyền IO trong tác vụ hiện tại cấp quyền truy cập đọc / ghi cho tất cả hoặc các cổng cụ thể.
Tôi sẽ đi sâu vào bóng tối và đoán bạn đang nói về Windows. Tóm lại, chế độ hạt nhân có toàn quyền truy cập vào phần cứng, nhưng chế độ người dùng thì không. Ví dụ, nhiều nếu không phải hầu hết các trình điều khiển thiết bị được viết ở chế độ hạt nhân vì chúng cần kiểm soát các chi tiết tốt hơn về phần cứng của chúng.
Xem thêm wikibook này .
Các câu trả lời khác đã giải thích sự khác biệt giữa chế độ người dùng và hạt nhân. Nếu bạn thực sự muốn tìm hiểu chi tiết, bạn nên lấy một bản sao của Windows Internals , một cuốn sách xuất sắc được viết bởi Mark Russinovich và David Solomon mô tả kiến trúc và chi tiết bên trong của các hệ điều hành Windows khác nhau.
Gì
Về cơ bản, sự khác biệt giữa chế độ hạt nhân và chế độ người dùng không phụ thuộc vào hệ điều hành và chỉ đạt được bằng cách hạn chế một số lệnh chỉ được chạy trong chế độ hạt nhân thông qua thiết kế phần cứng. Tất cả các mục đích khác như bảo vệ bộ nhớ chỉ có thể được thực hiện bởi hạn chế đó.
Làm sao
Nó có nghĩa là bộ xử lý sống ở chế độ hạt nhân hoặc chế độ người dùng. Sử dụng một số cơ chế, kiến trúc có thể đảm bảo rằng bất cứ khi nào nó được chuyển sang chế độ hạt nhân, mã hệ điều hành được tìm nạp để chạy.
Tại sao
Có cơ sở hạ tầng phần cứng này, những điều này có thể đạt được trong các hệ điều hành phổ biến: