Bộ nhớ cao và bộ nhớ thấp trên Linux là gì?


92

Tôi quan tâm đến sự khác biệt giữa Highmem và Lowmem:

  1. Tại sao có sự khác biệt như vậy?
  2. Chúng ta đạt được gì khi làm như vậy?
  3. Mỗi tính năng có những tính năng gì?

@hiro, ý bạn là "HIGHMEM" là "địa chỉ ảo kernel" như được mô tả bởi ldd3. Tôi đồng ý với bạn. thật khó hiểu, ldd3 đã định nghĩa "LOWMEM" "HIGHMEM", cũng được định nghĩa "địa chỉ ảo kernel" "địa chỉ logic kernel". chúng là cùng một thứ, nhưng có tên khác nhau. đó là "vẻ đẹp" của phần mềm, nó phụ thuộc vào ngôn ngữ mô tả.
steve

Câu trả lời:


69

Trên kiến ​​trúc 32 bit, phạm vi không gian địa chỉ để xử lý RAM là:

0x00000000 - 0xffffffff

hoặc 4'294'967'295(4 GB).

Hạt nhân linux chia ra 3/1 (cũng có thể là 2/2 hoặc 1/3 1 ) vào không gian người dùng (bộ nhớ cao) và không gian nhân (bộ nhớ thấp) tương ứng.

Phạm vi không gian người dùng:

0x00000000 - 0xbfffffff

Mỗi quá trình người dùng mới được sinh ra sẽ có một địa chỉ (phạm vi) trong khu vực này. Các quy trình người dùng thường không đáng tin cậy và do đó bị cấm truy cập vào không gian kernel. Hơn nữa, chúng được coi là không khẩn cấp, như một quy tắc chung, kernel cố gắng trì hoãn việc phân bổ bộ nhớ cho các quá trình đó.

Phạm vi không gian kernel:

0xc0000000 - 0xffffffff

Một tiến trình kernel có địa chỉ (phạm vi) ở đây. Hạt nhân có thể truy cập trực tiếp 1 GB địa chỉ này (tốt, không phải là 1 GB đầy đủ, có 128 MB dành riêng cho truy cập bộ nhớ cao).

Các quy trình sinh ra trong không gian kernel được tin cậy, khẩn cấp và không có lỗi, yêu cầu bộ nhớ được xử lý ngay lập tức.

Mọi tiến trình kernel cũng có thể truy cập phạm vi không gian người dùng nếu muốn. Và để đạt được điều này, kernel ánh xạ một địa chỉ từ không gian người dùng (bộ nhớ cao) sang không gian kernel của nó (bộ nhớ thấp), 128 MB được đề cập ở trên được dành riêng cho việc này.


1 Việc phân chia là 3/1, 2/2 hay 1/3 được kiểm soát bởi CONFIG_VMSPLIT_...tùy chọn; bạn có thể kiểm tra /boot/config*xem tùy chọn nào đã được chọn cho kernel của bạn.


Điều này đã cũ và tôi không chắc bạn ở đây. Nhưng tôi muốn hỏi một điều: 128 MB dành riêng trong không gian kernel (để truy cập bộ nhớ cao), đó có phải là tất cả các tham chiếu của vùng nhớ không gian người dùng không? Vì vậy, một quá trình kernel có thể truy cập bất kỳ không gian người dùng nào bằng cách tham khảo khu vực này, phải không?
Amumu

1
Tại sao nó luôn ở trong 1/4? Tức là tại sao nó không thể chia nó 5/1 hay cái gì đó?
mgasms

Chính xác thì "có thể truy cập trực tiếp" nghĩa là gì ở đây? Ý tôi là, hạt nhân không được truy cập thông qua cơ chế bộ nhớ ảo?
telenn

1
Tôi tin rằng những gì bạn nói về bộ nhớ cao / thấp là sai: Tôi tin rằng trong một hệ thống 32 bit thuần túy, hạt nhân có thể truy cập trực tiếp toàn bộ 3 GB không gian người dùng (kernel có thể truy cập không gian kernel và không gian người dùng). Tuy nhiên, khi bạn có nhân PAE, mọi thứ trở nên phức tạp hơn, giờ bạn có hơn 3 GB RAM, mỗi tiến trình có thể là 3 GB và bạn không thể truy cập trực tiếp vào toàn bộ không gian người dùng. Đây là nơi có mem cao và 128 MB bộ nhớ trong không gian kernel, xuất hiện. Với kernel 64 bit, nó trở nên đơn giản hơn, không có người cao, vì tất cả không gian người dùng đều có thể truy cập được từ kernel.
ctrl-alt-delor

2
@mgasms, 2/4 và chỉ là một tập hợp các lựa chọn mặc định được đưa ra. Kể từ năm 2007, người ta cũng có thể chọn 5/16 và 15/32. Nếu bạn biết chỉnh sửa dòng #define nào, bạn có thể chọn một phân chia gần như tùy ý của riêng bạn.
jørgensen

28

Tham chiếu đầu tiên để chuyển sang là Trình điều khiển thiết bị Linux (có sẵn cả trực tuyến và ở dạng sách), đặc biệt là chương 15 có một phần về chủ đề này.

Trong một thế giới lý tưởng, mọi thành phần hệ thống sẽ có thể ánh xạ tất cả bộ nhớ mà nó cần truy cập. Và đây là trường hợp đối với các quy trình trên Linux và hầu hết các hệ điều hành: quy trình 32 bit chỉ có thể truy cập ít hơn 2 ^ 32 byte bộ nhớ ảo (thực tế là khoảng 3 GB trên kiến ​​trúc 32 bit điển hình của Linux). Hạt nhân gặp khó khăn, cần có khả năng ánh xạ bộ nhớ đầy đủ của quá trình mà hệ thống gọi nó đang thực thi, cộng với toàn bộ bộ nhớ vật lý, cộng với bất kỳ thiết bị phần cứng được ánh xạ bộ nhớ nào khác.

