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


35

Tôi chỉ biết rằng đó Interruptlà một nguyên hardware signal assertionnhân trong một bộ xử lý pin. Nhưng tôi muốn biết Linux OS xử lý nó như thế nào.
Tất cả những gì xảy ra khi một sự gián đoạn xảy ra là gì?


tldp.org/LDP/tlk/dd/interrupts.html giải thích mọi thứ về câu hỏi bạn đã hỏi
John

Câu trả lời:


40

Đâ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, các 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 gián đoạn , bộ xử lý sẽ xem xét các ngắt bị che đi. 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.

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 10 là về sự gián đoạn.


22

Gilles đã 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 phát hành

Các ngoại lệ được gây ra bởi lỗi lập trình (lỗi phân chia lỗi , 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ệ được phát hiện bởi bộ xử lý 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 thường có thể được sửa chữa, Bẫy báo cáo một vụ hành quyết, Hủy bỏ là những lỗi nghiêm trọng.
  • Lập trình ngoại lệ theo yêu cầu của lập trình viên, 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 lệnh 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ạ được phát hành bởi các thiết bị I / O; 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ý.
  • Ngắt không thể khắc phục ; trục trặc nghiêm trọng (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ể.
Các hệ thống Linux đa xử lý hiện đại thường bao gồm PIC nâng cao (APIC) mới hơn, phân phối các yêu cầu IRQ bằng nhau giữa các CPU.

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 ( 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ý ngắt 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, hãy xác nhậ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ó

Bạn có thể làm rõ "CPU sẽ kiểm tra sau mỗi lệnh nếu có IRQ từ (A) PIC" . Làm thế nào chính xác nó xảy ra? Nó có liên quan đến VIP-flag trong cờ đăng ký hay gì không? Cảm ơn trước
red0ct

7

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ự 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. Nhân Linux có thể kiểm soát sự 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. Nhân Linux có thể kiểm soát sự 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.

Đ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 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 xử lý ngắt đầu tiên, 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 vòm \ x86 \ kernel \ irq.c)

Trình xử lý ngắt phụ thuộc vectơ thường được bao bọc bởi các lệnh gọi tới irq_enter () và irq_exit (). Vùng mã được đặt trong một cặp các hàm này, là nguyên tử đối với bất kỳ vùng 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 kernel 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.


CPU consults with special CPU control structures filled by Linux kernel to find an address of code to which control will be passed.Vâng! Tôi tự hỏi những cấu trúc điều khiển đặc biệt đó là gì ...
automaton

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.