Địa chỉ vật lý 0 trong x86 Linux chứa gì?


12

Tôi không chắc chắn nếu câu hỏi này nên đi ở đây hoặc trong đảo ngược.stackexchange.com

Trích dẫn từ wikipedia :

Trong bộ xử lý 8086, bảng ngắt được gọi là IVT (bảng vectơ ngắt). IVT luôn nằm ở cùng một vị trí trong bộ nhớ, từ 0x0000 đến 0x03ff và bao gồm 256 con trỏ xa chế độ thực bốn byte (256 × 4 = 1024 byte bộ nhớ).

Đây là những gì tôi tìm thấy trong màn hình qemu:

(qemu) xp/128xw 0
0000000000000000: 0xf000ff53 0xf000ff53 0xf000e2c3 0xf000ff53
0000000000000010: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000020: 0xf000fea5 0xf000e987 0xf000d62c 0xf000d62c
0000000000000030: 0xf000d62c 0xf000d62c 0xf000ef57 0xf000d62c
0000000000000040: 0xc0005526 0xf000f84d 0xf000f841 0xf000e3fe
0000000000000050: 0xf000e739 0xf000f859 0xf000e82e 0xf000efd2
0000000000000060: 0xf000d648 0xf000e6f2 0xf000fe6e 0xf000ff53
0000000000000070: 0xf000ff53 0xf000ff53 0xf0006aa4 0xc0008930
0000000000000080: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000090: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000c0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000d0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000e0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000100: 0xf000ec59 0xf000ff53 0xf000ff53 0xc0006730
0000000000000110: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000120: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000130: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000140: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000150: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000160: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000170: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000180: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000000190: 0x00000000 0x00000000 0x00000000 0xf000ff53
00000000000001a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001c0: 0xf000d611 0xf000ec4e 0xf000ec4e 0xf000ec4e
00000000000001d0: 0xf000d61a 0xf000d623 0xf000d608 0xf000ec4e
00000000000001e0: 0xf000ff53 0x00000000 0xf000ff53 0xf000ff53
00000000000001f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53

Tôi không chắc chắn những gì để làm cho những giá trị. Nó không giống như một bảng mô tả ngắt (bỏ qua các giá trị đó cho tất cả các giá trị null). Vì vậy, những gì tôi thực sự nhìn vào đây?

Câu trả lời:


9

Bất cứ phần sụn nào của bạn đều chứa nó.

Trên một hệ thống hiện đại lý tưởng, bộ xử lý không bao giờ chuyển sang chế độ thực, như tôi đã giải thích trong SU Q & A này có tiêu đề: Máy tính chip Intel 64-bit hiện đại chạy chế độ khởi động ở chế độ nào? , KiB đầu tiên của bộ nhớ vật lý cũng không liên quan như Johan Myréen đã đưa ra câu trả lời khác ở đây. Nhưng nhiều phần mềm hiện đại (vẫn) có hỗ trợ tương thích , có nghĩa là

  • họ có thể thả lại (vâng, quay lại , cho rằng họ đã chuyển trực tiếp từ chế độ không thực sang chế độ được bảo vệ) từ chế độ được bảo vệ sang chế độ thực để chạy phần mềm hệ thống được viết cho chế độ thực, chẳng hạn như các chương trình khởi động PC / AT kiểu cũ trong MBR và VBR; và
  • họ cung cấp các API phần sụn chế độ thực cũ và thiết lập tất cả các cấu trúc dữ liệu cho các API đó, phần mềm hệ thống đã nói ở trên.

Một trong những cấu trúc dữ liệu đó là IVT chế độ thực. Các API phần sụn ở chế độ thực cũ dựa trên các inthướng dẫn và IVT ở chế độ thực được phần sụn đưa vào như là một phần của quá trình khởi tạo với các con trỏ đến các quy trình xử lý phần sụn khác nhau cho các hướng dẫn đó.

Phần mềm hệ thống chế độ được bảo vệ không cần API phần sụn chế độ thực cũ và không bao giờ chạy bộ xử lý ở chế độ thực, do đó IVT chế độ thực trong 1KiB bộ nhớ vật lý đầu tiên không được sử dụng. (v8086 chế độ được bảo vệ không giải quyết địa chỉ vật lý 00000000 trở lên, hãy nhớ. Nó giải quyết các địa chỉ logic 00000000 trở lên, được dịch bởi các bảng trang.) bootstrap, cho nó biết phần nào được dành riêng cho phần sụn cho mục đích API chế độ được bảo vệ của riêng nó và phần nào mà hệ điều hành có thể tự do tiếp tục và sử dụng cho nhóm bộ nhớ vật lý của nó. Về lý thuyết, trang đầu tiên của bộ nhớ vật lý có thể thuộc danh mục sau.

Trong thực tế, trước tiên, các phần cứng thường đánh dấu trang đầu tiên của bộ nhớ vật lý là "mã dịch vụ khởi động", nghĩa là một hệ điều hành có thể yêu cầu nó và chỉ cần tiếp tục và sử dụng nó như một phần của nhóm bộ nhớ vật lý, nhưng chỉ sau khi khởi động- dịch vụ thời gian của phần sụn EFI đã bị hệ điều hành ngừng hoạt động và phần sụn giảm xuống chỉ còn cung cấp dịch vụ thời gian chạy. Một ví dụ về điều này có thể được nhìn thấy trong nhật ký nhân Linux (với add_efi_memmaptùy chọn) được hiển thị bởi Finnbarr P. Murphy:

[0,00000000] efi: mem00: type = 3, attr = 0xf, phạm vi = [0x0000000000000000-0x0000000000001000) (0MB)
xe nào giải mã với chương trình khác ở dạng dễ đọc hơn như:

