2011-11-25 27 views
11

Bất cứ ai có thể giải thích cho tôi chính xác chức năng copy_from_user hoạt động như thế nào? Nó có sử dụng bất kỳ bộ đệm nào hay không có bất kỳ ánh xạ bộ nhớ nào được thực hiện vì thực tế là hạt nhân có đặc quyền truy cập vào bộ nhớ không gian người dùng.Copy_from_user từ nhân Linux hoạt động như thế nào?

Trả lời

15

Việc triển khai copy_from_user() phụ thuộc nhiều vào kiến ​​trúc.

Trên x86 và x86-64, nó chỉ đọc trực tiếp từ địa chỉ không gian người dùng và ghi vào địa chỉ kernelspace, trong khi tạm thời tắt SMAP (Chế độ giám sát truy cập) nếu nó được cấu hình. Phần khó khăn của nó là mã copy_from_user() được đặt vào một vùng đặc biệt để trình xử lý lỗi trang có thể nhận ra khi có lỗi xảy ra trong đó. Một lỗi bảo vệ bộ nhớ xảy ra trong copy_from_user() không giết chết quá trình giống như nó được kích hoạt bởi bất kỳ mã ngữ cảnh quy trình nào khác, hoặc làm hoảng sợ hạt nhân như nó xảy ra trong ngữ cảnh ngắt - nó đơn giản tiếp tục thực hiện trong một mã đường dẫn trả về -EFAULT cho người gọi.

+0

Cảm ơn bạn, tôi đã chắc chắn truy cập trực tiếp bởi hạt nhân, vì vậy về cơ bản tôi đoán nó thực hiện kiểm tra trước trên con trỏ/địa chỉ được truyền vào nó để kiểm tra xem một số địa chỉ không hợp lệ không được chuyển vào hàm i không có nghĩa là để nói địa chỉ thuộc về một số quá trình không gian người dùng khác ... dù sao tôi không biết bout điều bảo vệ bộ nhớ mà bạn đã đề cập .... Vì vậy, DOubt của tôi là wht bout trong trường hợp của copy_to_user ... kể từ khi không gian người dùng được thông qua một địa chỉ trong không gian hạt nhân VM .... làm thế nào để không gian người dùng acccess it..or là nó mà bản đồ hạt nhân địa chỉ để một số địa chỉ không gian người dùng – Santi1986

+3

@ Santi1986: 'copy_to_user()' hoạt động trong cùng một chính xác cách, ngoại trừ các địa chỉ nguồn và đích được hoán đổi - nó đọc từ các địa chỉ hạt nhân và ghi vào các địa chỉ không gian người dùng. Việc kiểm tra duy nhất được thực hiện trong cả hai là địa chỉ không gian người dùng thực sự * là * dưới sự phân chia hạt nhân/người dùng; không cần kiểm tra các địa chỉ thuộc về các tiến trình người dùng khác, vì 'copy _ * _ user()' chỉ được gọi trong ngữ cảnh tiến trình, có nghĩa là * tất cả * địa chỉ là địa chỉ hạt nhân hoặc thuộc về tiến trình hiện tại. – caf

+0

Cảm ơn bạn đã dành thời gian duyệt qua mã và tìm ra hạt nhân này kiểm tra tính hợp lệ của con trỏ thông qua access_ok), về cơ bản hàm __copy _ * _ người dùng được gọi là nội hàm sử dụng hàm __copy _ * _ user_inatomic này, cuối cùng gọi __copy __ * _ user_ll, không sao chép actuall và cũng là PAGES ĐƯỢC PINI PRIOR COPYING .... nếu toàn bộ dữ liệu không được sao chép đệm của nó với số không (bởi len thông qua để gọi) – Santi1986

1

Việc thực hiện lệnh gọi hệ thống copy_from_user() được thực hiện bằng cách sử dụng hai bộ đệm từ các không gian địa chỉ khác nhau.

  • vùng đệm người dùng trong địa chỉ ảo của người dùng.
  • bộ đệm không gian hạt nhân tại địa chỉ ảo hạt nhân.

Khi cuộc gọi hệ thống gọi là copy_from_user() được sao chép từ bộ đệm người dùng sang bộ đệm hạt nhân.

Một phần (ghi hoạt động) của nhân vật mã trình điều khiển thiết bị nơi copy_from_user() được sử dụng được đưa ra dưới đây:

ssize_t cdev_fops_write (struct tập tin * lật, const char __user * ubuf, size_t count, loff_t * f_pos)

{

unsigned int *kbuf; 

copy_from_user(kbuf, ubuf, count); 

printk(KERN_INFO "Data: %d",*kbuf); 

}

+0

ok nghi ngờ của tôi với bạn câu trả lời là tốt của nó cho copy_from_user. .how bout copy_to_user kể từ khi hạt nhân đi qua địa chỉ không gian hạt nhân, làm thế nào có thể một người sử dụng không gian quá trình truy cập nó .. hạt nhân làm một mappin trước vào VM không gian người dùng để người dùng có thể truy cập nó từ đó – Santi1986

7

liên quan đến "cách copy_to_user bout kể từ khi hạt nhân chuyển qua địa chỉ không gian hạt nhân, cách quy trình không gian người dùng truy cập vào nó"

Quy trình không gian người dùng có thể tìm cách truy cập vào bất kỳ địa chỉ nào. Tuy nhiên, nếu địa chỉ không được ánh xạ trong không gian người dùng của quá trình đó (tức là trong các bảng trang của quy trình đó) hoặc nếu có sự cố với quyền truy cập như nỗ lực ghi vào vị trí chỉ đọc thì lỗi trang được tạo. Lưu ý rằng ít nhất là trên x86, mọi tiến trình đều có không gian hạt nhân được ánh xạ trong không gian địa chỉ ảo thấp nhất 1 gigabyte, trong khi 3 gigabyte trên không gian địa chỉ 4GB (tôi đang sử dụng ở đây là 32-bit classic trường hợp) được sử dụng cho văn bản quy trình (tức là mã) và dữ liệu. Một bản sao đến hoặc từ không gian người dùng được thực thi bằng mã hạt nhân đang thực thi thay mặt cho quá trình và thực sự đó là ánh xạ bộ nhớ (tức là các bảng trang) của quá trình đang được sử dụng trong bản sao. Điều này diễn ra trong khi thực thi ở chế độ hạt nhân - tức là chế độ đặc quyền/giám sát trong ngôn ngữ x86. Giả sử mã không gian người dùng đã vượt qua một vị trí mục tiêu hợp pháp (tức làđịa chỉ được ánh xạ chính xác trong không gian địa chỉ tiến trình) để sao chép dữ liệu vào, copy_to_user, chạy từ ngữ cảnh hạt nhân sẽ có thể ghi vào địa chỉ/vùng đó và sau khi điều khiển trả về cho người dùng, không gian người dùng cũng có thể đọc từ thiết lập vị trí này bằng chính quy trình để bắt đầu. Các chi tiết thú vị khác có thể tìm thấy trong chương 9 và 10 của Hiểu nhân Linux, Phiên bản thứ 3, Tác giả Daniel P. Bovet, Marco Cesati. Đặc biệt, access_ok() là một kiểm tra tính hợp lệ cần thiết nhưng không đủ. Người dùng vẫn có thể truyền địa chỉ không thuộc về không gian địa chỉ tiến trình. Trong trường hợp này, một ngoại lệ lỗi trang sẽ xảy ra trong khi mã hạt nhân đang thực thi bản sao. Phần thú vị nhất là cách trình xử lý lỗi trang hạt nhân xác định rằng lỗi trang trong trường hợp này không phải do lỗi trong mã hạt nhân mà là địa chỉ không hợp lệ của người dùng (đặc biệt nếu mã hạt nhân được đề cập đến từ mô-đun hạt nhân nạp vào).

1

Câu trả lời tốt nhất có điều gì sai, copy_ (từ | đến) dùng không thể được sử dụng trong bối cảnh gián đoạn, họ có thể ngủ, sao chép (từ | đến) chức năng sử dụng chỉ có thể được sử dụng trong bối cảnh quá trình, bảng trang của quy trình bao gồm tất cả thông tin mà hạt nhân cần truy cập, vì vậy hạt nhân có thể truy cập trực tiếp vào địa chỉ không gian người dùng nếu chúng tôi có thể đảm bảo rằng địa chỉ trang đó nằm trong bộ nhớ, sử dụng hàm (từ | to) _user có thể kiểm tra nó cho chúng tôi và nếu không gian người dùng địa chỉ trang không phải là cư dân, nó sẽ sửa chữa nó cho chúng tôi trực tiếp.

Các vấn đề liên quan