it-swarm-vi.com

Làm thế nào một ngắt được xử lý trong Linux?

Tôi chỉ biết rằng Interrupt là một hardware signal assertion gây ra trong một pin bộ xử lý. Nhưng tôi muốn biết Linux OS xử lý nó như thế nào.
[.___.] Tất cả những điều xảy ra khi gián đoạn xảy ra là gì?

35
Sen

Đây là một cái nhìn cấp cao về xử lý cấp thấp. Tôi đang mô tả một kiến ​​trúc điển hình đơn giản, kiến ​​trúc thực có thể phức tạp hơn hoặc khác biệt theo những cách không quan trọng ở mức độ chi tiết này.

Khi xảy ra ngắt , bộ xử lý sẽ xem nếu các ngắt bị che. Nếu có, không có gì xảy ra cho đến khi chúng bị vạch mặt. Khi các ngắt bị vạch mặt, nếu có bất kỳ ngắt nào đang chờ xử lý, bộ xử lý sẽ chọn một ngắt.

Sau đó, bộ xử lý thực hiện ngắt bằng cách phân nhánh đến một địa chỉ cụ thể trong bộ nhớ. Mã tại địa chỉ đó được gọi là trình xử lý ngắt . Khi bộ xử lý phân nhánh ở đó, nó che dấu ngắt (vì vậy trình xử lý ngắt có quyền kiểm soát độc quyền) và lưu nội dung của một số thanh ghi ở một nơi nào đó (thường là các thanh ghi khác).

Trình xử lý ngắt thực hiện những gì nó phải làm, thông thường bằng cách giao tiếp với thiết bị ngoại vi đã kích hoạt ngắt để gửi hoặc nhận dữ liệu. Nếu ngắt được tăng lên bởi bộ đếm thời gian, trình xử lý có thể kích hoạt bộ lập lịch hệ điều hành, để chuyển sang một luồng khác. Khi trình xử lý kết thúc thực thi, nó sẽ thực thi một lệnh trả về từ ngắt đặc biệt để khôi phục các thanh ghi đã lưu và vạch mặt các ngắt.

Trình xử lý ngắt phải chạy nhanh, vì nó ngăn không cho bất kỳ ngắt nào khác chạy. Trong nhân Linux, xử lý ngắt được chia thành hai phần:

  • Nửa đầu trên đỉnh cao là một bộ xử lý ngắt. Nó thực hiện tối thiểu cần thiết, thường giao tiếp với phần cứng và đặt cờ ở đâu đó trong bộ nhớ kernel.
  • Phần dưới cùng của một phần mềm thực hiện bất kỳ xử lý cần thiết nào khác, ví dụ sao chép dữ liệu vào bộ nhớ xử lý, cập nhật cấu trúc dữ liệu kernel, v.v. Nó có thể mất thời gian và thậm chí chặn chờ một số phần khác của hệ thống vì nó chạy với ngắt được kích hoạt.

Như thường lệ về chủ đề này, để biết thêm thông tin, hãy đọc Trình điều khiển thiết bị Linux ; chương 1 là về ngắt.

Gilles đã được mô tả trường hợp chung của một ngắt, điều sau đây áp dụng riêng cho Linux 2.6 trên kiến ​​trúc Intel (một phần của điều này cũng dựa trên thông số kỹ thuật của Intel).

Một ngắt là một sự kiện thay đổi chuỗi các lệnh được thực hiện bởi bộ xử lý.
[.__.] Có hai loại ngắt khác nhau:

  • Ngắt đồng bộ (Ngoại lệ) do CPU tạo ra trong khi xử lý các hướng dẫn
  • Ngắt không đồng bộ (Ngắt) do các thiết bị phần cứng khác cấp

Các ngoại lệ được gây ra bởi lỗi lập trình (fe Lỗi phân chia, Lỗi trang, Tràn) phải được xử lý bởi kernel . Anh ta gửi tín hiệu đến chương trình và cố gắng khắc phục lỗi.

Hai trường hợp ngoại lệ sau được phân loại:

  • Ngoại lệ do bộ xử lý phát hiện do CPU tạo ra trong khi phát hiện tình trạng bất thường; được chia thành ba nhóm: Lỗi nói chung có thể được sửa, Bẫy báo cáo thực thi, Hủy bỏ là những lỗi nghiêm trọng.
  • Ngoại lệ được lập trình do người lập trình yêu cầu, xử lý như một cái bẫy.

