📄 linux_0
字号:
250 restore_flags(flags);
251 return 0;
252 }
253
254 int request_irq(unsigned int irq, void (*handler)(int))
255 {
256 struct sigaction sa;
257
258 sa.sa_handler = handler;
259 sa.sa_flags = 0;
260 sa.sa_mask = 0;
261 sa.sa_restorer = NULL;
262 return irqaction(irq,&sa);
263 }
264
265 void free_irq(unsigned int irq)
266 {
267 struct sigaction * sa = irq + irq_sigaction;
268 unsigned long flags;
269
270 if (irq > 15) {
271 printk("Trying to free IRQ%d\n",irq);
272 return;
273 }
274 if (!sa->sa_mask) {
275 printk("Trying to free free IRQ%d\n",irq);
276 return;
277 }
278 save_flags(flags);
279 cli();
280 if (irq < 8) {
281 cache_21 |= 1 << irq;
282 outb(cache_21,0x21);
283 } else {
284 cache_A1 |= 1 << (irq-8);
285 outb(cache_A1,0xA1);
286 }
287 set_intr_gate(0x20+irq,bad_interrupt[irq]);
288 sa->sa_handler = NULL;
289 sa->sa_flags = 0;
290 sa->sa_mask = 0;
291 sa->sa_restorer = NULL;
292 restore_flags(flags);
293 }
294
295 /*
296 * Note that on a 486, we don't want to do a SIGFPE on a irq13
297 * as the irq is unreliable, and exception 16 works correctly
298 * (ie as explained in the intel litterature). On a 386, you
299 * can't use exception 16 due to bad IBM design, so we have to
300 * rely on the less exact irq13.
301 *
302 * Careful.. Not only is IRQ13 unreliable, but it is also
303 * leads to races. IBM designers who came up with it should
304 * be shot.
305 */
306 static void math_error_irq(int cpl)
307 {
308 outb(0,0xF0);
309 if (ignore_irq13)
310 return;
311 math_error();
312 }
313
314 static void no_action(int cpl) { }
315
316 static struct sigaction ignore_IRQ = {
317 no_action,
318 0,
319 SA_INTERRUPT,
320 NULL
321 };
322
323 void init_IRQ(void)
324 {
325 int i;
326
327 for (i = 0; i < 16 ; i++)
328 set_intr_gate(0x20+i,bad_interrupt[i]);
329 if (irqaction(2,&ignore_IRQ))
330 printk("Unable to get IRQ2 for cascade\n");
331 if (request_irq(13,math_error_irq))
332 printk("Unable to get IRQ13 for math-error handler\n");
333
334 /* intialize the bottom half routines. */
335 for (i = 0; i < 32; i++) {
336 bh_base[i].routine = NULL;
337 bh_base[i].data = NULL;
338 }
339 bh_active = 0;
340 intr_count = 0;
341 }
342
--------------------------------
1 /*
2 * linux/kernel/itimer.c
3 *
4 * Copyright (C) 1992 Darren Senn
5 */
6
7 /* These are all the functions necessary to implement itimers */
8
9 #include <linux/signal.h>
10 #include <linux/sched.h>
11 #include <linux/string.h>
12 #include <linux/errno.h>
13 #include <linux/time.h>
14
15 #include <asm/segment.h>
16
17 static unsigned long tvtojiffies(struct timeval *value)
18 {
19 return((unsigned long )value->tv_sec * HZ +
20 (unsigned long )(value->tv_usec + (1000000 / HZ - 1)) /
21 (1000000 / HZ));
22 }
23
24 static void jiffiestotv(unsigned long jiffies, struct timeval *value)
25 {
26 value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
27 value->tv_sec = jiffies / HZ;
28 return;
29 }
30
31 int _getitimer(int which, struct itimerval *value)
32 {
33 register unsigned long val, interval;
34
35 switch (which) {
36 case ITIMER_REAL:
37 val = current->it_real_value;
38 interval = current->it_real_incr;
39 break;
40 case ITIMER_VIRTUAL:
41 val = current->it_virt_value;
42 interval = current->it_virt_incr;
43 break;
44 case ITIMER_PROF:
45 val = current->it_prof_value;
46 interval = current->it_prof_incr;
47 break;
48 default:
49 return(-EINVAL);
50 }
51 jiffiestotv(val, &value->it_value);
52 jiffiestotv(interval, &value->it_interval);
53 return(0);
54 }
55
56 asmlinkage int sys_getitimer(int which, struct itimerval *value)
57 {
58 int error;
59 struct itimerval get_buffer;
60
61 if (!value)
62 return -EFAULT;
63 error = _getitimer(which, &get_buffer);
64 if (error)
65 return error;
66 error = verify_area(VERIFY_WRITE, value, sizeof(struct itimerval));
67 if (error)
68 return error;
69 memcpy_tofs(value, &get_buffer, sizeof(get_buffer));
70 return 0;
71 }
72
73 int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
74 {
75 register unsigned long i, j;
76 int k;
77
78 i = tvtojiffies(&value->it_interval);
79 j = tvtojiffies(&value->it_value);
80 if (ovalue && (k = _getitimer(which, ovalue)) < 0)
81 return k;
82 switch (which) {
83 case ITIMER_REAL:
84 if (j) {
85 j += 1+itimer_ticks;
86 if (j < itimer_next)
87 itimer_next = j;
88 }
89 current->it_real_value = j;
90 current->it_real_incr = i;
91 break;
92 case ITIMER_VIRTUAL:
93 if (j)
94 j++;
95 current->it_virt_value = j;
96 current->it_virt_incr = i;
97 break;
98 case ITIMER_PROF:
99 if (j)
100 j++;
101 current->it_prof_value = j;
102 current->it_prof_incr = i;
103 break;
104 default:
105 return -EINVAL;
106 }
107 return 0;
108 }
109
110 asmlinkage int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
111 {
112 int error;
113 struct itimerval set_buffer, get_buffer;
114
115 if (!value)
116 memset((char *) &set_buffer, 0, sizeof(set_buffer));
117 else
118 memcpy_fromfs(&set_buffer, value, sizeof(set_buffer));
119 error = _setitimer(which, &set_buffer, ovalue ? &get_buffer : 0);
120 if (error || !ovalue)
121 return error;
122 error = verify_area(VERIFY_WRITE, ovalue, sizeof(struct itimerval));
123 if (!error)
124 memcpy_tofs(ovalue, &get_buffer, sizeof(get_buffer));
125 return error;
126 }
127
----------------------------------
1 #include <linux/autoconf.h>
2 /*
3 * Herein lies all the functions/variables that are "exported" for linkage
4 * With dynamically loaded kernel modules. Could do with making this a bit
5 * cleaner!
6 *
7 * Jon.
8 */
9
10 _register_chrdev
11 _unregister_chrdev
12 _register_blkdev
13 _unregister_blkdev
14 _wake_up_interruptible
15
16 _wp_works_ok
17 ___verify_write
18
19 _current
20 _jiffies
21 _printk
22 _schedule
23
24 #ifdef CONFIG_FTAPE
25 #
26 # The next labels are needed for ftape driver.
27 #
28 _ftape_big_buffer
29 _do_floppy
30 #endif
--------------------------
1 # This program will construct ksyms.s. Ksyms.s contains a symbol table
2 # for all the kernel symbols included in the file ksyms.lst. The following
3 # variables are defined in ksym.s:
4 #
5 # int symbol_table_size; /* number of symbols */
6 # struct {
7 # void *value; /* value of symbol */
8 # char *name; /* name of symbol */
9 # } symbol_table[];
10 #
11 #
12
13 trap "rm -f ksyms.tmp ksyms.lst ; exit 1" 1 2
14
15 sed -e '/^#/d' -e '/^[ ]*$/d' ksyms.lst | sort > ksyms.tmp
16
17 echo ' .data
18 .globl _symbol_table_size, _symbol_table
19
20 _symbol_table_size:'
21 echo " .long" `wc -l < ksyms.tmp`
22 echo '
23 _symbol_table:'
24 awk 'BEGIN {stringloc = 0}
25 {print " .long " $1; print " .long strings+" stringloc; \
26 stringloc += length($1) + 1;}' ksyms.tmp
27 echo '
28 strings:'
29 awk '{print " .ascii \"" $1 "\\0\""}' ksyms.tmp
30 rm -f ksyms.tmp
31
32
33 #
34 # Alternativly, if the kernel is c++ compiled:
35 # By using gsub() we can forse all function names to appear as extern "C".
36 # This allows linkable drivers written in C or C++ - Jon
37 # awk '{gsub(/__F.*/, "") ; print " .ascii \"" $0 "\\0\""}' ksyms.tmp
-------------------------------
1 /*
2 * linux/kernel/ldt.c
3 *
4 * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
5 */
6
7 #include <linux/config.h>
8 #include <linux/errno.h>
9 #include <linux/sched.h>
10 #include <linux/string.h>
11 #include <asm/segment.h>
12 #include <asm/system.h>
13 #include <linux/ldt.h>
14
15 static int read_ldt(void * ptr, unsigned long bytecount)
16 {
17 int error;
18 void * address = current->ldt;
19 unsigned long size;
20
21 if (!ptr)
22 return -EINVAL;
23 size = LDT_ENTRIES*LDT_ENTRY_SIZE;
24 if (!address) {
25 address = &default_ldt;
26 size = sizeof(default_ldt);
27 }
28 if (size > bytecount)
29 size = bytecount;
30 error = verify_area(VERIFY_WRITE, ptr, size);
31 if (error)
32 return error;
33 memcpy_tofs(ptr, address, size);
34 return size;
35 }
36
37 static int write_ldt(void * ptr, unsigned long bytecount)
38 {
39 struct modify_ldt_ldt_s ldt_info;
40 unsigned long *lp;
41 unsigned long base, limit;
42 int error, i;
43
44 if (bytecount != sizeof(ldt_info))
45 return -EINVAL;
46 error = verify_area(VERIFY_READ, ptr, sizeof(ldt_info));
47 if (error)
48 return error;
49
50 memcpy_fromfs(&ldt_info, ptr, sizeof(ldt_info));
51
52 if (ldt_info.contents == 3 || ldt_info.entry_number >= LDT_ENTRIES)
53 return -EINVAL;
54
55 limit = ldt_info.limit;
56 base = ldt_info.base_addr;
57 if (ldt_info.limit_in_pages)
58 limit *= PAGE_SIZE;
59
60 limit += base;
61 if (limit < base || limit >= 0xC0000000)
62 return -EINVAL;
63
64 if (!current->ldt) {
65 for (i=1 ; i<NR_TASKS ; i++) {
66 if (task[i] == current) {
67 if (!(current->ldt = (struct desc_struct*) vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE)))
68 return -ENOMEM;
69 set_ldt_desc(gdt+(i<<1)+FIRST_LDT_ENTRY, current->ldt, LDT_ENTRI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -