1. Trang chủ
  2. » Giáo Dục - Đào Tạo

lập trình nhân linux interrupts

19 0 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 19
Dung lượng 160,35 KB

Nội dung

Chúng cũng có thểđược nhóm thành hai loại khác dựa trên khả năng trì hoãn hoặc vô hiệu hóa tạm thờingắt: Synchronous Đồng bộ, được tạo bằng cách thực hiện một lệnh Asynchronous Không đ

Trang 1

Interrupts: Ngắt Mục tiêu bài giảng

 Ngắt và ngoại lệ (x86)

 Ngắt và ngoại lệ (Linux)

 Công việc có thể trì hoãn

 Bộ hẹn giờ

Ngắt là gì?

Ngắt là một sự kiện làm thay đổi luồng thực thi thông thường của chương trình và

có thể được tạo ra bởi các thiết bị phần cứng hoặc thậm chí bởi chính CPU Khi xảy ra gián đoạn, luồng thực thi hiện tại bị tạm dừng và trình xử lý ngắt sẽ chạy Sau khi trình

xử lý ngắt chạy, luồng thực thi trước đó sẽ được tiếp tục

Các ngắt có thể được nhóm thành hai loại dựa trên nguồn ngắt Chúng cũng có thể được nhóm thành hai loại khác dựa trên khả năng trì hoãn hoặc vô hiệu hóa tạm thời ngắt:

Synchronous (Đồng bộ), được tạo bằng cách thực hiện một lệnh

Asynchronous (Không đồng bộ), được tạo bởi một sự kiện bên ngoài

Maskable (có thể che giấu hoặc tạm dừng)

o Có thể được bỏ qua

o Được báo hiệu qua chân INT

Non-maskable (không thể che giấu hoặc không thể tắt)

o Không thể bỏ qua

o Được báo hiệu qua chân NMI

Các ngắt đồng bộ, thường được đặt tên là ngoại lệ, xử lý các điều kiện được chính

bộ xử lý phát hiện trong quá trình thực hiện lệnh Chia cho số 0 hoặc cuộc gọi hệ thống

là những ví dụ về trường hợp ngoại lệ

Các ngắt không đồng bộ, thường được đặt tên là các ngắt, là các sự kiện bên ngoài được tạo ra bởi các thiết bị I/O Ví dụ, card mạng tạo ra các ngắt để báo hiệu rằng gói đã đến

Trang 2

Hầu hết các ngắt đều có thể tạm dừng được, có nghĩa là chúng ta có thể tạm thời trì hoãn việc chạy trình xử lý ngắt khi chúng ta vô hiệu hóa ngắt cho đến khi ngắt được kích hoạt lại Tuy nhiên, có một số ngắt quan trọng không thể tắt/hoãn lại được

Ngoại lệ

Có 2 nguồn cho các trường hợp ngoại lệ:

 Bộ xử lý phát hiện

o Lỗi

o Bẫy

o Hủy bỏ

 Lập trình

o int n

Các ngoại lệ do bộ xử lý phát hiện được đưa ra khi phát hiện thấy tình trạng bất thường trong khi thực hiện lệnh

Lỗi là một loại ngoại lệ được báo cáo trước khi thực hiện lệnh và thường có thể được sửa chữa EIP được lưu là địa chỉ của lệnh gây ra lỗi, do đó sau khi lỗi được sửa, chương trình có thể thực hiện lại lệnh bị lỗi (ví dụ: lỗi trang)

Bẫy là một loại ngoại lệ được báo cáo sau khi thực hiện lệnh trong đó phát hiện ngoại lệ EIP đã lưu là địa chỉ của lệnh sau lệnh gây ra bẫy (ví dụ: bẫy gỡ lỗi)

Câu hỏi: Thuật ngữ ngắt

Đối với mỗi thuật ngữ sau đây ở bên trái, hãy chọn tất cả các thuật ngữ từ bên phải