Vì vậy, khi kernel 32 bit cần ánh xạ hơn 4GB bộ nhớ, nó phải được biên dịch với sự hỗ trợ bộ nhớ cao. Bộ nhớ cao là bộ nhớ không được ánh xạ vĩnh viễn trong không gian địa chỉ của kernel. (Bộ nhớ thấp thì ngược lại: nó luôn được ánh xạ, do đó bạn có thể truy cập nó trong kernel chỉ bằng cách hủy bỏ một con trỏ.)

Khi bạn truy cập bộ nhớ cao từ mã kernel, bạn cần gọi kmaptrước, để lấy con trỏ từ cấu trúc dữ liệu trang ( struct page). Gọi kmaphoạt động cho dù trang ở bộ nhớ cao hay thấp. Ngoài ra còn kmap_atomiccó các ràng buộc bổ sung nhưng hiệu quả hơn trên các máy đa bộ xử lý vì nó sử dụng khóa hạt mịn hơn. Con trỏ thu được thông qua kmaplà một tài nguyên: nó sử dụng không gian địa chỉ. Khi bạn đã hoàn thành với nó, bạn phải gọi kunmap(hoặc kunmap_atomic) để giải phóng tài nguyên đó; sau đó con trỏ không còn hợp lệ và nội dung của trang không thể được truy cập cho đến khi bạn gọi kmaplại.


2
Cảm ơn Gilles đã trả lời .. Nhưng, tôi vẫn không thể có được toàn bộ khái niệm. Bạn có thể vui lòng đơn giản hơn một chút mà không làm giảm thông tin trong đó không?
Sen

17

Điều này có liên quan đến nhân Linux; Tôi không chắc làm thế nào bất kỳ nhân Unix nào xử lý việc này.

Bộ nhớ cao là phân đoạn bộ nhớ mà các chương trình không gian người dùng có thể xử lý. Nó không thể chạm vào Bộ nhớ thấp.

Bộ nhớ thấp là phân đoạn bộ nhớ mà nhân Linux có thể xử lý trực tiếp. Nếu hạt nhân phải truy cập vào Bộ nhớ cao, trước tiên nó phải ánh xạ nó vào không gian địa chỉ của chính nó.

Có một bản vá được giới thiệu gần đây cho phép bạn kiểm soát vị trí của phân khúc. Sự cân bằng là bạn có thể lấy bộ nhớ địa chỉ ra khỏi không gian người dùng để kernel có thể có nhiều bộ nhớ hơn mà nó không phải ánh xạ trước khi sử dụng.

Tài nguyên bổ sung:


4

HIGHMEM là một phạm vi không gian bộ nhớ của kernel, nhưng nó không phải là bộ nhớ bạn truy cập mà là nơi bạn đặt những gì bạn muốn truy cập.

Bản đồ bộ nhớ ảo 32 bit điển hình của Linux giống như:

  • 0x00000000-0xbfffffff: quy trình người dùng (3GB)

  • 0xc0000000-0xffffffff: dung lượng kernel (1GB)

(Vectơ dành riêng cho CPU và bất cứ điều gì được bỏ qua ở đây).

Linux chia không gian kernel 1GB thành 2 phần, LOWMEM và HIGHMEM. Sự phân chia khác nhau từ cài đặt để cài đặt.

Nếu cài đặt chọn, giả sử, 512MB-512MB cho các mem thấp và CAO, thì 512MB LOWMEM (0xc0000000-0xdfffffff) được ánh xạ tĩnh tại thời điểm khởi động kernel; thường là rất nhiều byte đầu tiên của bộ nhớ vật lý được sử dụng cho điều này để các địa chỉ ảo và vật lý trong phạm vi này có độ lệch không đổi là 0xc0000000.

Mặt khác, 512 MB sau (HIGHMEM) không có ánh xạ tĩnh (mặc dù bạn có thể để các trang được ánh xạ bán vĩnh viễn ở đó, nhưng bạn phải làm như vậy rõ ràng trong mã trình điều khiển của mình). Thay vào đó, các trang tạm thời được ánh xạ và không được ánh xạ ở đây để các địa chỉ ảo và vật lý trong phạm vi này không có ánh xạ nhất quán. Các ứng dụng điển hình của HIGHMEM bao gồm bộ đệm dữ liệu một lần.


3

Theo tôi nhớ, "Bộ nhớ cao" được sử dụng cho không gian ứng dụng và "Bộ nhớ thấp" cho kernel.

Ưu điểm là các ứng dụng (không gian người dùng) không thể truy cập bộ nhớ không gian nhân.


0

Nhiều người đã nói rằng bộ nhớ thấp là dành cho hệ điều hành. Điều này thường đúng nhưng không phải như vậy. Bộ nhớ cao và bộ nhớ thấp chỉ là hai phần của không gian bộ nhớ, nhưng trong hệ thống Linux, bộ nhớ thấp chỉ dành cho kernel và bộ nhớ cao cho các tiến trình của người dùng.

Theo "Cuốn sách khủng long (khái niệm hệ điều hành)", chúng ta có thể đặt hệ điều hành ở bộ nhớ thấp hoặc bộ nhớ cao. Yếu tố chính ảnh hưởng đến quyết định này là vị trí của vectơ ngắt. Do vectơ ngắt thường ở bộ nhớ thấp, nên các lập trình viên thường đặt hệ điều hành vào bộ nhớ thấp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.