Ngắt có thể được phát hành bởi các thiết bị I/O (bàn phím, bộ điều hợp mạng, ..), bộ định thời khoảng thời gian và (trên các hệ thống đa bộ xử lý) các CPU khác. Khi xảy ra gián đoạn, CPU phải dừng hướng dẫn hiện tại của mình và thực hiện ngắt mới đến. Anh ta cần lưu trạng thái quá trình bị gián đoạn cũ để (có thể) tiếp tục lại trạng thái đó sau khi ngắt được xử lý.

Xử lý ngắt là một nhiệm vụ nhạy cảm:

  • Ngắt có thể xảy ra bất cứ lúc nào, hạt nhân cố gắng đưa nó ra khỏi đường càng sớm càng tốt
  • Một ngắt có thể bị gián đoạn bởi một ngắt khác
  • Có những vùng trong kernel không bị gián đoạn

Hai mức ngắt khác nhau được xác định:

  • Ngắt mặt nạ do thiết bị I/O cấp; có thể ở hai trạng thái, bịt mặt hoặc lột mặt nạ. Chỉ có các ngắt bị vạch mặt đang được xử lý.
  • Các ngắt không thể mã hóa ; trục trặc nghiêm trọng (ví dụ: lỗi phần cứng); luôn được xử lý bởi CPU.

