1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
global ticked
global ticks
global timer_init
extern check_signals
extern register_isr
extern sched_tick
ticked: dd 0
ticks: dd 0
tick_handler:
pusha
; save the data segment selectors
mov ax, ds
push ax
; switch to kernel data segments
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; save a pointer to the state information
mov ebx, esp
; handle the timer tick
mov dword [ticked], 1
inc dword [ticks]
mov al, 0x20
out 0x20, al
; check that the user isn't executing in kernel space
mov eax, [esp+38]
test eax, 0x03
jz .end
; if it isn't, call the scheduler
call sched_tick
; handle any pending signals before returning to normal execution
push ebx
call check_signals
add esp, 4
.end:
; restore the data segment selectors
pop ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
popa
iret
timer_init:
push ebp
mov ebp, esp
; register the tick_handler
push tick_handler
push dword 0
push dword 0x20
call register_isr
add esp, 12
; initialize the pit
mov ax, 0x36
out 0x43, al
mov ax, 0x2E9C ; 10ms tick interval
out 0x40, al
mov al, ah
out 0x40, al
in al, 0x21
and al, 0xFE
out 0x21, al
pop ebp
ret
|