mô tả chúng đúng nhất

 Cơ quan giám sát (Watchdog)  Ngoại lệ (Exception)

 Phân trang theo yêu cầu (Demand

paging)

 Ngắt (Interrupt)

 Chia cho số không (Division by

zero)

 Tạm dừng (Maskable)

 Cuộc gọi hệ thống (System call)  Bẫy (Trap)

Trang 3

Câu trả lời:

 Watchdog: Interrupt, Maskable, Non-maskable

 Demand paging: Trap, Fault

 Division by zero: Exception, Trap, Fault

 Timer: Interrupt, Maskable, Non-maskable

 System call: Trap

 Breakpoint: Exception, Trap, Fault

Khái niệm phần cứng

Bộ điều khiển ngắt lập trình

Thiết bị hỗ trợ ngắt có chân đầu ra được sử dụng để báo hiệu Yêu cầu ngắt Các chân IRQ được kết nối với một thiết bị có tên Bộ điều khiển ngắt khả trình (PIC) được kết nối với chân INTR của CPU

PIC thường có một bộ cổng dùng để trao đổi thông tin với CPU Khi một thiết bị được kết nối với một trong các dòng IRQ của PIC cần sự chú ý của CPU, luồng sau sẽ xảy ra:

 Thiết bị tạo ra một ngắt trên chân IRQn tương ứng

 PIC chuyển đổi IRQ thành số vectơ và ghi nó vào cổng để CPU đọc

 PIC tăng một ngắt trên chân INTR của CPU

 PIC đợi CPU xác nhận một ngắt trước khi đưa ra một ngắt khác

 CPU xác nhận ngắt sau đó nó bắt đầu xử lý ngắt

Trang 4

Sau này sẽ xem CPU xử lý ngắt như thế nào Lưu ý rằng PIC theo thiết kế sẽ không tạo ra một ngắt khác cho đến khi CPU xác nhận ngắt hiện tại

Ghi chú

Sau khi CPU xác nhận ngắt, bộ điều khiển ngắt có thể yêu cầu một ngắt khác, bất

kể CPU đã xử lý xong ngắt trước đó hay chưa Do đó, tùy thuộc vào cách hệ điều

hành điều khiển CPU mà có thể có các ngắt lồng nhau

Bộ điều khiển ngắt cho phép từng dòng IRQ bị vô hiệu hóa riêng lẻ Điều này cho phép đơn giản hóa thiết kế bằng cách đảm bảo rằng các bộ xử lý ngắt luôn được thực thi tuần tự

Bộ điều khiển ngắt trong hệ thống SMP

Trong hệ thống SMP, chúng ta có thể có nhiều bộ điều khiển ngắt trong hệ thống

Ví dụ: trên kiến trúc x86, mỗi lõi có một APIC cục bộ được sử dụng để xử lý các ngắt từ các thiết bị được kết nối cục bộ như bộ định thời hoặc cảm biến nhiệt Sau đó, có APIC I/O được sử dụng để phân phối IRQ từ các thiết bị bên ngoài đến lõi CPU

Trang 5

Kiểm soát ngắt

Để đồng bộ hóa quyền truy cập vào dữ liệu được chia sẻ giữa trình xử lý ngắt và các hoạt động đồng thời tiềm năng khác như khởi tạo trình điều khiển hoặc xử lý dữ liệu trình điều khiển, thường cần phải bật và tắt các ngắt theo cách được kiểm soát

Điều này có thể được thực hiện ở nhiều cấp độ:

 Ở cấp độ thiết bị

o Bằng cách lập trình các thanh ghi điều khiển thiết bị

 Ở cấp độ PIC

o PIC có thể được lập trình để vô hiệu hóa một dòng IRQ nhất định

 Ở cấp độ CPU; ví dụ: trên x86, người ta có thể sử dụng các hướng dẫn sau:

 cli (Cờ ngắt Clear)

 sti (Cờ ngắt SeT)

Ưu tiên ngắt

Hầu hết các kiến trúc cũng hỗ trợ các ưu tiên ngắt Khi tính năng này được bật, nó chỉ cho phép lồng ngắt đối với những ngắt có mức ưu tiên cao hơn mức ưu tiên hiện tại