Mỗi thiết bị phần cứng đều có dòng Yêu cầu ngắt (IRQ) riêng. Các IRQ được đánh số bắt đầu từ 0. Tất cả các dòng IRQ được kết nối với Bộ điều khiển ngắt lập trình (PIC). PIC lắng nghe trên IRQ và gán chúng cho CPU. Cũng có thể vô hiệu hóa một dòng IRQ cụ thể.
[.___.

Bước giữa giữa một ngắt hoặc ngoại lệ và việc xử lý nó là Bảng mô tả ngắt (IDT). Bảng này liên kết mỗi vectơ ngắt hoặc ngoại lệ (một số) với một trình xử lý đã chỉ định (f.e. Lỗi phân chia được xử lý bởi hàm divide_error()).

Thông qua IDT, kernel biết chính xác cách xử lý gián đoạn xảy ra hoặc ngoại lệ.


Vì vậy, hạt nhân khi xảy ra gián đoạn là gì?

  • CPU sẽ kiểm tra sau mỗi lệnh nếu có IRQ từ (A) PIC
  • Nếu vậy, tư vấn IDT để ánh xạ vectơ nhận được vào một hàm
  • Kiểm tra nếu ngắt được cấp bởi một nguồn có thẩm quyền
  • Lưu các thanh ghi của quá trình bị gián đoạn
  • Gọi hàm theo để xử lý ngắt
  • Tải các thanh ghi đã lưu gần đây của quá trình bị gián đoạn và cố gắng tiếp tục nó
22
wag

Trước hết những người tham gia xử lý ngắt là các thiết bị phần cứng ngoại vi, bộ điều khiển ngắt, CPU, nhân hệ điều hành và trình điều khiển. Các thiết bị phần cứng ngoại vi chịu trách nhiệm tạo ra ngắt. Họ khẳng định các dòng yêu cầu ngắt khi họ muốn sự chú ý từ nhân hệ điều hành. Các tín hiệu này được ghép bởi bộ điều khiển ngắt, chịu trách nhiệm thu thập tín hiệu ngắt. Nó cũng chịu trách nhiệm xác định thứ tự các tín hiệu ngắt sẽ được truyền đến CPU. Bộ điều khiển ngắt có thể vô hiệu hóa tạm thời dòng yêu cầu ngắt cụ thể (IRQL) và kích hoạt lại nó (mặt nạ IRQL). Bộ điều khiển ngắt chuyển các yêu cầu ngắt được thu thập tới CPU theo tuần tự. CPU sau khi hoàn thành thực thi từng lệnh CPU không kiểm tra xem có yêu cầu ngắt chờ nào từ bộ điều khiển ngắt không. Nếu CPU thấy rằng có yêu cầu chờ VÀ cờ Bật ngắt được đặt trong thanh ghi điều khiển CPU bên trong thì CPU bắt đầu xử lý ngắt. Như bạn có thể thấy, bằng cách thao tác trên cờ Ngắt trong CPU và giao tiếp với bộ điều khiển ngắt, nhân Linux có thể điều khiển chấp nhận ngắt. Ví dụ: Linux có thể vô hiệu hóa việc chấp nhận các ngắt từ thiết bị cụ thể hoặc vô hiệu hóa chấp nhận ngắt ở tất cả.

Điều gì xảy ra khi bộ xử lý nhận được yêu cầu ngắt? Đầu tiên, CPU tự động vô hiệu hóa các ngắt bằng cách đặt lại Cờ ngắt. Chúng sẽ được kích hoạt lại sau khi xử lý ngắt sẽ kết thúc. Đồng thời, CPU tạo ra khối lượng công việc tối thiểu cần thiết để chuyển CPU từ chế độ người dùng sang chế độ kernel theo cách cho phép nó tiếp tục thực thi mã bị gián đoạn. CPU tư vấn với các cấu trúc điều khiển CPU đặc biệt được điền bởi nhân Linux để tìm địa chỉ mã mà điều khiển sẽ được thông qua. Địa chỉ này là địa chỉ của lệnh đầu tiên của trình xử lý ngắt, là một phần của nhân Linux.

Là bước đầu tiên của nhân xử lý ngắt xác định vectơ ngắt nhận được để xác định loại sự kiện nào đã xảy ra trong hệ thống. Vector ngắt xác định những hành động nào Linux sẽ thực hiện để xử lý nó. Là bước thứ hai, Linux lưu phần còn lại của các thanh ghi CPU (không được lưu tự động bởi CPU) và có thể được sử dụng bởi chương trình bị gián đoạn. Đây là hành động rất quan trọng, vì nó cho phép Linux xử lý các ngắt liên quan đến chương trình bị gián đoạn. Bước thứ ba, Linux hoàn thành việc chuyển sang chế độ kernel bằng cách đặt môi trường kernel và đặt trạng thái CPU cần thiết cho nó. Và cuối cùng, xử lý ngắt phụ thuộc vector được gọi. (Bạn có thể xem macro BUILD_INTERRUPT3 trong Arch\x86\kernel\entry_32.S để lấy các chi tiết bổ sung cho ví dụ liên quan đến kiến ​​trúc x86) Trong trường hợp thiết bị ngoại vi, đây là thói quen do_IRQ (). (Nhìn vào Arch\x86\kernel\irq.c)

Trình xử lý ngắt phụ thuộc vector thường được bao bọc bởi các lệnh gọi tới irq_enter () và irq_exit (). Khu vực mã được bao quanh trong một cặp các chức năng này, là nguyên tử đối với bất kỳ khu vực nào khác và cũng là nguyên tử đối với các cặp cli/sti. Irq_enter () và irq_exit () cũng nắm bắt một số thống kê liên quan đến việc xử lý ngắt. Cuối cùng, kernel nhìn vào bảng vector_irq để tìm số irq được gán cho vectơ của ngắt nhận được và gọi hàm hand_irq () (từ Arch\x86\kernel\irq_32.c).

Tại thời điểm này, phần chung của việc xử lý ngắt trong Linux kết thúc, bởi vì kernel trông thường trình xử lý ngắt phụ thuộc thiết bị được trình điều khiển thiết bị cài đặt như một phần của bộ mô tả irq và gọi nó. Nếu trình xử lý đó không được cài đặt bởi trình điều khiển, kernel chỉ thừa nhận ngắt trên bộ điều khiển ngắt và đi ra khỏi trình xử lý ngắt chung.

Sau khi kết thúc nhân xử lý ngắt sẽ khôi phục trạng thái của chương trình đã bị gián đoạn trước đó và tiếp tục thực hiện chương trình này.

8
ZarathustrA

Từ khía cạnh lý thuyết, hầu hết mọi thứ đã được giải thích. Nhưng nếu bạn đang tìm kiếm lời giải thích về khung mã xử lý ngắt kernel, liên kết sau đây bạn nên: Một mã đi bên trong xử lý ngắt kernel

Và nếu bạn vẫn đang tìm kiếm lý thuyết về các trình xử lý ngắt và ngắt, thì tôi khuyên bạn nên đọc phần này: Hiểu các ngắt và các trình xử lý ngắt

3
trukna