瀏覽代碼

(Redoing check-in lost by SourceForge's failure.)

Add method for hooking real-mode interrupt vectors.
tags/v0.9.3
Michael Brown 18 年之前
父節點
當前提交
847f38f4ac
共有 2 個文件被更改,包括 74 次插入0 次删除
  1. 17
    0
      src/arch/i386/include/biosint.h
  2. 57
    0
      src/arch/i386/interface/pcbios/biosint.c

+ 17
- 0
src/arch/i386/include/biosint.h 查看文件

@@ -0,0 +1,17 @@
1
+#ifndef BIOSINT_H
2
+#define BIOSINT_H
3
+
4
+/**
5
+ * @file BIOS interrupts
6
+ *
7
+ */
8
+
9
+struct segoff;
10
+
11
+extern void hook_bios_interrupt ( unsigned int interrupt, unsigned int handler,
12
+				  struct segoff *chain_vector );
13
+extern int unhook_bios_interrupt ( unsigned int interrupt,
14
+				   unsigned int handler,
15
+				   struct segoff *chain_vector );
16
+
17
+#endif /* BIOSINT_H */

+ 57
- 0
src/arch/i386/interface/pcbios/biosint.c 查看文件

@@ -0,0 +1,57 @@
1
+#include <errno.h>
2
+#include <realmode.h>
3
+#include <biosint.h>
4
+
5
+/**
6
+ * @file BIOS interrupts
7
+ *
8
+ */
9
+
10
+/**
11
+ * Hook INT vector
12
+ *
13
+ * @v interrupt		INT number
14
+ * @v handler		Offset within .text16 to interrupt handler
15
+ * @v chain_vector	Vector for chaining to previous handler
16
+ *
17
+ * Hooks in an i386 INT handler.  The handler itself must reside
18
+ * within the .text16 segment.  @c chain_vector will be filled in with
19
+ * the address of the previously-installed handler for this interrupt;
20
+ * the handler should probably exit by ljmping via this vector.
21
+ */
22
+void hook_bios_interrupt ( unsigned int interrupt, unsigned int handler,
23
+			   struct segoff *chain_vector ) {
24
+	struct segoff vector = {
25
+		.segment = rm_cs,
26
+		.offset = handler,
27
+	};
28
+
29
+	copy_from_real ( chain_vector, 0, ( interrupt * 4 ),
30
+			 sizeof ( *chain_vector ) );
31
+	copy_to_real ( 0, ( interrupt * 4 ), &vector, sizeof ( vector ) );
32
+}
33
+
34
+/**
35
+ * Unhook INT vector
36
+ *
37
+ * @v interrupt		INT number
38
+ * @v handler		Offset within .text16 to interrupt handler
39
+ * @v chain_vector	Vector containing address of previous handler
40
+ *
41
+ * Unhooks an i386 interrupt handler hooked by hook_i386_vector().
42
+ * Note that this operation may fail, if some external code has hooked
43
+ * the vector since we hooked in our handler.  If it fails, it means
44
+ * that it is not possible to unhook our handler, and we must leave it
45
+ * (and its chaining vector) resident in memory.
46
+ */
47
+int unhook_bios_interrupt ( unsigned int interrupt, unsigned int handler,
48
+			    struct segoff *chain_vector ) {
49
+	struct segoff vector;
50
+
51
+	copy_from_real ( &vector, 0, ( interrupt * 4 ), sizeof ( vector ) );
52
+	if ( ( vector.segment != rm_cs ) || ( vector.offset != handler ) )
53
+		return -EBUSY;
54
+	copy_to_real ( 0, ( interrupt * 4 ), chain_vector,
55
+		       sizeof ( *chain_vector ) );
56
+	return 0;
57
+}

Loading…
取消
儲存