Ghi chú

Trang 6

Không phải tất cả các kiến trúc đều hỗ trợ mức độ ưu tiên ngắt Cũng khó hỗ trợ

việc xác định sơ đồ chung cho các ưu tiên ngắt cho các hệ điều hành sử dụng

chung và một số hạt nhân (bao gồm cả Linux) không sử dụng các ưu tiên ngắt

Mặt khác, hầu hết các RTOS sử dụng mức độ ưu tiên ngắt vì chúng thường được

sử dụng trong các trường hợp sử dụng hạn chế hơn, trong đó việc xác định mức

độ ưu tiên ngắt sẽ dễ dàng hơn

Câu hỏi: Khái niệm phần cứng

Khẳng định nào sau đây là đúng?

 CPU có thể bắt đầu xử lý một ngắt mới trước khi ngắt hiện tại kết thúc

 Ngắt có thể bị vô hiệu hóa ở cấp độ thiết bị

 Các ngắt có mức ưu tiên thấp hơn không thể ưu tiên các trình xử lý cho các ngắt có mức ưu tiên cao hơn

 Ngắt có thể bị vô hiệu hóa ở cấp độ bộ điều khiển ngắt

 Trên hệ thống SMP, cùng một ngắt có thể được định tuyến đến các CPU khác nhau

Ngắt có thể bị vô hiệu hóa ở cấp độ CPU

Câu trả lời:

 CPU có thể bắt đầu xử lý một ngắt mới trước khi ngắt hiện tại kết thúc:

Đúng Điều này thường được gọi là lồng ngắt, trong đó ngắt có mức ưu tiên

cao hơn có thể làm gián đoạn việc xử lý ngắt có mức ưu tiên thấp hơn

Ngắt có thể bị vô hiệu hóa ở cấp độ thiết bị: Đúng Các thiết bị có thể có cơ

chế điều khiển để kích hoạt hoặc vô hiệu hóa khả năng tạo ra các ngắt

 Các ngắt có mức ưu tiên thấp hơn không thể ưu tiên các trình xử lý cho các

ngắt có mức ưu tiên cao hơn: Sai Trong hầu hết các hệ thống ngắt, các ngắt

có mức ưu tiên cao hơn có thể ưu tiên các ngắt có mức ưu tiên thấp hơn

Ngắt có thể bị vô hiệu hóa ở cấp độ bộ điều khiển ngắt: Đúng Bộ điều

khiển ngắt thường có cơ chế cho phép hoặc vô hiệu hóa việc tạo ngắt

 Trên hệ thống SMP, cùng một ngắt có thể được định tuyến đến các CPU

khác nhau: Đúng Điều này phổ biến trong các hệ thống đa xử lý đối xứng

(SMP), trong đó các ngắt có thể được phân phối trên nhiều CPU

Trang 7

Ngắt có thể bị vô hiệu hóa ở cấp độ CPU: Đúng CPU thường có cơ chế

kích hoạt hoặc vô hiệu hóa việc xử lý ngắt tạm thời

Xử lý ngắt trên kiến trúc x86

Phần này sẽ xem xét cách CPU xử lý các ngắt trên kiến trúc thex86

Bảng mô tả ngắt

Bảng mô tả ngắt (IDT) liên kết mỗi ngắt hoặc mã định danh ngoại lệ với một bộ mô

tả cho các lệnh phục vụ sự kiện liên quan Chúng ta sẽ đặt tên mã định danh là số vectơ

và các lệnh liên quan là trình xử lý ngắt/ngoại lệ

IDT có các đặc điểm sau:

 Nó được CPU sử dụng làm bảng nhảy khi một vectơ nhất định được kích hoạt

 Nó là một mảng gồm các mục 256 x 8 byte

 Có thể cư trú ở bất cứ đâu trong bộ nhớ vật lý

 Bộ xử lý định vị IDT bằng IDTR