[# 00] Loại: EfiBootServiceCode Attr: 0xF
      Vật lý: 0000000000000000-0000000000001000
      Số: 0000000000000000-0000000000001000

Trong thực tế, thứ hai, Linux rõ ràng bỏ qua phạm vi bộ nhớ vật lý này ngay cả khi phần sụn nói rằng nó có thể đi trước và sử dụng nó. Bạn sẽ thấy rằng trên cả hai phần mềm EFI và không phải EFI, một khi Linux có bản đồ bộ nhớ vật lý, nó sẽ vá nó ( trong một hàm có têntrim_bios_range ), dẫn đến các thông điệp nhật ký kernel như:

[0,00000000] e820: cập nhật [mem 0x00000000-0x00000fff] có thể sử dụng ==> dành riêng

Điều này không phải là quá nhiều để đối phó với các phần mềm EFI hiện đại, trong đó IVT chế độ thực không phải là một phần của API phần sụn, vì nó là để đối phó với các phần mềm PC98 cũ, nơi nó là một phần của API phần sụn nhưng phần cứng báo cáo nó (thông qua API tự giống nhau đó) như bộ nhớ vật lý có sẵn để được ghi đè hoàn toàn bởi hệ điều hành.

Vì vậy, trong lý thuyết, phạm vi của bộ nhớ vật lý có thể chứa mã hoặc dữ liệu tùy ý, tùy thuộc vào nhu cầu nhất thời của bộ cấp phát bộ nhớ kernel và bộ nhớ ảo theo yêu cầu; trong thực tế, Linux chỉ để nó không bị ảnh hưởng khi phần sụn được thiết lập ban đầu.

Và trên hệ thống của bạn, phần sụn đã chứa nó với các mục IVT chế độ thực. Tất nhiên, các mục IVT ở chế độ thực chỉ là 16:16 con trỏ xa, và nếu bạn nhìn vào bộ nhớ của mình bằng cách sử dụng hexdump 2 byte, bạn thực sự có thể thấy điều này khá rõ ràng. Vài ví dụ:

  • Hầu hết các mục IVT của bạn đều trỏ đến F000: FF53, một địa chỉ trong vùng ROM chương trình cơ sở thực. Nó có lẽ là một thói quen giả mà không có gì hơn một iret.
  • Mục nhập IVT 1E trỏ đến F000: 6AA4, một bảng trong cùng khu vực ROM.
  • Mục nhập IVT 1F trỏ đến C000: 8930, một bảng trong khu vực phần mềm ROM video chế độ thực.
  • Mục nhập IVT 43 điểm đến C000: 6730, một bảng khác trong khu vực phần mềm ROM video chế độ thực.

đọc thêm


Không, ý tôi là những gì tôi đã viết. Tập sách hướng dẫn dành cho nhà phát triển phần mềm kiến ​​trúc Intel tập 3 chương 20 § 2.
JdeBP

Vâng, bạn có bây giờ, bởi vì nó là; như câu đầu tiên của phần đó giải thích. Tôi nghi ngờ từ điều này rằng việc không công nhận chữ viết tắt phổ biến "v8086" là một loại shibboleth. (-:
JdeBP

Bạn cần học cách đọc danh từ thuộc tính. Hoặc khác học cách sống mà không có súp nấm.
JdeBP

7

Kiến trúc bộ xử lý 8086 ban đầu (được triển khai như Chế độ thực trong bộ xử lý 80286+) không liên quan đến Linux, hoạt động ở Chế độ bảo vệ. Không có bảng vectơ ngắt tại địa chỉ vật lý 0, thay vào đó, Bảng mô tả ngắt có chứa Mô tả ngắt được sử dụng. IDT có thể được đặt ở bất cứ đâu trong bộ nhớ.

Nhân Linux lấy bản đồ bộ nhớ vật lý từ phần sụn (BIOS hoặc EFI) cho biết các khung trang bộ nhớ vật lý nào có thể sử dụng được và được dành riêng hoặc không có. Phạm vi của các khung trang có thể sử dụng không liền kề nhau, nhưng thường có lỗ hổng lớn trong đó. Theo truyền thống, nhân Linux x86 đã bỏ qua việc bắt đầu bộ nhớ vật lý, ngay cả khi nó được đánh dấu là có thể sử dụng được. Do đó, địa chỉ vật lý 0 không được sử dụng bởi nhân Linux.


Điều này thật ý nghĩa. Có ai biết nội dung còn sót lại trong trang không sử dụng đó là từ đâu không?
rhodeo

Googling cho 53 ffthấy rằng đây rất có thể là một bảng vectơ ngắt chế độ thực 8086 được thiết lập bởi phần sụn hoặc bộ tải khởi động.
Johan Myréen

4

Bộ nhớ bán phá giá

Đây là một cách khác để kết xuất nội dung của bộ nhớ trong hệ thống so với việc phải thực hiện bên ngoài:

$ head /dev/mem | hexdump -C
00000000  53 ff 00 f0 53 ff 00 f0  53 ff 00 f0 53 ff 00 f0  |S...S...S...S...|
00000010  53 ff 00 f0 53 ff 00 f0  cc e9 00 f0 53 ff 00 f0  |S...S.......S...|
00000020  a5 fe 00 f0 87 e9 00 f0  53 ff 00 f0 46 e7 00 f0  |........S...F...|
00000030  46 e7 00 f0 46 e7 00 f0  57 ef 00 f0 53 ff 00 f0  |F...F...W...S...|
00000040  22 00 00 c0 4d f8 00 f0  41 f8 00 f0 fe e3 00 f0  |"...M...A.......|
00000050  39 e7 00 f0 59 f8 00 f0  2e e8 00 f0 d4 ef 00 f0  |9...Y...........|
00000060  a4 f0 00 f0 f2 e6 00 f0  6e fe 00 f0 53 ff 00 f0  |........n...S...|
00000070  ed ef 00 f0 53 ff 00 f0  c7 ef 00 f0 ed 57 00 c0  |....S........W..|
00000080  53 ff 00 f0 53 ff 00 f0  53 ff 00 f0 53 ff 00 f0  |S...S...S...S...|
...
...
000afea0  00 00 00 00 00 00 00 00  aa aa aa 00 aa aa aa 00  |................|
000afeb0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000b0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
000c0000  55 aa 40 e9 62 0a 00 00  00 00 00 00 00 00 00 00  |U.@.b...........|
000c0010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 49 42  |..............IB|

Phân tích

Phần trên 000c0000 có thể liên quan đến bộ nạp khởi động. Tại sao tôi lại nghi ngờ điều này? Mã 55aah tại vị trí 000c0000thường có thể là một dấu trong bộ nhớ cho những thứ như bộ kích hoạt để BIOS chạy bộ tải khởi động thứ cấp.

Tham khảo: Chữ ký khởi động - BIOS

  ss # 1

Tuy nhiên, với 55aah này xảy ra trong phạm vi c0000h-effffh, nhiều khả năng phần này là Tiêu đề mở rộng PNP:

Tham khảo: Thông số kỹ thuật khởi động BIOS

3.3 Thiết bị có Tiêu đề Mở rộng PnP

Tất cả các thiết bị IPL có ROM tùy chọn phải chứa tiêu đề ROM tùy chọn hợp lệ nằm giữa các địa chỉ bộ nhớ hệ thống C0000h và EFFFFh trên ranh giới 2k và bắt đầu bằng 55AAH. Việc khởi động thiết bị chỉ có thể được kiểm soát nếu thiết bị có Tiêu đề mở rộng PnP. Tiêu đề mở rộng, có địa chỉ nằm trong tiêu đề ROM tùy chọn tiêu chuẩn ở offset + 1Ah, chứa thông tin quan trọng được sử dụng để định cấu hình thiết bị. Nó cũng chứa các con trỏ tới mã trong ROM tùy chọn của thiết bị (BCV hoặc BEV) mà BIOS sẽ gọi để khởi động từ thiết bị. Xem Phụ lục A để biết cấu trúc của Tiêu đề mở rộng PnP. Có hai cách để thiết bị IPL có Tiêu đề mở rộng PnP có thể được khởi động. Nó phải chứa BCV hoặc BEV.

53ff ...

Đối với dữ liệu 53ffh đó là lúc bắt đầu. Nó không rõ ràng với tôi đó thực sự là gì. Nghiên cứu thêm về nó có khả năng là thứ mà nhân Linux đã viết ở đó sau khi quá trình khởi động MBR của BIOS được truyền cho nhân Linux để khởi động.

Thông thường, bộ nạp khởi động sẽ tải kernel vào bộ nhớ, sau đó nhảy đến kernel. Nhân sau đó sẽ có thể lấy lại bộ nhớ được sử dụng bởi bộ nạp khởi động (vì nó đã thực hiện công việc của nó). Tuy nhiên, có thể bao gồm mã hệ điều hành trong khu vực khởi động và giữ nó ở lại sau khi hệ điều hành bắt đầu

Đi sâu hơn nữa tôi đã có thể tìm thấy đoạn này từ một bài nghiên cứu có tiêu đề: Mã độc hại tiêm qua / dev / mem :

1 Thiết bị mem

/ dev / mem là giao diện trình điều khiển cho bộ nhớ địa chỉ vật lý. Mục đích ban đầu của cả mem và kmem là hỗ trợ gỡ lỗi kernel. Chúng ta có thể sử dụng thiết bị như một thiết bị ký tự thông thường, sử dụng lseek () để chọn một địa chỉ bù. Thiết bị kmem tương tự nhưng cung cấp hình ảnh của bộ nhớ kernel trong ngữ cảnh địa chỉ ảo. Máy chủ Xorg sử dụng thiết bị mem để truy cập bộ nhớ video VESA cũng như Bảng Vector ngắt của BIOS ROM (IVT) được đặt tại địa chỉ vật lý 0x00000000 để thao tác các chế độ video ở chế độ VM86. DOSEMU cũng sử dụng điều này để truy cập BIOS IVT để có thể tạo ra các ngắt BIOS cho các tác vụ khác nhau (đọc đĩa, in ra bàn điều khiển, v.v.).

Người giới thiệu

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.