Dưới đây chúng ta có thể tìm thấy bố cục vector IRQ của Linux 32 mục đầu tiên được dành riêng cho các trường hợp ngoại lệ, vectơ 128 được sử dụng cho giao diện tòa nhà và phần còn lại được sử dụng chủ yếu cho các trình xử lý ngắt phần cứng

Trang 8

Trên x86, mục nhập IDT có 8 byte và được đặt tên là cổng Có thể có 3 loại cổng:

 Cổng ngắt, giữ địa chỉ của trình xử lý ngắt hoặc ngoại lệ Việc chuyển sang trình

xử lý sẽ vô hiệu hóa các ngắt có thể che được (cờ IF bị xóa)

 Cổng bẫy, tương tự như cổng ngắt nhưng nó không vô hiệu hóa các ngắt có thể che được trong khi chuyển sang trình xử lý ngắt/ngoại lệ

 Cổng tác vụ (không được sử dụng trong Linux)

Chúng ta hãy xem xét một số trường của mục nhập IDT:

 Bộ chọn phân đoạn, lập chỉ mục vào GDT/LDT để tìm điểm bắt đầu của đoạn

mã nơi chứa trình xử lý ngắt

 Offset, offset bên trong đoạn mã

 T, đại diện cho loại cổng

 DPL, đặc quyền tối thiểu cần thiết để sử dụng nội dung phân đoạn

Trang 9

Địa chỉ xử lý ngắt

Để tìm địa chỉ trình xử lý ngắt, trước tiên chúng ta cần tìm địa chỉ bắt đầu của đoạn

mã nơi chứa trình xử lý ngắt Để làm điều này, chúng tôi sử dụng bộ chọn phân đoạn để lập chỉ mục vào GDT/LDT nơi chúng tôi có thể tìm thấy bộ mô tả phân đoạn tương ứng Điều này sẽ cung cấp địa chỉ bắt đầu được lưu trong trường 'cơ sở' Sử dụng địa chỉ cơ

sở và phần bù, bây giờ chúng ta có thể đi đến điểm bắt đầu của trình xử lý ngắt

Ngăn xếp xử lý ngắt

Tương tự như việc chuyển điều khiển sang một hàm thông thường, việc chuyển điều khiển sang một trình xử lý ngắt hoặc ngoại lệ sử dụng ngăn xếp để lưu trữ thông tin cần thiết để quay lại mã bị gián đoạn

Như có thể thấy trong hình bên dưới, một ngắt sẽ đẩy thanh ghi EFLAGS trước khi lưu địa chỉ của lệnh bị gián đoạn Một số loại ngoại lệ nhất định cũng khiến mã lỗi được đẩy lên ngăn xếp để giúp gỡ lỗi ngoại lệ

Trang 10

Xử lý yêu cầu ngắt

Sau khi một yêu cầu ngắt được tạo ra, bộ xử lý sẽ chạy một chuỗi các sự kiện mà cuối cùng kết thúc bằng việc chạy trình xử lý ngắt kernel:

 CPU kiểm tra mức đặc quyền hiện tại

 Nếu cần thay đổi cấp độ đặc quyền

o Thay đổi ngăn xếp bằng ngăn xếp được liên kết với đặc quyền mới

o Lưu thông tin ngăn xếp cũ vào ngăn xếp mới

 Lưu EFLAGS, CS, EIP vào ngăn xếp

 Lưu mã lỗi vào ngăn xếp trong trường hợp hủy bỏ

 Thực thi trình xử lý ngắt kernel

Trở về từ trình xử lý ngắt

Hầu hết các kiến trúc đều đưa ra các hướng dẫn đặc biệt để dọn sạch ngăn xếp và tiếp tục thực thi sau khi trình xử lý ngắt đã được thực thi Trên x86 IRET được sử dụng

để trả về từ trình xử lý ngắt IRET tương tự như RET ngoại trừ việc IRETin tăng thêm ESP thêm bốn byte (do các cờ trên ngăn xếp) và chuyển các cờ đã lưu vào thanh ghi EFLAGS

Để tiếp tục thực thi sau khi bị gián đoạn, trình tự sau được sử dụng (x86):

 Bật mã lỗi (trong trường hợp hủy bỏ)

Trang 11

 Gọi IRET

o POPS các giá trị từ ngăn xếp và khôi phục thanh ghi sau: CS, EIP, EFLAGS

o Nếu mức đặc quyền thay đổi sẽ trở về ngăn xếp cũ và mức đặc quyền cũ

Kiểm tra xử lý ngắt x86

Các lệnh gdb sau đây được sử dụng để xác định trình xử lý ngoại lệ cuộc gọi hệ thống dựa trên int80 Chọn và sắp xếp các lệnh hoặc đầu ra của lệnh theo đúng thứ tự

(void *) 0xc15de780 <entry_SYSENTER_32>

set $idtr_addr=($idtr_entry>>48<<16)|($idtr_entry&0xffff)

print (void*)$idtr_addr

set $idtr = 0xff800000

(void *) 0xc15de874 <entry_INT80_32>

set $idtr = 0xff801000

set $idtr_entry = *(uint64_t*)($idtr + 8 * 128)

monitor info registers

Câu trả lời:

1 set $idtr = 0xff800000: Đây là lệnh để thiết lập giá trị của biến $idtr, một địa chỉ

cụ thể trong bộ nhớ

2 set $idtr_entry = *(uint64_t*)($idtr + 8 * 128): Lệnh này sử dụng giá trị của

$idtr để truy cập một địa chỉ cụ thể trong bộ nhớ và gán giá trị tại đó cho biến

$idtr_entry

3 set $idtr_addr=($idtr_entry>>48<<16)|($idtr_entry&0xffff): Tính toán giá trị của $idtr_addr dựa trên giá trị của $idtr_entry theo công thức đã cho

4 print (void*)$idtr_addr: In ra giá trị của $idtr_addr dưới dạng con trỏ

5 (void *) 0xc15de780 <entry_SYSENTER_32>: Đây là đầu ra của lệnh trước đó,

có thể là một địa chỉ cụ thể trong bộ nhớ

6 set $idtr = 0xff801000: Lệnh này lại một lần nữa thiết lập giá trị mới cho $idtr

7 (void *) 0xc15de874 <entry_INT80_32>: Đây cũng là một địa chỉ cụ thể trong

bộ nhớ, có thể liên quan đến trình xử lý ngoại lệ cuộc gọi hệ thống

Trang 12

8 monitor info registers: Đây là lệnh để hiển thị thông tin về các thanh ghi trong máy tính

Xử lý ngắt trong Linux

Trong Linux, việc xử lý ngắt được thực hiện theo ba giai đoạn: quan trọng, ngay lập tức và trì hoãn

Trong giai đoạn đầu tiên, kernel sẽ chạy trình xử lý ngắt chung để xác định số ngắt, trình xử lý ngắt cho ngắt cụ thể này và bộ điều khiển ngắt Tại thời điểm này, mọi hành động quan trọng về thời gian cũng sẽ được thực hiện (ví dụ: xác nhận ngắt ở cấp bộ điều khiển ngắt) Các ngắt bộ xử lý cục bộ bị vô hiệu hóa trong suốt giai đoạn này và tiếp tục

bị vô hiệu hóa trong giai đoạn tiếp theo

Trong giai đoạn thứ hai, tất cả các trình xử lý của trình điều khiển thiết bị liên quan đến ngắt này sẽ được thực thi Vào cuối giai đoạn này, phương thức "kết thúc ngắt" của

bộ điều khiển ngắt được gọi để cho phép bộ điều khiển ngắt xác nhận lại ngắt này Các ngắt bộ xử lý cục bộ được kích hoạt tại thời điểm này

Ghi chú

Có thể một ngắt được liên kết với nhiều thiết bị và trong trường hợp này người ta

nói rằng ngắt được chia sẻ Thông thường, khi sử dụng các ngắt được chia sẻ,

trình điều khiển thiết bị có trách nhiệm xác định xem ngắt có nhắm mục tiêu đến

thiết bị của nó hay không

Cuối cùng, trong giai đoạn cuối của quá trình xử lý ngắt, các hành động trì hoãn bối cảnh ngắt sẽ được chạy Đôi khi chúng còn được gọi là "nửa dưới" của ngắt (nửa trên là phần xử lý ngắt chạy với các ngắt bị vô hiệu hóa) Tại thời điểm này, các ngắt được kích hoạt trên bộ xử lý cục bộ

Trang 13

Các ngắt và ngoại lệ lồng nhau

Linux từng hỗ trợ các ngắt lồng nhau nhưng điều này đã bị loại bỏ một thời gian trước để tránh các giải pháp ngày càng phức tạp cho các vấn đề về stackoverflow - chỉ cho phép một cấp độ lồng nhau, cho phép nhiều cấp độ lồng nhau đến một độ sâu ngăn xếp hạt nhân nhất định, v.v

Tuy nhiên, vẫn có thể có sự lồng ghép giữa các ngoại lệ và các ngắt nhưng các quy tắc khá hạn chế:

 Một ngoại lệ (ví dụ: lỗi trang, lệnh gọi hệ thống) không thể tránh được sự gián đoạn; nếu điều đó xảy ra thì đó được coi là một lỗi

 Một ngắt có thể ngăn chặn một ngoại lệ

 Một ngắt không thể chặn trước một ngắt khác (trước đây có thể xảy ra)

Sơ đồ dưới đây cho thấy các tình huống lồng nhau có thể xảy ra:

Trang 14

Bối cảnh ngắt

Trong khi một ngắt được xử lý (từ lúc CPU chuyển sang bộ xử lý ngắt cho đến khi

bộ xử lý ngắt quay trở lại - ví dụ: IRET được phát hành), người ta nói rằng mã đó chạy trong "ngữ cảnh ngắt"

Mã chạy trong ngữ cảnh ngắt có các thuộc tính sau:

 Nó chạy do IRQ (không phải là ngoại lệ)

 Không có bối cảnh quy trình được xác định rõ ràng liên quan

 Không được phép kích hoạt chuyển đổi ngữ cảnh (không có quyền truy cập chế

độ ngủ, lịch trình hoặc bộ nhớ người dùng)

Hành động có thể trì hoãn

Các hành động có thể trì hoãn được sử dụng để chạy các hàm gọi lại sau này Nếu các hành động có thể trì hoãn được lên lịch từ trình xử lý ngắt, hàm gọi lại liên quan sẽ chạy sau khi trình xử lý ngắt hoàn tất

Có hai loại hành động lớn có thể trì hoãn: những hành động chạy trong ngữ cảnh không bị gián đoạn và những hành động chạy trong ngữ cảnh tiến trình

Mục đích của các hành động có thể trì hoãn ngữ cảnh ngắt là để tránh thực hiện quá nhiều công việc trong hàm xử lý ngắt Chạy quá lâu với các ngắt bị vô hiệu hóa có thể gây ra những tác động không mong muốn như độ trễ tăng lên hoặc hiệu suất hệ thống kém do thiếu các ngắt khác (ví dụ: làm mất các gói mạng vì CPU không phản ứng kịp thời để loại bỏ các gói khỏi giao diện mạng và bộ đệm card mạng đã đầy)

Các hành động có thể trì hoãn có các API để: khởi tạo một phiên bản, kích hoạt hoặc lên lịch hành động và che/vô hiệu hóa và vạch mặt/cho phép thực thi chức năng gọi lại Cái sau được sử dụng cho mục đích đồng bộ hóa giữa hàm gọi lại và các ngữ cảnh khác

Thông thường, trình điều khiển thiết bị sẽ khởi tạo cấu trúc hành động có thể trì hoãn trong quá trình khởi tạo phiên bản thiết bị và sẽ kích hoạt/lên lịch hành động có thể trì hoãn từ trình xử lý ngắt

Ngày đăng: 08/05/2024, 15:56

w